diff --git a/.cursor/rules/00-project.mdc b/.cursor/rules/00-project.mdc deleted file mode 100644 index 4c5ba03..0000000 --- a/.cursor/rules/00-project.mdc +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Project-wide NO SUS Monad experiment rules and handover map. -alwaysApply: true ---- - -Read `AGENTS.md` and `docs/STATUS.md` before changing code. This is a separate, testnet-only NO SUS -experiment; do not read, edit, deploy, or reuse secrets from the production NO SUS repository. - -Preserve the threshold-custody honesty boundary: no plaintext, key, salt, filename, private key, or -service-role key may reach the contract, client logs, or public environment. Do not claim a human read, -legal proof, screenshot prevention, or independently verifiable deletion. - -Use focused checks in normal work. Ask the exact finalization question from `AGENTS.md` after every -substantive file-changing response. diff --git a/.cursor/rules/10-contracts.mdc b/.cursor/rules/10-contracts.mdc deleted file mode 100644 index 9efbd0d..0000000 --- a/.cursor/rules/10-contracts.mdc +++ /dev/null @@ -1,9 +0,0 @@ ---- -description: Solidity contract scope and receipt invariants. -globs: contracts/** -alwaysApply: false ---- - -The contract records a ciphertext digest and wallet acknowledgement only. Never add plaintext, keys, -salts, filenames, payment logic, admin bypasses, or an on-chain key-proof function. Preserve one open, -recipient, and expiry invariants. Add a failing test before every contract behavior change. diff --git a/.cursor/rules/20-web.mdc b/.cursor/rules/20-web.mdc deleted file mode 100644 index b190ba6..0000000 --- a/.cursor/rules/20-web.mdc +++ /dev/null @@ -1,9 +0,0 @@ ---- -description: Web experience and client security rules. -globs: web/** -alwaysApply: false ---- - -Keep browser crypto and wallet actions in client components; keep Supabase service-role access in server -route handlers only. Show explicit testnet and experimental labels. Dynamic wallet and receipt state must -be accessible, keyboard usable, and respect reduced-motion preferences. diff --git a/.env.example b/.env.example index 5c580a0..ef8a342 100644 --- a/.env.example +++ b/.env.example @@ -1,19 +1,28 @@ -# Public browser configuration — safe to expose in the client bundle. -NEXT_PUBLIC_MONAD_RPC_URL=https://rpc.testnet.monad.xyz -NEXT_PUBLIC_MONAD_EXPLORER_URL=https://testnet.monadscan.com -NEXT_PUBLIC_DROPS_CONTRACT_ADDRESS= -NEXT_PUBLIC_SUPABASE_URL= -NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY= +# NO SUS Canary: every secret and setting, with no values. +# Nothing here is needed to run the app locally (it uses the hosted devnet backend). +# Real values go in Supabase function secrets (`supabase secrets set ...`) or a git-ignored +# .env file. Never commit a filled-in copy. See docs/SELF_HOSTING.md. -# Server-only values — never prefix these with NEXT_PUBLIC_. -SUPABASE_SERVICE_ROLE_KEY= -LIT_NETWORK=naga-dev -LIT_ACCOUNT_API_KEY= -DEPLOYER_PRIVATE_KEY= -CONFIRM_MONAD_DEPLOY= +# --- Relayer: Supabase Edge Function `canary` (function secrets) --- +# 64 hex chars, random (openssl rand -hex 32). Salts the anonymous reader tag. Never share it. +CANARY_TAG_SALT= +# Devnet relayer keypairs, comma-separated: base58 64-byte secret keys or solana-keygen JSON +# arrays. Fund them at https://faucet.solana.com. Devnet only. +SOLANA_RELAYER_KEYS= +# Optional. Default https://api.devnet.solana.com +SOLANA_RPC_URL= +# Optional. Default MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr (SPL Memo) +SOLANA_MEMO_PROGRAM= +# Leave unset. Setting it turns on a legacy prototype path the product does not use. +CANARY_CONTRACT_ADDRESS= +# SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY are injected by Supabase. Never set them by hand +# and never put the service-role key in the app. -# Gate T1 live runner only (tool/threshold-spike). Never put these in NEXT_PUBLIC_*. -# DROPS_CONTRACT_ADDRESS= -# RECIPIENT_PRIVATE_KEY= -# STRANGER_PRIVATE_KEY= -# THRESHOLD_SPIKE_RUN= +# --- Flutter build (--dart-define, public by design) --- +# true = the standalone Canary web app that is deployed. +NOSUS_CANARY_ONLY=true +# Repo link shown in the app. +CANARY_REPO_URL=https://github.com/https-shubhamsahu/nosus-canary + +# --- tool/solana-spike (optional, local only) --- +# The spike writes its own devnet key to tool/solana-spike/.keys/ (git-ignored). diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 473051f..6383c44 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,8 +1 @@ -# Replace the handle if the GitHub repository uses a different owner account. * @https-shubhamsahu - -/contracts/ @https-shubhamsahu -/web/ @https-shubhamsahu -/supabase/ @https-shubhamsahu -/.github/ @https-shubhamsahu -/docs/ @https-shubhamsahu diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml deleted file mode 100644 index d91d95d..0000000 --- a/.github/workflows/checks.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: repository checks - -on: - pull_request: - push: - branches: [main, "codex/**"] - -permissions: - contents: read - -jobs: - check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - uses: actions/setup-node@v5 - with: - node-version: 22 - cache: npm - cache-dependency-path: | - contracts/package-lock.json - web/package-lock.json - - name: Check repository navigation - run: node tool/check-repository.mjs - - name: Check contracts - working-directory: contracts - run: | - npm ci - npm test - - name: Check web types - working-directory: web - run: | - npm ci - npm run check diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6445938 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,78 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + flutter: + name: Flutter app + runs-on: ubuntu-latest + defaults: + run: + working-directory: app + steps: + - uses: actions/checkout@v5 + - uses: subosito/flutter-action@v2 + with: + channel: stable + flutter-version: 3.47.7 + cache: true + - run: flutter pub get + - name: Analyze + run: flutter analyze + - name: Test + run: flutter test + - name: Fingerprint harness (must print FAILURES 0) + run: dart run tool/canary_fingerprint_harness.dart | tail -4 + + receipts-dart: + name: Receipts library (Dart) + runs-on: ubuntu-latest + defaults: + run: + working-directory: packages/receipts-dart + steps: + - uses: actions/checkout@v5 + - uses: subosito/flutter-action@v2 + with: + channel: stable + flutter-version: 3.47.7 + cache: true + - run: dart pub get + - run: dart analyze --fatal-infos + - run: dart format --output=none --set-exit-if-changed . + - run: dart test + + deno: + name: Relayer + receipts library (TypeScript) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: denoland/setup-deno@v2 + with: + deno-version: v2.9.x + - name: Receipts library checks + working-directory: packages/receipts-ts + run: | + deno check mod.ts cli.ts test/ + deno lint + deno fmt --check + deno test + - name: Relayer checks + working-directory: app/supabase/functions/canary + run: | + deno check index.ts + deno test --allow-env + - name: Relayer bundles for deploy + run: deno bundle --platform=deno app/supabase/functions/canary/index.ts -o "$RUNNER_TEMP/canary.bundle.js" + - name: Devnet spike type-checks + run: deno check tool/solana-spike/send_memo.ts diff --git a/AGENTS.md b/AGENTS.md index 63ca829..d732cc9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,59 +1,45 @@ -# NO SUS — Monad Experiment agent map - -This repository is an isolated, **testnet-only** experiment. Read -[docs/STATUS.md](docs/STATUS.md), then only the local guide for files you will change. - -## Current workstream: NO SUS Canary (owner decision, 19 Sep 2026) - -- Brand: **NO SUS**. Feature: **NO SUS Canary**. This supersedes the "NO SUS — Monad Experiment" - naming rule below for user-facing text. -- Build plan: [docs/canary/NOSUS_CANARY_BUILD_PLAN.md](docs/canary/NOSUS_CANARY_BUILD_PLAN.md) - (executed; the live code in `app/` and `contracts/` is the source of truth). Verification log: - [docs/canary/VERIFICATION.md](docs/canary/VERIFICATION.md). -- Canary is server-gated copy delivery and is described as such. It does not use Lit, does not - change Gate T1, and does not change `monadThresholdVerified`. -- Still requires explicit owner approval each time: contract deploys, funding wallets, applying - SQL, setting secrets, deploying functions, creating public repos or Pages, commits and pushes. - -## Product boundaries - -- Brand it **NO SUS — Monad Experiment**. Do not call it Rasid and do not change the production - NO SUS repository, credentials, Supabase project, deployment, or URL. -- Use only harmless, personally owned test notes. Never use credentials, third-party documents, - employment records, financial information, or sensitive personal data. -- The product may say "threshold-gated decryption after a wallet acknowledgement." It must never - claim legal proof, a human read, screenshot prevention, serverless deletion, or identity proof. -- The contract must never receive plaintext, encryption keys, salts, filenames, or document content. -- Threshold custody is a release gate, not decoration: if the Monad-to-Lit proof is not clean, do - not present it as shipped and never substitute a hidden server key-release path. - -## How to navigate - -| Area | Read first | -|---|---| -| Contract | `contracts/README.md` and `contracts/AGENTS.md` | -| Web app | `web/README.md` and `web/AGENTS.md` | -| Storage schema | `supabase/README.md` | -| Handover | `docs/CURSOR_HANDOFF.md` | -| Lit technical gate | `docs/LIT_MONAD_SPIKE.md` | -| Parallel work | `docs/AGENT_COLLABORATION.md` | - -## Working rules - -- Use the smallest necessary change. Do not add an abstraction, dependency, code generator, or - generic utility without a current consumer. -- Keep all secrets in ignored environment files. `NEXT_PUBLIC_*` values are public by design; never - put service-role keys, private keys, Lit account keys, or test-wallet keys there. -- Work in a dedicated branch and small commits. Update `docs/STATUS.md` and local README files when - behavior, contracts, or setup changes. -- Normal work uses focused checks and localhost. Do not deploy, fund wallets, apply a Supabase - migration, or use a real test note without explicit user direction. -- After each substantive response that changes files, ask exactly: "Would you like to finalize today's - work? If yes, say whether to verify only, build a target, or deploy a named target." - -Would you like to finalize today's work? If yes, say whether to verify only, build a target, or deploy a named target. - -## Finalization - -"Verify only" permits the contract tests, web checks, repository checks, and the real Monad/Lit -technical gate. A deployment additionally needs an explicitly named target. +# NO SUS Canary: agent map + +Read [docs/STATUS.md](docs/STATUS.md) first, then only the guide for the files you will change. + +## What this is + +NO SUS Canary: every reader of a note gets a uniquely marked copy, and every seal and every open is +one SPL Memo transaction on **Solana devnet**, sent by a relayer (Supabase Edge Function `canary`) +so readers need no wallet. Leak matching runs on the sender's device. + +## Map + +| Area | Code | Read first | +|---|---|---| +| Canary UI and fingerprinting | `app/lib/features/canary/` | `app/AGENTS.md` | +| Relayer | `app/supabase/functions/canary/` | `docs/ARCHITECTURE.md` | +| Receipt format and libraries | `packages/receipts-ts/`, `packages/receipts-dart/`, `packages/test-vectors/` | `docs/RECEIPTS_SPEC.md` | +| Schema | `app/supabase/migrations/2026091909*`, `2026101009*` | `docs/SELF_HOSTING.md` | +| Security model | — | `SECURITY.md` | + +## Rules + +- Backend: experiment project `ffidvfguojalzpclipzi` only. Never touch the NO SUS production + project, its credentials or deployment. +- Never put note text, keys, names or device ids on chain. Memos carry hashes only; the format is + frozen at v1 (see the spec) and both libraries must stay byte-identical with the test vectors. +- Secrets live in Supabase function secrets or git-ignored files (`.env.example` lists them). The + Supabase publishable key in `app/lib/config/supabase_credentials.dart` is public by design. +- Keep the legacy EVM prototype path off: `CANARY_MONAD` stays false in Flutter and + `CANARY_CONTRACT_ADDRESS` stays unset for the function. User-facing text mentions Solana only. +- Never claim screenshot prevention, legal proof, identity proof or proof that a human read a note. +- Use harmless test notes only. +- Smallest change that works. No new dependency or abstraction without a current consumer. +- Owner approval is needed every time for: commits and pushes, merges, deploying the function, + applying SQL, setting secrets, funding keys or spending devnet SOL, changing gh-pages, and + making anything public. + +## Checks (CI runs all of these) + +```bash +(cd app && flutter analyze && flutter test && dart run tool/canary_fingerprint_harness.dart) +(cd app/supabase/functions/canary && deno check index.ts && deno test --allow-env) +(cd packages/receipts-ts && deno check mod.ts cli.ts && deno lint && deno fmt --check && deno test) +(cd packages/receipts-dart && dart pub get && dart analyze && dart format --set-exit-if-changed . && dart test) +``` diff --git a/CLAUDE.md b/CLAUDE.md index edc3f27..3085c49 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,3 +1,3 @@ -# NO SUS — Monad Experiment +# NO SUS Canary Read [AGENTS.md](AGENTS.md). It is the single source of truth for humans and coding agents. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..11069ed --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..1f01b77 --- /dev/null +++ b/NOTICE @@ -0,0 +1,8 @@ +NO SUS Canary +Copyright 2026 Shubham Sahu (NO SUS) + +Licensed under the Apache License, Version 2.0 (see LICENSE). + +Third-party packages listed in app/pubspec.lock, packages/receipts-dart/pubspec.lock and +packages/receipts-ts/deno.lock keep their own licenses. The fonts in app/assets/google_fonts/ +are from Google Fonts and keep their own (SIL Open Font) licenses. diff --git a/README.md b/README.md index 2231a94..e981e96 100644 --- a/README.md +++ b/README.md @@ -1,121 +1,219 @@ - -

- NO SUS Canary: every reader gets their own copy. + NO SUS Canary: every reader gets their own copy. Receipts on Solana devnet.

- Play live -   - Judge checklist + CI + Solana devnet receipts + Live demo + License: Apache-2.0

-

Prof. Canary: Share one link. Every reader gets a secretly different copy. If it leaks, I tell you whose copy it was.

+**NO SUS Canary lets you share a sensitive note with a group so that every reader gets a secretly +different copy, and every seal and every open is recorded as a Solana transaction. If a screenshot +leaks, NO SUS tells you whose copy it was.** -## Step 1: Watch +[**Live demo**](https://shubham-sahu.me/nosus-canary/) · +[Pitch video (2:24)](https://github.com/https-shubhamsahu/nosus-canary/releases/download/v0.1.0/nosus-canary-pitch.mp4) · +[Demo video (1:18)](https://github.com/https-shubhamsahu/nosus-canary/releases/download/v0.1.0/nosus-canary-demo.mp4) · +[Judge FAQ](SUBMISSION.md) · +[A real receipt on Solana Explorer](https://explorer.solana.com/tx/5TXFPfTDFWyVe98DVPph7r55uRdJAcih6vKMBBRJKA96KtWT7Q4MUoFQG6GwH8N1FFkiMMbZzPssGtqtoW3wAsy2?cluster=devnet) · +[Security model](SECURITY.md) -

Animation: the sender seals a note on Monad, five readers each receive a different copy, Priya's copy leaks, NO SUS scans it and the canary sings: copy 03 is Priya's.

+

+ Demo on the live site: the sender writes a note and it is sealed on Solana devnet; Priya opens her own copy with no wallet; the sender sees who opened which copy; the leaked text is pasted in and the canary names copy 1, Priya's; the open receipt is shown on Solana Explorer. +

+

Recorded on the live site on 20 Oct 2026, no edits to the app. +Receipts from this run: +seal · +Priya's open · +Ben's open. +MP4 version.

-## Step 2: Try it +## The problem -**60 seconds. No wallet. No install.** +Salary sheets, offer letters, investor decks, exam papers and internal memos leak as screenshots +and forwards. When they do, nobody can show whose copy it was. Name watermarks get cropped. +Document-security tools ask every reader to make an account or install an app, so people go back +to WhatsApp and email. -1. **Make a note.** Open the [live app](http://shubham-sahu.me/nosus-canary/) → **PLAY CANARY** → **Create a Canary link** → **Use the demo note** → **Create Canary link**. -2. **Be a reader.** Open that link in a private window, type any name, tap **Open my copy**. -3. **Catch the leak.** Copy the reader's text → **Check a leak** → paste. It names the reader. +## The insight -

Battle text: A wild LEAK appeared! Canary used FINGERPRINT! It's super effective! It was Priya's copy, number 03.

+Give every reader a slightly different copy (a "canary trap"), and make the record of who got +which copy something neither side can edit. -## Step 3: Why Monad +- **Small wording changes survive.** `do not` / `don't`, `5` / `five`, `until` / `till`, plus an + invisible marker. They survive copy-paste, retyping into a chat and OCR, so even part of a + leaked text points to one copy. +- **Receipts are now cheap and fast.** A Solana memo costs about 0.000005 SOL and confirms in about + a second. That makes one neutral, timestamped receipt per reader affordable. A row in our own + database is only our word. -- **One transaction per reader.** Every **Open my copy** is recorded on-chain. -- **Final in under a second.** About **0.015 MON** each. -- **Parallel execution.** A whole room can open the link at once. +## The product -## Judge checklist +| | What happens | Where it runs | +|---|---|---| +| **1. Write once** | You write the note. Canary makes up to 100 copies that read the same but are each unique, and encrypts them. A **seal** memo goes to Solana with one hash of all copies. | Your browser (AES-256, key only in the link's `#fragment`) + relayer | +| **2. Share one link** | Each reader types a name and gets the next unused copy. An **open** memo goes to Solana with an anonymous tag. **Readers need no wallet, no app and no sign-up.** | Reader's browser + relayer | +| **3. Catch a leak** | Paste the leaked text (or part of it). Canary names the copy, or names nobody if too little survived. | Your device only | + + + + + + + + + + + + +
Priya's own copy, marked 'Copy 1 / 10 · made for Priya', with a 'Recorded on Solana' chip.Leak check result: 'The canary sang. Priya. Copy 1 / 10.' with a 'Proof on Solana' chip.Solana Explorer showing one Memo instruction with the JSON receipt: hashes only.
Each reader gets their own copyA pasted leak names the copyEvery open is a memo on Solana
+ +## Traction + +We are early: live, pre-revenue, devnet only. + +- **Canary on Solana devnet:** live at [shubham-sahu.me/nosus-canary](https://shubham-sahu.me/nosus-canary/) + since 10 Oct 2026. The relayer has written **31 receipts** so far (20 Oct 2026), all from our own + tests and demos. Every one is public on the + [relayer's account page](https://explorer.solana.com/address/CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx?cluster=devnet). +- **Parent product, [NO SUS](https://nosus.foo):** a privacy app for notes and files that open once + and are watermarked with the viewer's name. In production since July 2026 (Google Play closed + test, APK and web), 10+ releases. On 10 Oct 2026: 18 registered users, 6 active in the last 30 + days. + +## Why Solana + +1. **Cost per open.** A receipt is one SPL Memo instruction with one signature, so it pays the + 5,000-lamport base fee (0.000005 SOL). One receipt per reader stays affordable even for a + 100-reader note. +2. **Speed.** Receipts confirm in about a second, so the sender sees "opened" while the reader is + still reading. In the recording above, the sealed link was ready about 3 s after clicking + Create, including encryption and confirmation. +3. **Neutral and append-only.** Once written, neither the sender, the reader nor NO SUS can edit + a receipt. Anyone can check it on Solana Explorer without trusting our database. +4. **No program to audit, no wallet to install.** We use the standard SPL Memo program, which + Explorer shows as plain text. The relayer pays fees, so readers never see a wallet. +5. **Room to scale.** Batching many opens into one transaction (Merkle roots, state compression) + and the Solana dApp Store for the Android app are both on the roadmap below. + +## Architecture -| | What | Where | +```mermaid +flowchart LR + subgraph S["Sender's device"] + W["Write note"] --> K["Make N marked copies
word swaps + invisible marker"] + K --> E["Encrypt each copy
AES-256, key stays in the link #fragment"] + L["Leaked text"] --> M["Match on device
names a copy or nobody"] + end + E -- "ciphertexts + one hash of all copies" --> F["Relayer
Supabase Edge Function 'canary'"] + RD["Reader's browser
no wallet"] -- "open + typed name" --> F + F -- "their ciphertext only" --> RD + F -- "seal memo / open memo
hashed ids only" --> SOL[("Solana devnet
SPL Memo program")] + SOL -- "signature" --> X["Solana Explorer link
on every proof chip"] + F <--> DB[("Postgres
ciphertexts, names, signatures")] +``` + +| Where | What it holds | What it never holds | |---|---|---| -| **Done** | Live app | [shubham-sahu.me/nosus-canary/](http://shubham-sahu.me/nosus-canary/) | -| **Done** | Contract on Monad testnet | [`0xb1a1858866122c84cf97861ca815fb070e010e68`](https://testnet.monadscan.com/address/0xb1a1858866122c84cf97861ca815fb070e010e68) | -| **Done** | Verified source code | [View verified source](https://sourcify.dev/server/repo-ui/10143/0xb1a1858866122c84cf97861ca815fb070e010e68) | -| **Done** | Live transaction in the demo | Every **Open my copy** tap | -| **Done** | Public repo you can run | [Run it yourself](#more) | -| Soon | Build in public | _soon_ · _soon_ · _soon_ | -| Soon | Bonus: Monad mainnet | _soon_ | -| **Done** | Bonus: custom domain | [shubham-sahu.me](http://shubham-sahu.me/nosus-canary/) | +| Solana (public) | Hashed note id, copy count, one hash of all copies, expiry, copy number, salted reader tag | Note text, keys, names, device ids | +| Server (Supabase) | Encrypted copies, reader names and open times (shown to the sender), signatures | Note text, the decryption key | +| Sender's device | The note, every copy's fingerprint, the owner secret | — | +| The link | Note id and the AES key, in the `#fragment` (browsers never send it to a server) | — | -> **Honest limits:** it names *whose copy* leaked, not *who shared it*. It doesn't stop screenshots. It makes them traceable. +More: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) and the receipt format in +[docs/RECEIPTS_SPEC.md](docs/RECEIPTS_SPEC.md). -## More +## Receipts you can check now -
-How the fingerprint works +| Receipt | Signature | Memo | +|---|---|---| +| Seal, 10 copies (20 Oct 2026) | [`QqdiqT84…uL11wb`](https://explorer.solana.com/tx/QqdiqT84UfFyHNhpfLrK32HfqbUB5vF8qtC4DiAQ7wZZGn2MkUVJGGpVPpgmk4MCxVLtkhmZm6rbuBxqyuL11wb?cluster=devnet) | `{"p":"nosus-canary","v":1,"t":"seal","note":"0x6b0b…3698","copies":10,"hash":"0x…","exp":…}` | +| Open, copy 1 (Priya) | [`5TXFPfTD…oW3wAsy2`](https://explorer.solana.com/tx/5TXFPfTDFWyVe98DVPph7r55uRdJAcih6vKMBBRJKA96KtWT7Q4MUoFQG6GwH8N1FFkiMMbZzPssGtqtoW3wAsy2?cluster=devnet) | `{"p":"nosus-canary","v":1,"t":"open","note":"0x6b0b…3698","copy":0,"tag":"0x4096…c2b0"}` | +| Open, copy 2 (Ben) | [`3tqhYUQ2…h7GMTcT1`](https://explorer.solana.com/tx/3tqhYUQ2BppvWh6dy8q5u7U23NpZ7FqfAnd34B58GTriGVZXtykcPj1i4sF7bNh4t8ShnhQokySNz7Uwh7GMTcT1?cluster=devnet) | same note, `"copy":1` | +| First seal ever (10 Oct 2026) | [`2BHqnuCx…FRk512bQ`](https://explorer.solana.com/tx/2BHqnuCxYyemfegHkncgTsQyMPjpyB9boD1XqYfD1Wtbcf51Fpy3y264UwGhnvRKtcxFKCaSAzHxLrDwFRk512bQ?cluster=devnet) | `"t":"seal"`, 3 copies | +| All receipts | [relayer `CCD4SUQt…hueQJx`](https://explorer.solana.com/address/CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx?cluster=devnet) | | -- **Write once.** NO SUS swaps safe word twins (`don't` / `do not`, `five` / `5`) to make up to **100 copies**. Each looks normal, each is unique. -- **Seal it.** Copies are encrypted in your browser. The key lives only in the link's `#fragment`. `sealNote` puts one hash of all copies on Monad before anyone reads. -- **Share it.** Each reader gets the next unused copy. `openCopy` records it on Monad with an anonymous tag, never the name. -- **Catch it.** Paste a leak into **Check a leak**. Matching runs on your device. If too little text survived, it names nobody. -
+Decode any receipt yourself, without our app or server: -
-Run it yourself +```bash +deno run --allow-net packages/receipts-ts/cli.ts 5TXFPfTDFWyVe98DVPph7r55uRdJAcih6vKMBBRJKA96KtWT7Q4MUoFQG6GwH8N1FFkiMMbZzPssGtqtoW3wAsy2 +``` -You need Flutter 3.44+ and Node 22+. +## Run it locally in under 5 minutes + +You need [Flutter](https://docs.flutter.dev/get-started/install) 3.47+ and Chrome. The app talks +to the hosted devnet backend with its public (publishable) key, so there is nothing else to set up. ```bash git clone https://github.com/https-shubhamsahu/nosus-canary.git -cd nosus-canary - -# App (web) -cd app +cd nosus-canary/app flutter pub get -flutter run -d chrome - -# Contract -cd ../contracts -npm ci -npx hardhat test +flutter run -d chrome --dart-define=NOSUS_CANARY_ONLY=true ``` -Own backend and contract: see [`docs/canary/NOSUS_CANARY_BUILD_PLAN.md`](docs/canary/NOSUS_CANARY_BUILD_PLAN.md). -
+Run the checks that CI runs (add [Deno](https://deno.com) 2.x for the last three): -
-Architecture - -```mermaid -%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FAF6EC','primaryTextColor':'#141414','primaryBorderColor':'#141414','lineColor':'#F28C28','fontFamily':'monospace'}}}%% -flowchart LR - S["Sender app"] -- "encrypted copies" --> F["canary function"] - F -- "sealNote" --> M[("NoSusCanary on Monad")] - R["Reader"] -- "open + name" --> F - F -- "openCopy" --> M - F -- "their copy" --> R +```bash +(cd app && flutter analyze && flutter test) +(cd packages/receipts-dart && dart pub get && dart analyze && dart test) +(cd packages/receipts-ts && deno test) +(cd app/supabase/functions/canary && deno check index.ts && deno test --allow-env) ``` -- **Chain:** hashes and anonymous tags only. -- **Server:** encrypted copies it can't read. -- **Sender's device:** the key and every copy's fingerprint. -
- -
-Test results +Your own backend and relayer: [docs/SELF_HOSTING.md](docs/SELF_HOSTING.md). Secrets template: +[.env.example](.env.example). + +## Security notes + +- **On chain:** only sha256-based ids and hashes. The reader tag is salted with a server secret + and bound to the note and copy, so tags can't be linked across notes. Never note text, keys, + names or device ids. +- **On the server:** encrypted copies it cannot read (the key never leaves the link fragment), + plus each reader's typed name and open time, which the sender sees. +- **On the sender's device:** the original note and the fingerprint of every copy. Leak matching + runs here. Clearing browser data deletes it. +- **What a receipt proves:** that the NO SUS relayer recorded this seal or this open at this time, + and that the note's copies were committed before anyone read them. It does **not** prove who a + person is, that a human read the text, or who shared a leak. Canary names *whose copy* leaked. +- **Known limits:** it does not stop screenshots; a reader who rewrites the text in their own + words can defeat it; two readers who blend their copies can confuse the match (measured rates + in the threat model). Encryption is AES-256 in CTR mode without an authentication tag today; + moving to AES-GCM is on the roadmap. +- **Secrets:** none in the repo. The whole history (46 commits, all branches) was scanned on + 20 Oct 2026; the only key found is the Supabase publishable key, which is public by design. + +Full threat model and how to report a problem: [SECURITY.md](SECURITY.md). + +## Roadmap + +| Next | What | Status | +|---|---|---| +| **Mainnet** | Receipts on Solana mainnet-beta with priority fees, retries with backoff, and relayer key rotation | Devnet live | +| **Open-source receipts library** | `@nosus/receipts` (TypeScript) and `nosus_receipts` (Dart): encode, parse, send, fetch and verify Canary receipts, with shared test vectors | **v0.1 in [`packages/`](packages/)**; the live relayer runs it; not yet published to JSR, npm or pub.dev | +| **Solana dApp Store / Seeker** | Canary inside the NO SUS Android app, submitted to the Solana dApp Store | Android build exists; not submitted | +| **PDFs and images** | Per-copy marks for files, not only text | Not started | +| **Merkle / compressed batching** | Many opens in one transaction (a Merkle root per batch, or state compression) to cut cost at scale | Not started | +| **Authenticated encryption** | AES-GCM per copy, so a tampered copy fails to open | Not started | -Fingerprint test harness, 15-slot demo note: +## What's in this repo -| Leak type | Right copy | Wrong copy | -|---|---|---| -| Full copy, marker removed | 300 / 300 | 0 | -| OCR-style (caps, no punctuation) | 300 / 300 | 0 | -| 2% random typos | 300 / 300 | 0 | -| Partial excerpts (30–70%) | named only when sure | 0 / 600 | -
+| Path | What | +|---|---| +| [`app/`](app/) | The NO SUS Flutter app (web + Android). Canary lives in [`app/lib/features/canary/`](app/lib/features/canary/); the deployed site is the standalone build (`NOSUS_CANARY_ONLY=true`). | +| [`app/supabase/functions/canary/`](app/supabase/functions/canary/) | The relayer: one Supabase Edge Function (Deno) that stores ciphertexts and writes the Solana memos | +| [`app/supabase/migrations/`](app/supabase/migrations/) | Database schema, including `canary_notes` and `canary_copies` | +| [`packages/receipts-ts/`](packages/receipts-ts/) · [`packages/receipts-dart/`](packages/receipts-dart/) | The receipts library, v0.1, plus [shared test vectors](packages/test-vectors/) from real devnet transactions | +| [`docs/`](docs/) | Architecture, receipt spec, self-hosting, status and verification log | +| [`tool/solana-spike/`](tool/solana-spike/) | Script that sends a test seal and open memo to devnet with your own key | -Full technical write-up (setup, deployment, contract and relayers): [`docs/TECHNICAL_README.md`](docs/TECHNICAL_README.md) +## Team ---- +**Shubham Sahu**, founder of NO SUS. B.E. Electronics & Computer Engineering, TSEC Mumbai (2028). +[nosus.foo](https://nosus.foo) · [shubhamsahu@nosus.foo](mailto:shubhamsahu@nosus.foo) · +[LinkedIn](https://www.linkedin.com/in/shubhamsahu9372) · [X @isagi0011](https://x.com/isagi0011) -**Team:** Shubham Sahu · Built at **Monad Blitz Mumbai V4** · part of **NO SUS** +## License -

Game over? Play again at the live app.

+[Apache-2.0](LICENSE). Use harmless test notes only on the devnet demo. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..d93cef1 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,93 @@ +# Security + +## Reporting a problem + +Email **shubhamsahu@nosus.foo** with "security" in the subject. Please don't open a public issue +for a vulnerability. The demo runs on Solana devnet and a test +backend; never put real secrets or personal data into it. + +## What goes where + +| Data | Sender's device | Link | Server (Supabase) | Solana (public) | +|---|---|---|---|---| +| Note text and every copy | ✅ | — | encrypted only | — | +| AES-256 key | ✅ | in the `#fragment` | — | — | +| Fingerprint of each copy (which words were swapped) | ✅ | — | — | — | +| Owner secret (unlocks the dashboard) | ✅ | — | stored as sha256 only | — | +| Reader's typed name, open time | shown on dashboard | — | ✅ | — | +| Reader's device id (random, per browser) | — | — | stored as sha256 only | — | +| Note id | ✅ | ✅ | ✅ | sha256 only | +| Commitment to all copies | ✅ | — | ✅ | ✅ | +| Which copy was opened | ✅ | — | ✅ | ✅ | +| Reader tag | — | — | ✅ | ✅ | + +The browser never sends the `#fragment` to a server, so the key reaches only people who have the +link. The Canary tables have row-level security on and no grants to the public (`anon`) role; only +the edge function, using the service role, can read or write them. + +## How each value is computed + +| Value | Formula | Computed by | +|---|---|---| +| Chain note id | `0x` + sha256(`"nosus-canary:" + noteId`) | device and relayer | +| Copy digest | sha256(`salt + ":" + index + ":" + copyText`) with a random 32-byte salt kept on the device | device | +| Copies hash (sealed on chain) | `0x` + sha256(all copy digests joined in copy order) | device | +| Owner hash | sha256(`ownerSecret`), the secret is 32 random bytes kept on the device | device | +| Device hash | sha256(`"device:" + deviceId`) | relayer | +| Reader tag (on chain) | `0x` + sha256(`CANARY_TAG_SALT + ":" + noteId + ":" + copyIndex + ":" + deviceHash`) | relayer | + +`CANARY_TAG_SALT` is a 32-byte server secret. Without it nobody can link a tag to a device or link +two tags from different notes. The memo format is specified in +[docs/RECEIPTS_SPEC.md](docs/RECEIPTS_SPEC.md). + +## Threat model + +**What Canary is for:** naming which reader's copy a leaked text came from, and keeping a neutral, +timestamped record of the seal and of each open. + +| Who | What they try | What happens | +|---|---|---| +| A reader | Screenshot or copy-paste their copy | The copy is identified if enough text survives. See the measured rates below. | +| A reader | Strip invisible characters, change case or punctuation, OCR a screenshot | Still identified: the word swaps carry the fingerprint. | +| A reader | Retype the note in their own words | Can defeat it. Canary marks wording, not meaning. | +| Two readers | Blend their two copies | Usually names one of them; sometimes names an innocent reader (rates below). The app warns about this. | +| Anyone with the link | Open a copy and type a fake name | Works. A typed name is not an identity. The link is the access control: share it like a password. | +| Someone with the sender's device | Read the note, open the dashboard | Works. Device security is out of scope. | +| A passive observer of Solana | Learn the note, names or devices | Sees only hashes, copy counts, copy numbers, expiry and timestamps. | +| The server operator (us) | Read notes | Cannot: the server never has the key. | +| The server operator (us) | Give two readers the same copy, swap ciphertexts, or skip a receipt | Possible today. Partly detectable: the seal commits to every copy before anyone reads, and the sender's device can check any copy a reader shows them against it. Authenticated encryption (AES-GCM) is on the roadmap so a tampered copy fails to open. | +| Whoever steals the relayer key | Write fake memos from our relayer address | Possible. The key is a devnet key stored as a Supabase secret, never in the repo. Mainnet adds key rotation. | + +**Measured leak matching** (`app/tool/canary_fingerprint_harness.dart`, run in CI; a note with 15 +swappable words, like the app's demo note): + +| Leak | 20 copies | 50 copies | 100 copies | +|---|---|---|---| +| Full copy without invisible marker, OCR-style text, 2% typos | 300 / 300 each, 0 wrong | 300 / 300 each, 0 wrong | 300 / 300 each, 0 wrong | +| Partial excerpts: named / wrong | 431 / 600, 0 wrong | 313 / 600, 0 wrong | 188 / 600, 0 wrong | +| Two copies blended: an innocent named | 1 / 600 | 8 / 600 | 23 / 600 | + +## What we do not claim + +- Canary does not stop screenshots. It makes them traceable. +- A receipt proves that the NO SUS relayer recorded an event at a time. It does not prove who a + person is, that a human read the text, or who shared a leak. +- It is not legal evidence by itself. +- Deleting data from the server is an operational step, not something anyone can verify. + +## Known gaps + +- **Encryption mode.** Copies use AES-256 from `package:encrypt` with its default mode (SIC, which + is CTR) and a random 16-byte IV per copy. There is no authentication tag. Planned: AES-GCM. +- **Relayer trust.** One relayer key signs every memo. Planned: several keys with rotation, and + receipts batched under a Merkle root so a reader can check their own open. +- **Devnet only.** Devnet can be reset; receipts there are for demos, not records. + +## Secrets in this repository + +None. On 20 Oct 2026 every commit on every branch (46 commits, 17 refs, plus unreachable objects) +was scanned for Solana and EVM private keys, Supabase service-role and secret keys, GitHub, Google, +AWS, Stripe and AI-provider tokens, PEM keys and signing files. The only key-like value is the +Supabase **publishable** key in `app/lib/config/supabase_credentials.dart`, which is public by +design and gated by row-level security. Real secrets live only in Supabase function secrets and in +git-ignored files; see [.env.example](.env.example). diff --git a/SUBMISSION.md b/SUBMISSION.md new file mode 100644 index 0000000..722bd42 --- /dev/null +++ b/SUBMISSION.md @@ -0,0 +1,112 @@ +# NO SUS Canary: for judges and reviewers + +**One line:** share a sensitive note with a group; every reader gets a secretly different copy; +every seal and every open is a Solana transaction; if a screenshot leaks, NO SUS names whose copy +it was. + +| | Link | +|---|---| +| Live app (Solana devnet) | https://shubham-sahu.me/nosus-canary/ | +| Code (Apache-2.0) | https://github.com/https-shubhamsahu/nosus-canary | +| Pitch video (2:24) | [nosus-canary-pitch.mp4](https://github.com/https-shubhamsahu/nosus-canary/releases/download/v0.1.0/nosus-canary-pitch.mp4) | +| Product demo, narrated (1:18) | [nosus-canary-demo.mp4](https://github.com/https-shubhamsahu/nosus-canary/releases/download/v0.1.0/nosus-canary-demo.mp4) | +| 36-second silent demo | [GIF](docs/media/canary-demo.gif) · [MP4](docs/media/canary-demo.mp4) | +| A real open receipt | [`5TXFPfTD…oW3wAsy2` on Solana Explorer](https://explorer.solana.com/tx/5TXFPfTDFWyVe98DVPph7r55uRdJAcih6vKMBBRJKA96KtWT7Q4MUoFQG6GwH8N1FFkiMMbZzPssGtqtoW3wAsy2?cluster=devnet) | +| Every receipt so far | [Relayer account on Solana Explorer](https://explorer.solana.com/address/CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx?cluster=devnet) | +| Receipt format | [docs/RECEIPTS_SPEC.md](docs/RECEIPTS_SPEC.md) | +| Threat model | [SECURITY.md](SECURITY.md) | +| Contact | Shubham Sahu · [shubhamsahu@nosus.foo](mailto:shubhamsahu@nosus.foo) | + +## Check it yourself in 60 seconds + +1. Open the [live app](https://shubham-sahu.me/nosus-canary/) → **Create a Canary link** → + **Use the demo note** → **Create Canary link**. A "Sealed on Solana" chip appears. +2. Open the link in a private window, type any name, tap **Open my copy**. Your copy shows a + "Recorded on Solana" chip. Click it: Solana Explorer shows one Memo instruction with hashes only. +3. Copy the reader's text. Back in the first window, open **Who opened it** and paste it into + **Check a leak** → **Find the copy**. It names the reader. + +Use harmless text only. This is devnet. + +## 2-minute demo script + +| Time | Do | Say | +|---|---|---| +| 0:00 | Show the landing page | "Salary sheets, offer letters and decks leak as screenshots. Today nobody can show whose copy it was." | +| 0:15 | **Create a Canary link** → **Use the demo note** | "I write the note once. Canary makes up to 100 copies that read the same, with tiny word swaps like *don't* and *do not*, and an invisible marker." | +| 0:30 | Point at the fingerprint meter, pick 10 readers, **Create Canary link** | "Every copy is encrypted in my browser. The key stays in the link. Before anyone reads, a seal goes to Solana: one hash of all ten copies." | +| 0:45 | Click **Sealed on Solana** → Explorer | "That's a real devnet transaction. One SPL Memo. No text, no names, just hashes." | +| 1:00 | Open the link in a private window, type "Priya", **Open my copy** | "Priya needs no wallet and no app. She gets her own copy, and her open is another Solana memo, paid by our relayer for about 0.000005 SOL." | +| 1:20 | Copy Priya's text. Sender window: **Who opened it**, paste into **Check a leak**, **Find the copy** | "Now imagine Priya's copy shows up in a group chat. I paste it in. Matching runs on my device." | +| 1:35 | Result card: **The canary sang · Priya · Copy 1 / 10** | "It names her copy. If too little text survived, it names nobody. It never guesses." | +| 1:45 | Click **Proof on Solana** | "And the receipt shows when her copy was opened, on a chain neither of us can edit." | +| 1:55 | Back to README roadmap | "Next: mainnet, the open receipts library, PDFs, and the Solana dApp Store." | + +## FAQ + +**What does a receipt prove, exactly?** +That the NO SUS relayer recorded a seal (with a commitment to every copy) or an open of copy N, at +a chain timestamp, and that the copies were committed before anyone read them. It does not prove +a person's identity, that a human read the text, or who shared a leak. Canary names *whose copy* +leaked. Phones get lost and screens get shown to friends. + +**Why put this on a chain instead of in your database?** +A database row is our word, and we can edit it. A Solana memo is public, timestamped and +append-only, so the sender, the reader and a third party can all check the same record without +trusting NO SUS. + +**Why Solana?** +One receipt per reader has to be cheap (each receipt pays the 5,000-lamport base fee) and fast (about a +second to confirm, so the sender sees "opened" right away). The standard SPL Memo program means +there is no custom program to audit, and Explorer shows the memo as plain text. + +**Does the server see the note?** +No. Copies are encrypted on the sender's device and the AES key lives in the link's `#fragment`, +which browsers never send to a server. The server does see each reader's typed name and when they +opened, because the sender's dashboard shows it. Names never go on chain. + +**Can a reader strip the marks?** +Removing the invisible marker is not enough: the word swaps still identify the copy. From the +fingerprint test harness (`app/tool/canary_fingerprint_harness.dart`, run in CI), on a note with +15 swappable words like the app's demo note: + +| Leak | 20 copies | 50 copies | 100 copies | +|---|---|---|---| +| Full copy, invisible marker removed | 300 / 300 right | 300 / 300 | 300 / 300 | +| OCR-style (caps, no punctuation) | 300 / 300 right | 300 / 300 | 300 / 300 | +| 2% random typos | 300 / 300 right, 0 wrong | 300 / 300, 0 wrong | 300 / 300, 0 wrong | +| Partial excerpts (named / wrong) | 431 / 600, 0 wrong | 313 / 600, 0 wrong | 188 / 600, 0 wrong | +| Two readers blend their copies: an innocent named | 1 / 600 | 8 / 600 | 23 / 600 | + +When an excerpt is too short, Canary names nobody instead of guessing. A reader who rewrites the +whole note in their own words can defeat it. Blending is the known weak spot; the app says so. + +**Who pays the fees? Do readers need a wallet?** +The relayer (a Supabase Edge Function) pays and signs every memo. Readers never see a wallet. + +**Are reader tags private?** +Each tag is `sha256(server salt : note id : copy number : sha256(device id))`. Without the server +salt nobody can link tags across notes or back to a device. + +**Is it on mainnet?** +Not yet. Devnet only. Mainnet with priority fees and retries is the first roadmap item. + +**What is open source?** +Everything in this repo, under Apache-2.0: the Flutter app, the relayer, the database schema, and +the receipts library v0.1 in TypeScript and Dart (`packages/`), which any app can use to write and +verify the same receipts. + +**What is the business?** +Pre-revenue. First users we are building for: small teams, HR, founders sharing decks, and college +groups in India. Planned paid features for teams: leak alerts, a team dashboard and audit exports. +None of those are built yet. + +**What traction is there?** +Canary has been live on devnet since 10 Oct 2026; its relayer has written 31 receipts (20 Oct +2026), all from our own tests and demos. The parent app, NO SUS, has been in production since July +2026 with 18 registered users and 6 active in the last 30 days (10 Oct 2026). We do not claim more +than that. + +**Who is building it?** +Shubham Sahu, founder of NO SUS, B.E. Electronics & Computer Engineering at TSEC Mumbai (2028). +NO SUS has shipped 10+ releases since July 2026. diff --git a/app/AGENTS.md b/app/AGENTS.md index 7f41eb2..44bbea4 100644 --- a/app/AGENTS.md +++ b/app/AGENTS.md @@ -1,20 +1,18 @@ -# NO SUS — Monad Experiment: Flutter app +# NO SUS Canary: Flutter app -Full NO SUS app copied from `no_sus` at -`ec29fdae94a68fefcb5efea2797224dc2245549c`, explicitly requested by the owner. -The root AGENTS.md still applies. Production files are not edited. +This is the NO SUS Flutter app (copied from the production `no_sus` repo at +`ec29fdae94a68fefcb5efea2797224dc2245549c`). NO SUS Canary lives in `lib/features/canary/`. The +root `AGENTS.md` still applies. -- Preserve the five tabs and existing app features and deep-link formats. -- Add Monad under `lib/features/monad/`, reached from Welcome and Workspace. - Use the existing Flutter theme, accessibility and navigation. -- Backend: **ffidvfguojalzpclipzi** only. Never apply this fork's SQL to - production `rxfnazmusofikwaggntb`. No production users or storage are copied. -- Target: **monad.nosus.foo**, web only. Native source is retained for parity; - do not release it with the copied production application/signing identity. -- No secrets were copied. The publishable Supabase key is a public client key. -- Gate T1 still blocks Monad encrypted sharing and public release. Reading - `canDecrypt` alone is not proof of successful Lit decryption. -- Run `flutter analyze`, `flutter test`, and `flutter build web --base-href /`. - SDK: `C:/Users/shubh/AppData/Local/flutter/bin/flutter.bat`. -- Do not format unrelated copied Dart files. Migrations remain immutable; - experiment-specific changes are append-only. +- The deployed site is the standalone Canary build: `--dart-define=NOSUS_CANARY_ONLY=true`, base + href `/nosus-canary/`. Without that flag you get the full NO SUS app, with Canary reachable from + the welcome screen and `#/canary`. +- Backend: `ffidvfguojalzpclipzi` only. Never apply this fork's SQL to the production project. No + production users or storage were copied. The publishable Supabase key is a public client key. +- Native source is kept for parity. Do not release it with the production application or signing + identity. +- Leave `CANARY_MONAD` off (default). User-facing text names Solana only. +- After changing the word list in `canary_fingerprint.dart`, run + `dart run tool/canary_fingerprint_harness.dart`; it must end with `FAILURES: 0`. +- Run `flutter analyze` and `flutter test` before every commit. Do not reformat unrelated copied + files. Migrations are immutable; add new ones. diff --git a/app/analysis_options.yaml b/app/analysis_options.yaml index f5306fb..ec9fbef 100644 --- a/app/analysis_options.yaml +++ b/app/analysis_options.yaml @@ -7,6 +7,15 @@ # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. +analyzer: + exclude: + - build/** + - android/** + - ios/** + - web/** + - windows/** + - macos/** + - linux/** include: package:flutter_lints/flutter.yaml linter: diff --git a/app/lib/features/monad/presentation/experiment_frame.dart b/app/lib/components/experiment_frame.dart similarity index 90% rename from app/lib/features/monad/presentation/experiment_frame.dart rename to app/lib/components/experiment_frame.dart index 56f988c..04d5887 100644 --- a/app/lib/features/monad/presentation/experiment_frame.dart +++ b/app/lib/components/experiment_frame.dart @@ -14,7 +14,7 @@ class ExperimentFrame extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 12, vertical: 7), child: Center( child: Text( - 'NO SUS · Monad testnet · use harmless test notes only', + 'NO SUS · experiment build · use harmless test notes only', textAlign: TextAlign.center, style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600), ), diff --git a/app/lib/config/app_mode.dart b/app/lib/config/app_mode.dart index fabeeae..23551cf 100644 --- a/app/lib/config/app_mode.dart +++ b/app/lib/config/app_mode.dart @@ -3,7 +3,17 @@ /// The full NO SUS app (APK, main web app) never sets it. const bool kCanaryOnly = bool.fromEnvironment('NOSUS_CANARY_ONLY'); -/// Optional deployed contract address to show on the Canary landing page. +/// Shows the Monad testnet prototype in NO SUS Canary: the wallet button, +/// Monad proof chips, "Verify on Monad" and all Monad wording. Off by +/// default: Solana devnet is the only receipt the product shows. Build with +/// --dart-define=CANARY_MONAD=true to reproduce the earlier Monad build. +const bool kCanaryMonad = bool.fromEnvironment( + 'CANARY_MONAD', + defaultValue: false, +); + +/// Optional deployed contract address to show on the Canary landing page +/// (Monad testnet; only shown when [kCanaryMonad] is true). const String kCanaryContract = String.fromEnvironment( 'CANARY_CONTRACT', defaultValue: '0xb1a1858866122c84cf97861ca815fb070e010e68', @@ -12,5 +22,5 @@ const String kCanaryContract = String.fromEnvironment( /// Optional repo URL for the open-source link in the hero/footer. const String kCanaryRepoUrl = String.fromEnvironment( 'CANARY_REPO_URL', - defaultValue: 'https://github.com/https-shubhamsahu/nosus-monad', + defaultValue: 'https://github.com/https-shubhamsahu/nosus-canary', ); diff --git a/app/lib/features/canary/data/canary_api.dart b/app/lib/features/canary/data/canary_api.dart index eb04638..10ca767 100644 --- a/app/lib/features/canary/data/canary_api.dart +++ b/app/lib/features/canary/data/canary_api.dart @@ -68,8 +68,12 @@ class CanaryApi { return decoded; } - /// Uploads every encrypted copy and seals the note on Monad. - Future<({String sealTxHash, DateTime expiresAt})> create({ + /// Uploads every encrypted copy and seals the note: one memo on Solana + /// devnet ([sealSolanaSig]) and, only while the server has the Monad + /// prototype switched on, one Monad testnet transaction ([sealTxHash]). + /// The server answers 200 only once at least one of them exists. + Future<({String? sealTxHash, String? sealSolanaSig, DateTime expiresAt})> + create({ required String noteId, required String ownerHash, required int copyCount, @@ -89,8 +93,17 @@ class CanaryApi { {'index': c.index, 'ciphertext': c.ciphertext, 'iv': c.iv}, ], }, timeout: const Duration(seconds: 60)); + final sealTxHash = result['seal_tx_hash'] as String?; + final sealSolanaSig = result['seal_solana_sig'] as String?; + if (sealTxHash == null && sealSolanaSig == null) { + throw const CanaryApiException( + 'The note was not sealed. Try again.', + retryable: true, + ); + } return ( - sealTxHash: result['seal_tx_hash'] as String, + sealTxHash: sealTxHash, + sealSolanaSig: sealSolanaSig, expiresAt: DateTime.parse(result['expires_at'] as String), ); } @@ -103,6 +116,7 @@ class CanaryApi { String ciphertext, String iv, String? openTxHash, + String? openSolanaSig, DateTime openedAt, }) > @@ -123,6 +137,7 @@ class CanaryApi { ciphertext: r['ciphertext'] as String, iv: r['iv'] as String, openTxHash: r['open_tx_hash'] as String?, + openSolanaSig: r['open_solana_sig'] as String?, openedAt: DateTime.parse(r['opened_at'] as String), ); } @@ -140,6 +155,7 @@ class CanaryApi { return CanaryNoteStatus( copyCount: r['copy_count'] as int, sealTxHash: r['seal_tx_hash'] as String?, + sealSolanaSig: r['seal_solana_sig'] as String?, expiresAt: DateTime.parse(r['expires_at'] as String), copies: [ for (final c in r['copies'] as List) @@ -148,6 +164,7 @@ class CanaryApi { readerName: c['reader_name'] as String, openedAt: DateTime.parse(c['opened_at'] as String), openTxHash: c['open_tx_hash'] as String?, + openSolanaSig: c['open_solana_sig'] as String?, ), ], ); diff --git a/app/lib/features/canary/data/canary_crypto.dart b/app/lib/features/canary/data/canary_crypto.dart index a8364e9..83eb68b 100644 --- a/app/lib/features/canary/data/canary_crypto.dart +++ b/app/lib/features/canary/data/canary_crypto.dart @@ -46,7 +46,7 @@ class CanaryCrypto { static String copyDigest(String saltHex, int index, String copyText) => sha256Hex('$saltHex:$index:$copyText'); - /// Commitment to every copy, written to Monad: sha256 of the digests + /// Commitment to every copy, written on chain: sha256 of the digests /// concatenated in copy order, as 0x-prefixed hex. static String copiesHash(List copyDigests) => '0x${sha256Hex(copyDigests.join())}'; diff --git a/app/lib/features/canary/data/canary_repository.dart b/app/lib/features/canary/data/canary_repository.dart index 6cab315..698c597 100644 --- a/app/lib/features/canary/data/canary_repository.dart +++ b/app/lib/features/canary/data/canary_repository.dart @@ -1,5 +1,6 @@ import 'package:uuid/uuid.dart'; +import '../../../config/app_mode.dart'; import '../../../core/utils/web_links.dart'; import '../domain/canary_fingerprint.dart'; import '../domain/canary_link.dart'; @@ -33,7 +34,9 @@ class CanaryRepository { CanaryOwnerRecord? findNote(String noteId) => _store.findNote(noteId); /// Sender: builds every copy on this device, uploads only ciphertext, and - /// seals the note on Monad. [onStage] receives short progress messages. + /// seals the note on Solana devnet (plus Monad testnet when the server has + /// the prototype on). + /// [onStage] receives short progress messages. Future createNote({ required String text, required int copyCount, @@ -118,7 +121,9 @@ class CanaryRepository { // the codewords. Removed again below if the upload fails. await _store.saveNote(draft); - onStage?.call('Sealing on Monad…'); + onStage?.call( + kCanaryMonad ? 'Sealing on Monad + Solana…' : 'Sealing on Solana devnet…', + ); try { final result = await _api.create( noteId: noteId, @@ -130,6 +135,7 @@ class CanaryRepository { ); final sealed = draft.copyWith( sealTxHash: result.sealTxHash, + sealSolanaSig: result.sealSolanaSig, expiresAt: result.expiresAt, ); await _store.saveNote(sealed); @@ -177,6 +183,7 @@ class CanaryRepository { readerName: name, openedAt: result.openedAt, openTxHash: result.openTxHash, + openSolanaSig: result.openSolanaSig, ); } diff --git a/app/lib/features/canary/domain/canary_link.dart b/app/lib/features/canary/domain/canary_link.dart index a889830..8b6067b 100644 --- a/app/lib/features/canary/domain/canary_link.dart +++ b/app/lib/features/canary/domain/canary_link.dart @@ -50,7 +50,8 @@ CanaryLinkToken? parseCanaryReaderLink(String fullUrl) { return CanaryLinkToken(noteId: noteId, keyHex: key); } -/// The bytes32 note id used on Monad: sha256("nosus-canary:" + noteId). +/// The bytes32 note id used on chain (Solana memo, Monad contract): +/// sha256("nosus-canary:" + noteId). /// The edge function computes the same value; keep them identical. String canaryChainNoteId(String noteId) => '0x${sha256.convert(utf8.encode('nosus-canary:$noteId'))}'; @@ -58,3 +59,25 @@ String canaryChainNoteId(String noteId) => /// Public block explorer page for a Monad testnet transaction. String canaryExplorerTxUrl(String txHash) => 'https://testnet.monadscan.com/tx/$txHash'; + +/// Public block explorer page for a Solana devnet transaction signature. +String canarySolanaExplorerTxUrl(String signature) => + 'https://explorer.solana.com/tx/$signature?cluster=devnet'; + +/// Which public chain a Canary proof lives on. +enum CanaryChain { + monad, + solana; + + /// Short brand name for chips: 'Monad' / 'Solana'. + String get label => this == CanaryChain.monad ? 'Monad' : 'Solana'; + + /// Network name for sentences: 'Monad testnet' / 'Solana devnet'. + String get network => + this == CanaryChain.monad ? 'Monad testnet' : 'Solana devnet'; + + /// Public explorer page for a transaction on this chain. + String txUrl(String hash) => this == CanaryChain.monad + ? canaryExplorerTxUrl(hash) + : canarySolanaExplorerTxUrl(hash); +} diff --git a/app/lib/features/canary/domain/canary_models.dart b/app/lib/features/canary/domain/canary_models.dart index 1693625..f7300a5 100644 --- a/app/lib/features/canary/domain/canary_models.dart +++ b/app/lib/features/canary/domain/canary_models.dart @@ -27,6 +27,7 @@ class CanaryOwnerRecord { required this.plan, required this.codewords, this.sealTxHash, + this.sealSolanaSig, }); final String noteId; @@ -49,26 +50,37 @@ class CanaryOwnerRecord { /// codewords[i] is the 0/1 choice per slot for copy i. final List> codewords; - /// Monad transaction that sealed the note. Null until sealing succeeded. + /// Monad testnet transaction that sealed the note (earlier prototype). + /// Null while the server has Monad off, and for unsealed drafts. final String? sealTxHash; - bool get isSealed => sealTxHash != null; - - CanaryOwnerRecord copyWith({String? sealTxHash, DateTime? expiresAt}) => - CanaryOwnerRecord( - noteId: noteId, - keyHex: keyHex, - ownerSecret: ownerSecret, - saltHex: saltHex, - copyCount: copyCount, - createdAt: createdAt, - expiresAt: expiresAt ?? this.expiresAt, - readerLink: readerLink, - preview: preview, - plan: plan, - codewords: codewords, - sealTxHash: sealTxHash ?? this.sealTxHash, - ); + /// Solana devnet memo signature that sealed the note: the product's + /// receipt. Null for unsealed drafts and for records saved before Solana + /// proofs existed. + final String? sealSolanaSig; + + /// Sealed once either chain holds the seal. + bool get isSealed => sealTxHash != null || sealSolanaSig != null; + + CanaryOwnerRecord copyWith({ + String? sealTxHash, + String? sealSolanaSig, + DateTime? expiresAt, + }) => CanaryOwnerRecord( + noteId: noteId, + keyHex: keyHex, + ownerSecret: ownerSecret, + saltHex: saltHex, + copyCount: copyCount, + createdAt: createdAt, + expiresAt: expiresAt ?? this.expiresAt, + readerLink: readerLink, + preview: preview, + plan: plan, + codewords: codewords, + sealTxHash: sealTxHash ?? this.sealTxHash, + sealSolanaSig: sealSolanaSig ?? this.sealSolanaSig, + ); Map toJson() => { 'v': 1, @@ -84,6 +96,7 @@ class CanaryOwnerRecord { 'plan': plan.toJson(), 'codewords': [for (final c in codewords) c.join()], 'sealTxHash': sealTxHash, + 'sealSolanaSig': sealSolanaSig, }; factory CanaryOwnerRecord.fromJson(Map json) { @@ -104,6 +117,8 @@ class CanaryOwnerRecord { [for (final ch in (c as String).split('')) ch == '1' ? 1 : 0], ], sealTxHash: json['sealTxHash'] as String?, + // Records saved before Solana proofs existed have no key here. + sealSolanaSig: json['sealSolanaSig'] as String?, ); } } @@ -115,36 +130,52 @@ class CanaryCopyStatus { required this.readerName, required this.openedAt, required this.openTxHash, + required this.openSolanaSig, }); final int copyIndex; final String readerName; final DateTime openedAt; - /// Null while the Monad record is still being written. + /// Monad testnet transaction for this open. Null while it is being + /// written, and always null while the server has Monad off. final String? openTxHash; + + /// Solana devnet memo signature for this open. Null while it is being + /// written (a failed memo is sent again on the reader's next open). + final String? openSolanaSig; + + /// The open has a public receipt on at least one chain. + bool get isRecorded => openTxHash != null || openSolanaSig != null; } class CanaryNoteStatus { const CanaryNoteStatus({ required this.copyCount, required this.sealTxHash, + required this.sealSolanaSig, required this.expiresAt, required this.copies, }); final int copyCount; + + /// Monad testnet transaction that sealed the note. Null while the server + /// has Monad off. final String? sealTxHash; + + /// Solana devnet memo signature that sealed the note. + final String? sealSolanaSig; final DateTime expiresAt; /// Only copies that have been opened, ordered by copy index. final List copies; - /// Nothing more can change: every copy is opened and on Monad, or the - /// link has expired. Screens stop polling at this point. + /// Nothing more can change: every copy is opened and recorded on chain, + /// or the link has expired. Screens stop polling at this point. bool get isSettled => !expiresAt.isAfter(DateTime.now()) || - (copies.length >= copyCount && copies.every((c) => c.openTxHash != null)); + (copies.length >= copyCount && copies.every((c) => c.isRecorded)); CanaryCopyStatus? copy(int index) { for (final c in copies) { @@ -163,6 +194,7 @@ class CanaryOpenedCopy { required this.readerName, required this.openedAt, required this.openTxHash, + required this.openSolanaSig, }); /// The copy text, including its invisible marker. @@ -172,7 +204,12 @@ class CanaryOpenedCopy { final String readerName; final DateTime openedAt; - /// Null only in the rare case the Monad write succeeded but its hash was - /// not stored; the UI then shows the time without a proof link. + /// Monad testnet transaction for this open (earlier prototype). Null + /// while the server has Monad off. final String? openTxHash; + + /// Solana devnet memo signature for this open. Null when the memo has not + /// landed yet (it is sent again on the next open of this copy); the UI + /// then shows the time without a proof link. + final String? openSolanaSig; } diff --git a/app/lib/features/canary/presentation/canary_composer_screen.dart b/app/lib/features/canary/presentation/canary_composer_screen.dart index 227e0f2..5ea9154 100644 --- a/app/lib/features/canary/presentation/canary_composer_screen.dart +++ b/app/lib/features/canary/presentation/canary_composer_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../../../config/app_mode.dart'; import '../../../core/layout/app_breakpoints.dart'; import '../../../theme.dart'; import '../data/canary_api.dart'; @@ -455,10 +456,15 @@ class _CanaryComposerScreenState extends ConsumerState { ), const SizedBox(height: 16), const Text( - 'Your note is encrypted on this device. NO SUS stores only the ' - 'encrypted copies; the key travels inside the link. Monad testnet ' - 'receives only a hash of the copies and an anonymous tag per ' - 'reader, never the text or names.', + kCanaryMonad + ? 'Your note is encrypted on this device. NO SUS stores only the ' + 'encrypted copies; the key travels inside the link. Monad testnet ' + 'and Solana devnet receive only a hash of the copies and an ' + 'anonymous tag per reader, never the text or names.' + : 'Your note is encrypted on this device. NO SUS stores only the ' + 'encrypted copies; the key travels inside the link. Solana ' + 'devnet receives only a hash of the copies and an anonymous ' + 'tag per reader, never the text or names.', style: TextStyle( fontSize: 13, height: 1.55, diff --git a/app/lib/features/canary/presentation/canary_created_screen.dart b/app/lib/features/canary/presentation/canary_created_screen.dart index 8d764bf..325d9de 100644 --- a/app/lib/features/canary/presentation/canary_created_screen.dart +++ b/app/lib/features/canary/presentation/canary_created_screen.dart @@ -13,8 +13,8 @@ import '../domain/canary_models.dart'; import 'canary_note_screen.dart'; import 'canary_providers.dart'; import 'canary_ui.dart'; -import 'ui/chain_chip.dart'; import 'ui/glow_card.dart'; +import 'ui/proof_chips.dart'; import 'ui/swap_word_text.dart'; /// Shown right after creating a note, and from the dashboard's "Show QR". @@ -219,9 +219,13 @@ class _CanaryCreatedScreenState extends ConsumerState { ), ], ), - if (record.sealTxHash != null) ...[ + if (record.sealTxHash != null || record.sealSolanaSig != null) ...[ const SizedBox(height: 12), - ChainChip(label: 'Sealed on Monad', txHash: record.sealTxHash), + ProofChips( + monadTxHash: record.sealTxHash, + solanaSig: record.sealSolanaSig, + labelPrefix: 'Sealed on', + ), ], ], ); diff --git a/app/lib/features/canary/presentation/canary_home_screen.dart b/app/lib/features/canary/presentation/canary_home_screen.dart index e4d2f52..b162e23 100644 --- a/app/lib/features/canary/presentation/canary_home_screen.dart +++ b/app/lib/features/canary/presentation/canary_home_screen.dart @@ -94,14 +94,23 @@ class _CanaryHomeScreenState extends ConsumerState { static const double _maxWide = 1360; - static const _tickerItems = [ - 'EVERY OPEN = 1 MONAD TRANSACTION', - '~0.015 MON PER READER', - 'FINAL IN UNDER 1 SECOND', - 'NO WALLET NEEDED TO READ', - 'LEAK MATCHING STAYS ON YOUR DEVICE', - 'IT CANNOT STOP SCREENSHOTS. IT MAKES THEM TRACEABLE.', - ]; + static const _tickerItems = kCanaryMonad + ? [ + 'EVERY OPEN = 1 TX ON MONAD + 1 ON SOLANA', + '~0.015 MON PER READER', + 'FINAL IN UNDER 1 SECOND', + 'NO WALLET NEEDED TO READ', + 'LEAK MATCHING STAYS ON YOUR DEVICE', + 'IT CANNOT STOP SCREENSHOTS. IT MAKES THEM TRACEABLE.', + ] + : [ + 'EVERY OPEN = 1 MEMO ON SOLANA DEVNET', + '~0.000005 SOL PER READER', + 'ONLY HASHES GO ON CHAIN, NEVER TEXT', + 'NO WALLET NEEDED TO READ', + 'LEAK MATCHING STAYS ON YOUR DEVICE', + 'IT CANNOT STOP SCREENSHOTS. IT MAKES THEM TRACEABLE.', + ]; Widget _sectionTitle(String title, String subtitle) => Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -456,14 +465,21 @@ class _CanaryHomeScreenState extends ConsumerState { borderRadius: BorderRadius.circular(8), border: Border.all(color: CanaryTokens.text, width: 2), ), - child: const Text( - 'NO SUS x MONAD', - style: TextStyle( + // One line on wide screens; on a phone the three names of the + // Monad build would not fit in 320 px, so Solana takes a second + // line in the stamp. + child: Text( + !kCanaryMonad + ? 'NO SUS x SOLANA' + : expanded + ? 'NO SUS x MONAD x SOLANA' + : 'NO SUS x MONAD\nx SOLANA', + style: const TextStyle( color: CanaryTokens.text, fontFamily: CanaryTokens.monoFont, fontSize: 22, letterSpacing: 2, - height: 1, + height: 1.1, ), ), ), @@ -561,14 +577,19 @@ class _CanaryHomeScreenState extends ConsumerState { runSpacing: 12, crossAxisAlignment: WrapCrossAlignment.center, children: [ - if (kCanaryContract.isNotEmpty) - const ChainChip( - label: 'Contract on Monad', - txHash: kCanaryContract, - compact: true, - ), - const Text('~0.015 MON / READER', style: stat), - const Text('FINAL < 1 S', style: stat), + if (kCanaryMonad) ...[ + if (kCanaryContract.isNotEmpty) + const ChainChip( + label: 'Contract on Monad', + txHash: kCanaryContract, + compact: true, + ), + const Text('~0.015 MON / READER', style: stat), + const Text('FINAL < 1 S', style: stat), + ] else ...[ + const Text('SOLANA DEVNET', style: stat), + const Text('~0.000005 SOL / READER', style: stat), + ], InkWell( onTap: () => _openUrl(kCanaryRepoUrl), child: const Text( diff --git a/app/lib/features/canary/presentation/canary_note_screen.dart b/app/lib/features/canary/presentation/canary_note_screen.dart index 431fc8c..6ee6431 100644 --- a/app/lib/features/canary/presentation/canary_note_screen.dart +++ b/app/lib/features/canary/presentation/canary_note_screen.dart @@ -2,17 +2,20 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:url_launcher/url_launcher.dart'; +import '../../../config/app_mode.dart'; import '../../../core/layout/app_breakpoints.dart'; import '../../../theme.dart'; import '../data/canary_api.dart'; +import '../domain/canary_link.dart'; import '../domain/canary_models.dart'; import 'canary_created_screen.dart'; import 'canary_leak_check_screen.dart'; import 'canary_providers.dart'; import 'canary_ui.dart'; -import 'ui/chain_chip.dart'; import 'ui/glow_card.dart'; +import 'ui/proof_chips.dart'; import 'ui/wallet_button.dart'; /// Owner dashboard: live "Seen by" list plus the leak check. @@ -73,6 +76,25 @@ class _CanaryNoteScreenState extends ConsumerState { } } + Future _openSolanaSeal(String signature) async { + final ok = await launchUrl( + Uri.parse(canarySolanaExplorerTxUrl(signature)), + mode: LaunchMode.externalApplication, + ); + if (!ok && mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Could not open the explorer.')), + ); + } + } + + /// Solana is on for this note when its seal landed there; an open with no + /// signature yet is then "still being written" for a short while. + bool _solanaPending(CanaryNoteStatus status, CanaryCopyStatus copy) => + status.sealSolanaSig != null && + copy.openSolanaSig == null && + DateTime.now().difference(copy.openedAt) < const Duration(minutes: 2); + @override Widget build(BuildContext context) { final record = _record; @@ -180,10 +202,21 @@ class _CanaryNoteScreenState extends ConsumerState { ), ), ), - VerifyOnMonadButton( - noteId: record.noteId, - localOpened: status?.copies.length, - ), + if (kCanaryMonad) + VerifyOnMonadButton( + noteId: record.noteId, + localOpened: status?.copies.length, + ), + if (status?.sealSolanaSig case final sig?) + OutlinedButton.icon( + icon: const Icon(Icons.open_in_new, size: 18), + label: const Text( + 'Verify on Solana ↗', + semanticsLabel: 'Verify on Solana. Opens the seal on ' + 'Solana devnet in the explorer.', + ), + onPressed: () => _openSolanaSeal(sig), + ), OutlinedButton.icon( icon: const Icon(Icons.qr_code), label: const Text('Show link & QR'), @@ -214,6 +247,7 @@ class _CanaryNoteScreenState extends ConsumerState { margin: const EdgeInsets.only(bottom: 10), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), child: Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ CircleAvatar( backgroundColor: CanaryTokens.surfaceHi, @@ -233,25 +267,19 @@ class _CanaryNoteScreenState extends ConsumerState { color: CanaryTokens.textDim, ), ), + const SizedBox(height: 8), + // Below the name, not beside it: two chips need the + // card's full width to wrap on a phone. + ProofChips( + monadTxHash: copy.openTxHash, + solanaSig: copy.openSolanaSig, + monadPending: copy.openTxHash == null, + solanaPending: _solanaPending(status, copy), + compact: true, + ), ], ), ), - if (copy.openTxHash == null) - const Tooltip( - message: 'Recording on Monad…', - child: Icon( - Icons.hourglass_empty, - color: CanaryTokens.monad, - ), - ) - else - Flexible( - child: ChainChip( - label: 'Monad', - txHash: copy.openTxHash, - compact: true, - ), - ), ], ), ), diff --git a/app/lib/features/canary/presentation/canary_reader_screen.dart b/app/lib/features/canary/presentation/canary_reader_screen.dart index 3cdcd1d..3f615a2 100644 --- a/app/lib/features/canary/presentation/canary_reader_screen.dart +++ b/app/lib/features/canary/presentation/canary_reader_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../../../config/app_mode.dart'; import '../../../core/layout/app_breakpoints.dart'; import '../../../theme.dart'; import '../data/canary_api.dart'; @@ -8,11 +9,11 @@ import '../domain/canary_models.dart'; import 'canary_providers.dart'; import 'canary_ui.dart'; import 'ui/canary_envelope.dart'; -import 'ui/chain_chip.dart'; import 'ui/copy_badge.dart'; import 'ui/glow_card.dart'; import 'ui/liquid_carve_button.dart'; import 'ui/pixel_canary.dart'; +import 'ui/proof_chips.dart'; import 'ui/canary_strip.dart'; /// Standalone app for the web reader path (main.dart runs it directly for @@ -273,8 +274,13 @@ class _CanaryReaderScreenState extends ConsumerState { ), const SizedBox(height: 16), const Text( - 'The sender sees your name and when you opened your copy. Monad ' - 'testnet records that a copy was opened, without your name.', + kCanaryMonad + ? 'The sender sees your name and when you opened your copy. Monad ' + 'testnet and Solana devnet each record that a copy was opened, ' + 'without your name.' + : 'The sender sees your name and when you opened your copy. ' + 'Solana devnet records that a copy was opened, without ' + 'your name.', style: TextStyle( fontSize: 14, height: 1.55, @@ -316,14 +322,21 @@ class _CanaryReaderScreenState extends ConsumerState { const SizedBox(height: 12), DelayedFadeIn( delay: const Duration(milliseconds: 450), - child: copy.openTxHash == null + // No polling here, so no pending chip: show the proofs that + // exist, or the time alone when no shown proof was stored. + child: + copy.openSolanaSig == null && + (!kCanaryMonad || copy.openTxHash == null) ? Text( - 'Recorded on Monad testnet at ${CanaryUi.clock(copy.openedAt)}', + kCanaryMonad + ? 'Recorded on Monad testnet at ${CanaryUi.clock(copy.openedAt)}' + : 'Opened at ${CanaryUi.clock(copy.openedAt)}', style: const TextStyle(fontFamily: CanaryTokens.monoFont), ) - : ChainChip( - label: 'Recorded on Monad', - txHash: copy.openTxHash, + : ProofChips( + monadTxHash: copy.openTxHash, + solanaSig: copy.openSolanaSig, + labelPrefix: 'Recorded on', ), ), ], @@ -337,7 +350,9 @@ class _BrandSide extends StatelessWidget { static const _facts = [ 'YOUR COPY IS UNIQUE TO YOU', - 'OPENING IT = 1 MONAD TRANSACTION', + kCanaryMonad + ? 'OPENING IT = 1 TX ON MONAD + 1 ON SOLANA' + : 'OPENING IT = 1 MEMO ON SOLANA DEVNET', 'NO WALLET, NO APP, NO SIGN-UP', ]; @@ -363,7 +378,9 @@ class _BrandSide extends StatelessWidget { ), const SizedBox(height: 14), const Text( - ' Your own copy. Recorded on Monad. ', + kCanaryMonad + ? ' Your own copy. Recorded on Monad + Solana. ' + : ' Your own copy. Recorded on Solana. ', style: TextStyle( fontFamily: CanaryTokens.displayFont, fontSize: 26, diff --git a/app/lib/features/canary/presentation/canary_ui.dart b/app/lib/features/canary/presentation/canary_ui.dart index 20fac40..b09ab51 100644 --- a/app/lib/features/canary/presentation/canary_ui.dart +++ b/app/lib/features/canary/presentation/canary_ui.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; +import '../../../config/app_mode.dart'; import '../../../core/layout/app_breakpoints.dart'; import '../../../theme.dart'; import '../domain/canary_link.dart'; @@ -97,7 +98,8 @@ class CanaryUi { ), actions: [ ...?actions, - const WalletButton(compact: true), + if (kCanaryMonad) + const WalletButton(compact: true), const SizedBox(width: 8), ], ), diff --git a/app/lib/features/canary/presentation/ui/canary_envelope.dart b/app/lib/features/canary/presentation/ui/canary_envelope.dart index 50cb8f1..3e995b5 100644 --- a/app/lib/features/canary/presentation/ui/canary_envelope.dart +++ b/app/lib/features/canary/presentation/ui/canary_envelope.dart @@ -2,6 +2,7 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; +import '../../../../config/app_mode.dart'; import '../../../../theme.dart'; import 'canary_mark.dart'; import 'glow_card.dart'; @@ -18,7 +19,7 @@ class BobbingCanaryMark extends StatelessWidget { Widget build(BuildContext context) => PixelCanary(size: size); } -/// Sealed envelope shown while the copy is assigned on Monad. +/// Sealed envelope shown while the copy is assigned and recorded on chain. class CanaryEnvelope extends StatefulWidget { const CanaryEnvelope({super.key}); @@ -67,7 +68,9 @@ class _CanaryEnvelopeState extends State const CanaryMark(size: 56), const SizedBox(height: 16), Text( - 'Making your copy… recording it on Monad', + kCanaryMonad + ? 'Making your copy… recording it on Monad' + : 'Making your copy… recording it on Solana', textAlign: TextAlign.center, style: Theme.of(context).textTheme.titleMedium, ), diff --git a/app/lib/features/canary/presentation/ui/canary_nav_bar.dart b/app/lib/features/canary/presentation/ui/canary_nav_bar.dart index 54bff8d..d9095f9 100644 --- a/app/lib/features/canary/presentation/ui/canary_nav_bar.dart +++ b/app/lib/features/canary/presentation/ui/canary_nav_bar.dart @@ -97,16 +97,19 @@ class CanaryTopBar extends StatelessWidget implements PreferredSizeWidget { ], ), - // Right side: Monad pulse pill + NO SUS app link + // Right side: network pulse pill (+ Monad wallet when the + // CANARY_MONAD build flag is on) + NO SUS app link Row( mainAxisSize: MainAxisSize.min, children: [ if (showPill) ...[ - const MonadTestnetPill(), + const NetworkPill(), const SizedBox(width: 14), ], - WalletButton(compact: !expanded), - const SizedBox(width: 12), + if (kCanaryMonad) ...[ + WalletButton(compact: !expanded), + const SizedBox(width: 12), + ], if (standalone) expanded ? ConstrainedBox( @@ -239,15 +242,23 @@ class _NavLinkState extends State<_NavLink> { } } -/// Pulsing "Monad testnet" indicator pill. -class MonadTestnetPill extends StatefulWidget { - const MonadTestnetPill({super.key}); +/// Name of the network Canary proofs land on, for pills and strips. +/// "SOLANA DEVNET", or "MONAD TESTNET" in a CANARY_MONAD build. +const String kCanaryNetworkLabel = kCanaryMonad + ? 'MONAD TESTNET' + : 'SOLANA DEVNET'; + +/// Pulsing network indicator pill ([kCanaryNetworkLabel]). +class NetworkPill extends StatefulWidget { + const NetworkPill({super.key, this.label = kCanaryNetworkLabel}); + + final String label; @override - State createState() => _MonadTestnetPillState(); + State createState() => _NetworkPillState(); } -class _MonadTestnetPillState extends State +class _NetworkPillState extends State with SingleTickerProviderStateMixin { late final AnimationController _controller; @@ -307,9 +318,9 @@ class _MonadTestnetPillState extends State }, ), const SizedBox(width: 8), - const Text( - 'MONAD TESTNET', - style: TextStyle( + Text( + widget.label, + style: const TextStyle( fontFamily: CanaryTokens.monoFont, fontSize: 21, letterSpacing: 1, @@ -443,11 +454,13 @@ class CanaryFooter extends StatelessWidget { spacing: 12, runSpacing: 8, children: [ - const Text( - 'Built at Monad Blitz Mumbai V4', - style: TextStyle(color: CanaryTokens.textDim, fontSize: 13), - ), - const Text('·', style: TextStyle(color: CanaryTokens.textDim)), + if (kCanaryMonad) ...[ + const Text( + 'Built at Monad Blitz Mumbai V4', + style: TextStyle(color: CanaryTokens.textDim, fontSize: 13), + ), + const Text('·', style: TextStyle(color: CanaryTokens.textDim)), + ], InkWell( onTap: () => _openUrl(context, 'https://nosus.foo'), child: const Text( diff --git a/app/lib/features/canary/presentation/ui/canary_reveal.dart b/app/lib/features/canary/presentation/ui/canary_reveal.dart index 48e5f2a..a2ac73d 100644 --- a/app/lib/features/canary/presentation/ui/canary_reveal.dart +++ b/app/lib/features/canary/presentation/ui/canary_reveal.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; +import '../../../../config/app_mode.dart'; import '../../../../theme.dart'; import '../../domain/canary_fingerprint.dart'; +import '../../domain/canary_link.dart'; import '../../domain/canary_models.dart'; import '../canary_ui.dart'; import 'canary_mark.dart'; @@ -126,9 +128,16 @@ class _CanaryRevealState extends State 'Opened ${CanaryUi.clock(copy.openedAt)}', style: const TextStyle(fontFamily: CanaryTokens.monoFont), ), - if (copy.openTxHash != null) ...[ + if (kCanaryMonad && copy.openTxHash != null) ...[ const SizedBox(height: 8), ChainChip(label: 'Proof on Monad', txHash: copy.openTxHash), + ] else if (!kCanaryMonad && copy.openSolanaSig != null) ...[ + const SizedBox(height: 8), + ChainChip( + chain: CanaryChain.solana, + label: 'Proof on Solana', + txHash: copy.openSolanaSig, + ), ], ], const SizedBox(height: 8), diff --git a/app/lib/features/canary/presentation/ui/canary_strip.dart b/app/lib/features/canary/presentation/ui/canary_strip.dart index b9911cf..930c535 100644 --- a/app/lib/features/canary/presentation/ui/canary_strip.dart +++ b/app/lib/features/canary/presentation/ui/canary_strip.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import '../../../../theme.dart'; +import 'canary_nav_bar.dart' show kCanaryNetworkLabel; /// Orange "testnet" strip across the top of the Canary web app. class CanaryStrip extends StatelessWidget { @@ -24,7 +25,7 @@ class CanaryStrip extends StatelessWidget { child: const SafeArea( bottom: false, child: Text( - 'NO SUS · MONAD TESTNET · USE HARMLESS TEST NOTES ONLY', + 'NO SUS · $kCanaryNetworkLabel · USE HARMLESS TEST NOTES ONLY', textAlign: TextAlign.center, maxLines: 1, overflow: TextOverflow.ellipsis, diff --git a/app/lib/features/canary/presentation/ui/chain_chip.dart b/app/lib/features/canary/presentation/ui/chain_chip.dart index b4cfb50..a1b76d8 100644 --- a/app/lib/features/canary/presentation/ui/chain_chip.dart +++ b/app/lib/features/canary/presentation/ui/chain_chip.dart @@ -4,33 +4,70 @@ import 'package:url_launcher/url_launcher.dart'; import '../../../../theme.dart'; import '../../domain/canary_link.dart'; -/// On-chain status pill. Monad purple only; hash is VT323. +/// Ink and tint for one chain's chip. Monad keeps the orange paper tint with +/// an ink border; Solana gets a single restrained teal ink (5.7:1 on the +/// paper background) so the two proofs read apart without a brand gradient. +class _ChainStyle { + const _ChainStyle({required this.ink, required this.tint}); + + final Color ink; + final Color tint; + + static const Color _solanaInk = Color(0xFF0F6E63); + + static _ChainStyle of(CanaryChain chain) => switch (chain) { + CanaryChain.monad => const _ChainStyle( + ink: CanaryTokens.monad, + tint: Color(0x40F28C28), + ), + CanaryChain.solana => const _ChainStyle( + ink: _solanaInk, + tint: Color(0x1F0F6E63), + ), + }; +} + +const TextStyle _chipText = TextStyle( + fontFamily: CanaryTokens.monoFont, + fontSize: 20, + color: CanaryTokens.text, + height: 1.2, +); + +/// On-chain status pill. Border and icon take the chain's ink; hash is VT323. class ChainChip extends StatelessWidget { const ChainChip({ super.key, required this.label, this.txHash, + this.chain = CanaryChain.monad, this.compact = false, }); final String label; final String? txHash; + final CanaryChain chain; final bool compact; + /// `0x1234…abcd` for hex hashes, `5VfY…Qm2p` for base58 signatures. static String shortHash(String hash) { - final h = hash.startsWith('0x') ? hash.substring(2) : hash; + final hex = hash.startsWith('0x'); + final h = hex ? hash.substring(2) : hash; if (h.length < 10) return hash; - return '0x${h.substring(0, 4)}…${h.substring(h.length - 4)}'; + final short = '${h.substring(0, 4)}…${h.substring(h.length - 4)}'; + return hex ? '0x$short' : short; } Future _open(BuildContext context) async { final hash = txHash; if (hash == null) return; + // A 42-char 0x value is a Monad address (the contract), not a tx. + final isMonadAddress = chain == CanaryChain.monad && hash.length == 42; final ok = await launchUrl( Uri.parse( - hash.length == 42 + isMonadAddress ? 'https://testnet.monadscan.com/address/$hash' - : canaryExplorerTxUrl(hash), + : chain.txUrl(hash), ), mode: LaunchMode.externalApplication, ); @@ -44,14 +81,15 @@ class ChainChip extends StatelessWidget { @override Widget build(BuildContext context) { final hash = txHash; + final style = _ChainStyle.of(chain); final text = hash == null ? label : '$label · ${shortHash(hash)}'; final chip = ConstrainedBox( constraints: const BoxConstraints(minHeight: 48), child: DecoratedBox( decoration: BoxDecoration( - color: const Color(0x40F28C28), + color: style.tint, borderRadius: BorderRadius.circular(CanaryTokens.rChip), - border: Border.all(color: CanaryTokens.monad), + border: Border.all(color: style.ink), ), child: Padding( padding: EdgeInsets.symmetric( @@ -61,18 +99,9 @@ class ChainChip extends StatelessWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - const Icon(Icons.link, size: 18, color: CanaryTokens.monad), + Icon(Icons.link, size: 18, color: style.ink), const SizedBox(width: 8), - Text( - text, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontFamily: CanaryTokens.monoFont, - fontSize: 20, - color: CanaryTokens.text, - height: 1.2, - ), - ), + Text(text, overflow: TextOverflow.ellipsis, style: _chipText), ], ), ), @@ -84,7 +113,7 @@ class ChainChip extends StatelessWidget { } return Semantics( button: true, - label: '$label. View proof on Monad testnet.', + label: '$label. View proof on ${chain.network}.', child: Material( color: Colors.transparent, child: InkWell( @@ -96,3 +125,59 @@ class ChainChip extends StatelessWidget { ); } } + +/// Same silhouette as [ChainChip] for a proof that is still being written: +/// a 16 px progress ring plus "Monad…" / "Solana…". Not tappable. +class PendingChainChip extends StatelessWidget { + const PendingChainChip({ + super.key, + required this.chain, + this.compact = false, + }); + + final CanaryChain chain; + final bool compact; + + @override + Widget build(BuildContext context) { + final style = _ChainStyle.of(chain); + final message = 'Recording on ${chain.network}…'; + return Semantics( + label: message, + excludeSemantics: true, + child: Tooltip( + message: message, + child: ConstrainedBox( + constraints: const BoxConstraints(minHeight: 48), + child: DecoratedBox( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(CanaryTokens.rChip), + border: Border.all(color: style.ink.withValues(alpha: 0.6)), + ), + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: compact ? 12 : 16, + vertical: 10, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator( + strokeWidth: 2, + color: style.ink, + ), + ), + const SizedBox(width: 8), + Text('${chain.label}…', style: _chipText), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/app/lib/features/canary/presentation/ui/proof_chips.dart b/app/lib/features/canary/presentation/ui/proof_chips.dart new file mode 100644 index 0000000..025793a --- /dev/null +++ b/app/lib/features/canary/presentation/ui/proof_chips.dart @@ -0,0 +1,75 @@ +import 'package:flutter/material.dart'; + +import '../../../../config/app_mode.dart'; +import '../../domain/canary_link.dart'; +import 'chain_chip.dart'; + +/// The on-chain proofs for one seal or one open. +/// +/// Solana devnet is the receipt: its chip shows whenever a signature exists. +/// The Monad testnet chip (earlier prototype) shows only when [showMonad] is +/// true, which defaults to the CANARY_MONAD build flag ([kCanaryMonad]). +/// +/// A [ChainChip] is shown for every hash that exists. A null hash shows a +/// [PendingChainChip] only when the matching `pending` flag is true, so a +/// chain that is switched off simply does not appear. Chips wrap onto new +/// rows instead of clipping on narrow screens. +class ProofChips extends StatelessWidget { + const ProofChips({ + super.key, + this.monadTxHash, + this.solanaSig, + this.monadPending = false, + this.solanaPending = false, + this.labelPrefix = '', + this.compact = false, + bool? showMonad, + }) : showMonad = showMonad ?? kCanaryMonad; + + final String? monadTxHash; + final String? solanaSig; + + /// Show a progress chip while the Monad record is still being written. + final bool monadPending; + + /// Show a progress chip while the Solana record is still being written. + final bool solanaPending; + + /// 'Sealed on' / 'Recorded on' / '' (bare chain name). + final String labelPrefix; + final bool compact; + + /// Whether the Monad chip may appear at all. + final bool showMonad; + + String _label(CanaryChain chain) => + labelPrefix.isEmpty ? chain.label : '$labelPrefix ${chain.label}'; + + Widget? _chip(CanaryChain chain, String? hash, bool pending) { + if (hash != null) { + return ChainChip( + chain: chain, + label: _label(chain), + txHash: hash, + compact: compact, + ); + } + if (pending) return PendingChainChip(chain: chain, compact: compact); + return null; + } + + @override + Widget build(BuildContext context) { + final chips = [ + if (showMonad) _chip(CanaryChain.monad, monadTxHash, monadPending), + _chip(CanaryChain.solana, solanaSig, solanaPending), + ].nonNulls.toList(); + if (chips.isEmpty) return const SizedBox.shrink(); + return Wrap( + spacing: 8, + runSpacing: 8, + crossAxisAlignment: WrapCrossAlignment.center, + children: chips, + ); + } +} diff --git a/app/lib/features/monad/data/monad_rpc_repository.dart b/app/lib/features/monad/data/monad_rpc_repository.dart deleted file mode 100644 index 82ea781..0000000 --- a/app/lib/features/monad/data/monad_rpc_repository.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'dart:convert'; -import 'package:http/http.dart' as http; -import '../domain/monad_receipt.dart'; -import '../domain/monad_repository.dart'; - -class MonadRpcRepository implements MonadRepository { - MonadRpcRepository({ - http.Client? client, - String? contractAddress, - Uri? rpcUrl, - }) : _client = client ?? http.Client(), - _contract = - contractAddress ?? - const String.fromEnvironment('MONAD_DROPS_CONTRACT'), - _rpc = rpcUrl ?? Uri.parse('https://testnet-rpc.monad.xyz'); - final http.Client _client; - final String _contract; - final Uri _rpc; - - @override - bool get isConfigured => - RegExp(r'^0x[0-9a-fA-F]{40}$').hasMatch(_contract) && - _contract.toLowerCase() != MonadReceipt.zeroAddress; - - Future _call(String method, List params) async { - final response = await _client - .post( - _rpc, - headers: {'Content-Type': 'application/json'}, - body: jsonEncode({ - 'jsonrpc': '2.0', - 'id': 1, - 'method': method, - 'params': params, - }), - ) - .timeout(const Duration(seconds: 15)); - if (response.statusCode != 200) { - throw StateError('Monad is unavailable. Try again shortly.'); - } - final decoded = jsonDecode(response.body); - if (decoded is! Map || - decoded['id'] != 1 || - decoded['error'] != null || - decoded['result'] is! String) { - throw StateError( - 'No receipt could be verified. Check the ID and try again.', - ); - } - return decoded['result'] as String; - } - - @override - Future receiptOf(String id) async { - final dropId = parseMonadDropId(id); - if (dropId == null) { - throw const FormatException('Enter a valid Monad receipt ID.'); - } - if (!isConfigured) { - throw StateError('The testnet receipt contract is not deployed yet.'); - } - final chain = await _call('eth_chainId', const []); - if (BigInt.tryParse(chain.replaceFirst('0x', ''), radix: 16) != - BigInt.from(10143)) { - throw StateError('This experiment requires Monad testnet (10143).'); - } - final code = await _call('eth_getCode', [_contract, 'latest']); - if (code == '0x' || code == '0x0') { - throw StateError('No contract exists at the configured address.'); - } - final data = await _call('eth_call', [ - {'to': _contract, 'data': '0x72a41fdd${dropId.substring(2)}'}, - 'latest', - ]); - return MonadReceipt.fromAbi(dropId, data); - } - - void dispose() => _client.close(); -} diff --git a/app/lib/features/monad/domain/monad_receipt.dart b/app/lib/features/monad/domain/monad_receipt.dart deleted file mode 100644 index e9a23b3..0000000 --- a/app/lib/features/monad/domain/monad_receipt.dart +++ /dev/null @@ -1,80 +0,0 @@ -/// Public acknowledgement metadata. Never contains note content or keys. -class MonadReceipt { - const MonadReceipt({ - required this.id, - required this.sender, - required this.recipient, - required this.opener, - required this.ciphertextDigest, - required this.sealedAt, - required this.openedAt, - required this.expiresAt, - }); - - static const zeroAddress = '0x0000000000000000000000000000000000000000'; - final String id, sender, recipient, opener, ciphertextDigest; - final int sealedAt, openedAt, expiresAt; - bool get acknowledged => opener != zeroAddress; - bool isExpired(DateTime now) => - expiresAt != 0 && now.millisecondsSinceEpoch ~/ 1000 >= expiresAt; - String status(DateTime now) => acknowledged - ? (isExpired(now) ? 'Acknowledged · access expired' : 'Acknowledged') - : (isExpired(now) - ? 'Expired without acknowledgement' - : 'Awaiting acknowledgement'); - - factory MonadReceipt.fromAbi(String id, String data) { - if (!RegExp(r'^0x[0-9a-fA-F]{448}$').hasMatch(data)) { - throw const FormatException('The contract returned an invalid receipt.'); - } - final words = List.generate( - 7, - (i) => data.substring(2 + i * 64, 2 + (i + 1) * 64), - ); - for (final word in words.take(3)) { - if (!word.startsWith('0' * 24)) { - throw const FormatException('Invalid wallet address in receipt.'); - } - } - int timestamp(int index) { - final value = BigInt.parse(words[index], radix: 16); - if (value > BigInt.from(8640000000000)) { - throw const FormatException('Invalid receipt timestamp.'); - } - return value.toInt(); - } - - final sender = '0x${words[0].substring(24)}'.toLowerCase(); - if (sender == zeroAddress) { - throw const FormatException('Receipt does not exist.'); - } - return MonadReceipt( - id: id.toLowerCase(), - sender: sender, - recipient: '0x${words[1].substring(24)}'.toLowerCase(), - opener: '0x${words[2].substring(24)}'.toLowerCase(), - ciphertextDigest: '0x${words[3]}'.toLowerCase(), - sealedAt: timestamp(4), - openedAt: timestamp(5), - expiresAt: timestamp(6), - ); - } -} - -/// Never forward arbitrary URLs or Burn fragments to the RPC. -String? parseMonadDropId(String input) { - final text = input.trim(); - if (RegExp(r'^0x[0-9a-fA-F]{64}$').hasMatch(text)) return text.toLowerCase(); - final uri = Uri.tryParse(text); - if (uri == null || - uri.scheme != 'https' || - uri.host != 'monad.nosus.foo' || - uri.userInfo.isNotEmpty || - uri.hasQuery || - uri.path != '/') { - return null; - } - return RegExp( - r'^/monad/(0x[0-9a-fA-F]{64})$', - ).firstMatch(uri.fragment)?.group(1)?.toLowerCase(); -} diff --git a/app/lib/features/monad/domain/monad_repository.dart b/app/lib/features/monad/domain/monad_repository.dart deleted file mode 100644 index dcdf255..0000000 --- a/app/lib/features/monad/domain/monad_repository.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'monad_receipt.dart'; - -abstract interface class MonadRepository { - bool get isConfigured; - Future receiptOf(String id); -} diff --git a/app/lib/features/monad/presentation/monad_entry_card.dart b/app/lib/features/monad/presentation/monad_entry_card.dart deleted file mode 100644 index 866f0c9..0000000 --- a/app/lib/features/monad/presentation/monad_entry_card.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'monad_screen.dart'; - -class MonadEntryCard extends StatelessWidget { - const MonadEntryCard({super.key}); - @override - Widget build(BuildContext context) => Card.outlined( - margin: const EdgeInsets.symmetric(vertical: 12), - child: ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), - leading: const Icon(Icons.verified_outlined), - title: const Text('Monad receipts'), - subtitle: const Text( - 'A wallet acknowledgement for an encrypted note. Explore the experiment.', - ), - trailing: const Icon(Icons.chevron_right), - onTap: () => Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => const MonadScreen(), - settings: const RouteSettings(name: '/monad'), - ), - ), - ), - ); -} diff --git a/app/lib/features/monad/presentation/monad_providers.dart b/app/lib/features/monad/presentation/monad_providers.dart deleted file mode 100644 index ba0d807..0000000 --- a/app/lib/features/monad/presentation/monad_providers.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import '../data/monad_rpc_repository.dart'; -import '../domain/monad_repository.dart'; - -final monadRepositoryProvider = Provider((ref) { - final repository = MonadRpcRepository(); - ref.onDispose(repository.dispose); - return repository; -}); - -// Not an environment flag. Requires browser custody implementation and all -// six recorded Gate T1 proofs before it may become true. -const monadThresholdVerified = false; diff --git a/app/lib/features/monad/presentation/monad_screen.dart b/app/lib/features/monad/presentation/monad_screen.dart deleted file mode 100644 index b57fd31..0000000 --- a/app/lib/features/monad/presentation/monad_screen.dart +++ /dev/null @@ -1,288 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import '../domain/monad_receipt.dart'; -import 'monad_providers.dart'; - -class MonadScreen extends ConsumerStatefulWidget { - const MonadScreen({super.key, this.dropId}); - final String? dropId; - @override - ConsumerState createState() => _MonadScreenState(); -} - -class _MonadScreenState extends ConsumerState { - final _input = TextEditingController(); - MonadReceipt? _receipt; - String? _error; - bool _loading = false; - @override - void initState() { - super.initState(); - _input.text = widget.dropId ?? ''; - if (widget.dropId != null) { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (mounted) _verify(); - }); - } - } - - @override - void dispose() { - _input.dispose(); - super.dispose(); - } - - Future _verify() async { - if (_loading) return; - final id = parseMonadDropId(_input.text); - setState(() { - _receipt = null; - _error = null; - }); - if (id == null) { - setState( - () => _error = - 'Enter a 0x receipt ID (64 hex characters), or a Monad receipt link.', - ); - return; - } - setState(() => _loading = true); - try { - final receipt = await ref.read(monadRepositoryProvider).receiptOf(id); - if (mounted) setState(() => _receipt = receipt); - } on FormatException catch (error) { - if (mounted) setState(() => _error = error.message); - } on StateError catch (error) { - if (mounted) setState(() => _error = error.message); - } catch (_) { - if (mounted) { - setState( - () => _error = - 'Could not reach Monad. Check your connection and try again.', - ); - } - } finally { - if (mounted) setState(() => _loading = false); - } - } - - Widget _step(String number, String title, String body) => Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(number, style: Theme.of(context).textTheme.titleMedium), - const SizedBox(width: 18), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(title, style: Theme.of(context).textTheme.titleSmall), - const SizedBox(height: 4), - Text(body), - ], - ), - ), - ], - ), - ); - String _time(int seconds) => seconds == 0 - ? '—' - : '${DateTime.fromMillisecondsSinceEpoch(seconds * 1000, isUtc: true).toIso8601String()} (UTC)'; - - @override - Widget build(BuildContext context) { - final configured = ref.watch(monadRepositoryProvider).isConfigured; - final receipt = _receipt; - return Scaffold( - appBar: AppBar(title: const Text('Monad receipts')), - body: Center( - child: ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 720), - child: ListView( - padding: const EdgeInsets.all(24), - children: [ - Text( - 'NO SUS — MONAD EXPERIMENT', - style: Theme.of(context).textTheme.labelSmall, - ), - const SizedBox(height: 20), - Text( - 'Share a note.\nKeep the acknowledgement.', - style: Theme.of(context).textTheme.headlineLarge, - ), - const SizedBox(height: 14), - const Text( - 'An optional receipt for handoffs where the receiving wallet matters. ' - 'Your Workspace, Vault, Study Desk and Burn tools remain part of this app.', - ), - const SizedBox(height: 24), - const Card.outlined( - child: Padding( - padding: EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Encrypted Monad sharing is not available yet', - style: TextStyle(fontWeight: FontWeight.w700), - ), - SizedBox(height: 12), - Text( - 'We still need to verify that only the acknowledged wallet can decrypt. ' - 'Use harmless test data in this experimental app.', - ), - SizedBox(height: 16), - FilledButton( - onPressed: null, - child: Text('Send with a Monad receipt'), - ), - ], - ), - ), - ), - const SizedBox(height: 20), - Text( - 'How the planned handoff works', - style: Theme.of(context).textTheme.titleLarge, - ), - _step( - '01', - 'Address it to a wallet', - 'Encrypt a note for a recipient and choose an expiry.', - ), - _step( - '02', - 'The recipient acknowledges', - 'Their wallet records an acknowledgement on Monad testnet.', - ), - _step( - '03', - 'Unlock and verify', - 'Threshold custody permits decryption; the public receipt remains verifiable.', - ), - const Divider(height: 40), - Text( - 'Verify a receipt', - style: Theme.of(context).textTheme.titleLarge, - ), - const SizedBox(height: 8), - const Text( - 'Read public acknowledgement metadata directly from Monad. No wallet connection required.', - ), - if (!configured) - const Padding( - padding: EdgeInsets.only(top: 12), - child: Text( - 'Waiting for the testnet contract deployment. Receipt lookup will become available here.', - ), - ), - const SizedBox(height: 16), - TextField( - controller: _input, - enabled: !_loading, - autocorrect: false, - enableSuggestions: false, - decoration: const InputDecoration( - labelText: 'Receipt ID or Monad receipt link', - hintText: '0x…', - border: OutlineInputBorder(), - ), - onChanged: (_) { - if (_receipt != null || _error != null) { - setState(() { - _receipt = null; - _error = null; - }); - } - }, - onSubmitted: configured ? (_) => _verify() : null, - ), - const SizedBox(height: 12), - FilledButton.icon( - onPressed: configured && !_loading ? _verify : null, - icon: _loading - ? const SizedBox( - width: 16, - height: 16, - child: CircularProgressIndicator(strokeWidth: 2), - ) - : const Icon(Icons.search), - label: Text(_loading ? 'Checking Monad…' : 'Verify receipt'), - ), - if (_error != null) - Padding( - padding: const EdgeInsets.only(top: 16), - child: Semantics( - liveRegion: true, - child: Text( - _error!, - style: TextStyle( - color: Theme.of(context).colorScheme.error, - ), - ), - ), - ), - if (receipt != null) ...[ - const SizedBox(height: 20), - Card.outlined( - child: Padding( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Semantics( - liveRegion: true, - child: Text( - receipt.status(DateTime.now()), - style: Theme.of(context).textTheme.titleLarge, - ), - ), - const SizedBox(height: 16), - SelectableText( - 'Sender\n${receipt.sender}\n\nRecipient\n${receipt.recipient == MonadReceipt.zeroAddress ? 'First eligible wallet' : receipt.recipient}' - '\n\nAcknowledged by\n${receipt.acknowledged ? receipt.opener : 'No wallet yet'}' - '\n\nSealed\n${_time(receipt.sealedAt)}\n\nAcknowledged\n${_time(receipt.openedAt)}' - '\n\nExpiry\n${receipt.expiresAt == 0 ? 'No expiry' : _time(receipt.expiresAt)}' - '\n\nEncrypted-content digest\n${receipt.ciphertextDigest}', - ), - const SizedBox(height: 16), - OutlinedButton.icon( - icon: const Icon(Icons.copy), - label: const Text('Copy receipt link'), - onPressed: () async { - await Clipboard.setData( - ClipboardData( - text: - 'https://monad.nosus.foo/#/monad/${receipt.id}', - ), - ); - if (context.mounted) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Receipt link copied'), - ), - ); - } - }, - ), - ], - ), - ), - ), - ], - const SizedBox(height: 24), - const Text( - 'A receipt proves a wallet acknowledged an encrypted drop. It does not prove ' - 'that a person read it or that decryption succeeded. Wallet addresses and timestamps ' - 'are public. Recipients can keep content after decrypting it.', - style: TextStyle(fontSize: 12), - ), - ], - ), - ), - ), - ); - } -} diff --git a/app/lib/features/share/presentation/screens/anonymous_share_viewer_screen.dart b/app/lib/features/share/presentation/screens/anonymous_share_viewer_screen.dart index b41037f..34d60b6 100644 --- a/app/lib/features/share/presentation/screens/anonymous_share_viewer_screen.dart +++ b/app/lib/features/share/presentation/screens/anonymous_share_viewer_screen.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:flutter/material.dart'; -import '../../../monad/presentation/experiment_frame.dart'; +import '../../../../components/experiment_frame.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:http/http.dart' as http; import 'package:pdfrx/pdfrx.dart'; diff --git a/app/lib/features/share/presentation/screens/burn_file_viewer_screen.dart b/app/lib/features/share/presentation/screens/burn_file_viewer_screen.dart index df94ebb..624b2eb 100644 --- a/app/lib/features/share/presentation/screens/burn_file_viewer_screen.dart +++ b/app/lib/features/share/presentation/screens/burn_file_viewer_screen.dart @@ -1,6 +1,6 @@ import 'package:encrypt/encrypt.dart' as enc; import 'package:flutter/material.dart'; -import '../../../monad/presentation/experiment_frame.dart'; +import '../../../../components/experiment_frame.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:http/http.dart' as http; import 'package:share_plus/share_plus.dart'; diff --git a/app/lib/features/share/presentation/screens/burn_note_viewer_screen.dart b/app/lib/features/share/presentation/screens/burn_note_viewer_screen.dart index 072440f..61a942d 100644 --- a/app/lib/features/share/presentation/screens/burn_note_viewer_screen.dart +++ b/app/lib/features/share/presentation/screens/burn_note_viewer_screen.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import '../../../monad/presentation/experiment_frame.dart'; +import '../../../../components/experiment_frame.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; diff --git a/app/lib/main.dart b/app/lib/main.dart index fb1fba8..84cb73a 100644 --- a/app/lib/main.dart +++ b/app/lib/main.dart @@ -1,7 +1,5 @@ import 'dart:async'; -import 'features/monad/domain/monad_receipt.dart'; -import 'features/monad/presentation/experiment_frame.dart'; -import 'features/monad/presentation/monad_screen.dart'; +import 'components/experiment_frame.dart'; import 'features/canary/domain/canary_link.dart'; import 'features/canary/presentation/canary_app.dart'; import 'features/canary/presentation/canary_home_screen.dart'; @@ -615,12 +613,6 @@ class MyApp extends ConsumerWidget { builder: (_) => const CanaryHomeScreen(), ); } - if (route == '/monad' || route.startsWith('/monad/')) { - final id = route.startsWith('/monad/') - ? parseMonadDropId(route.substring('/monad/'.length)) : null; - return MaterialPageRoute(settings: settings, - builder: (_) => MonadScreen(dropId: id)); - } // Web OAuth (Google/GitHub) redirects land on e.g. "/?code=..." — not // exactly "/", so Flutter treats it as a distinct route instead of // falling back to `home`. By the time this builds, Supabase has diff --git a/app/pubspec.lock b/app/pubspec.lock index 07fb904..e72720d 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -700,10 +700,10 @@ packages: dependency: transitive description: name: matcher - sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 + sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" url: "https://pub.dev" source: hosted - version: "0.12.19" + version: "0.12.20" material_color_utilities: dependency: transitive description: @@ -724,10 +724,10 @@ packages: dependency: transitive description: name: meta - sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" + sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" mime: dependency: transitive description: @@ -1257,26 +1257,26 @@ packages: dependency: transitive description: name: test - sha256: "8d9ceddbab833f180fbefed08afa76d7c03513dfdba87ffcec2718b02bbcbf20" + sha256: ca578dc12bb8b2f40b67b7d3bd2fac4f31c01a6ff7130a14e2597b919934507f url: "https://pub.dev" source: hosted - version: "1.31.0" + version: "1.31.1" test_api: dependency: transitive description: name: test_api - sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" + sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" url: "https://pub.dev" source: hosted - version: "0.7.11" + version: "0.7.12" test_core: dependency: transitive description: name: test_core - sha256: "1991d4cfe85d5043241acac92962c3977c8d2f2add1ee73130c7b286417d1d34" + sha256: d2e98ec12998368dc59ddd47ab709f2cd55acd6b66dc7db764455a44082f4bc5 url: "https://pub.dev" source: hosted - version: "0.6.17" + version: "0.6.18" typed_data: dependency: transitive description: @@ -1377,10 +1377,10 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "92b9910f66ed1057fd4da7b040ae7c74cafacf885bdc81be496928d5049b032d" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.4.3" vm_service: dependency: transitive description: diff --git a/app/supabase/config.toml b/app/supabase/config.toml index a2f5b6b..41866b3 100644 --- a/app/supabase/config.toml +++ b/app/supabase/config.toml @@ -2,7 +2,7 @@ # https://supabase.com/docs/guides/local-development/cli/config # A string used to distinguish different Supabase projects on the same host. Defaults to the # working directory name when running `supabase init`. -project_id = "nosus-monad-experiment" +project_id = "nosus-canary" [api] enabled = true @@ -156,11 +156,11 @@ max_indexes = 5 enabled = true # The base URL of your website. Used as an allow-list for redirects and for constructing URLs used # in emails. -site_url = "https://monad.nosus.foo" +site_url = "https://shubham-sahu.me/nosus-canary/" # The public URL that Auth serves on. Defaults to the API external URL with `/auth/v1` appended. # external_url = "" # A list of *exact* URLs that auth providers are permitted to redirect to post authentication. -additional_redirect_urls = ["https://monad.nosus.foo/**", "http://127.0.0.1:5052/**"] +additional_redirect_urls = ["https://shubham-sahu.me/nosus-canary/**", "http://127.0.0.1:5052/**"] # How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week). jwt_expiry = 3600 # JWT issuer URL. If not set, defaults to auth.external_url. diff --git a/app/supabase/functions/canary/gating.ts b/app/supabase/functions/canary/gating.ts new file mode 100644 index 0000000..24f5b3f --- /dev/null +++ b/app/supabase/functions/canary/gating.ts @@ -0,0 +1,61 @@ +// Which proof chains a canary request writes to. Pure functions only (no env, +// no network) so the rules can be checked with `deno test` offline. +// +// Solana devnet is the product's receipt. Monad testnet is the earlier +// prototype and is on only while CANARY_CONTRACT_ADDRESS is set. + +/** Monad is on only when a contract address is configured (blank = off). */ +export function monadEnabled(contractAddress: string | null | undefined): boolean { + return (contractAddress ?? "").trim() !== ""; +} + +type SealFields = { seal_tx_hash?: string | null; seal_solana_sig?: string | null }; + +/** A note is sealed once either chain holds its seal. */ +export function isSealed(note: SealFields | null | undefined): boolean { + return !!note && (!!note.seal_tx_hash || !!note.seal_solana_sig); +} + +export type SealPlan = { + /** Send sealNote on Monad (in parallel with Solana, Monad authoritative). */ + monad: boolean; + /** Send the seal memo on Solana. */ + solana: boolean; + /** A failed Solana memo must fail the request (Solana is the only receipt). */ + solanaRequired: boolean; +}; + +export function planSeal(p: { + monadOn: boolean; + solanaOn: boolean; + sealTx: string | null; + sealSolana: string | null; +}): SealPlan { + const sealed = isSealed({ seal_tx_hash: p.sealTx, seal_solana_sig: p.sealSolana }); + const solana = p.solanaOn && !p.sealSolana; + return { + monad: p.monadOn && !p.sealTx, + solana, + solanaRequired: solana && !p.monadOn && !sealed, + }; +} + +export type OpenPlan = { + /** Send openCopy on Monad (only for notes sealed there). */ + monad: boolean; + /** Send the open memo on Solana. A failure is stored as null and retried. */ + solana: boolean; +}; + +export function planOpen(p: { + monadOn: boolean; + solanaOn: boolean; + noteSealTx: string | null; + openTx: string | null; + openSolana: string | null; +}): OpenPlan { + return { + monad: p.monadOn && !!p.noteSealTx && !p.openTx, + solana: p.solanaOn && !p.openSolana, + }; +} diff --git a/app/supabase/functions/canary/gating_test.ts b/app/supabase/functions/canary/gating_test.ts new file mode 100644 index 0000000..3ae9be8 --- /dev/null +++ b/app/supabase/functions/canary/gating_test.ts @@ -0,0 +1,83 @@ +// Offline checks for the proof-chain rules. Run from the repo root: +// npx -y deno@2 test app/supabase/functions/canary/gating_test.ts +import { assertEquals } from "jsr:@std/assert@1"; +import { isSealed, monadEnabled, planOpen, planSeal } from "./gating.ts"; + +const TX = "0x" + "a".repeat(64); +const SIG = "5".repeat(88); + +Deno.test("monadEnabled: only a non-blank contract address turns Monad on", () => { + assertEquals(monadEnabled(undefined), false); + assertEquals(monadEnabled(null), false); + assertEquals(monadEnabled(""), false); + assertEquals(monadEnabled(" "), false); + assertEquals(monadEnabled("0x" + "1".repeat(40)), true); +}); + +Deno.test("isSealed: either chain's seal counts", () => { + assertEquals(isSealed(null), false); + assertEquals(isSealed({ seal_tx_hash: null, seal_solana_sig: null }), false); + assertEquals(isSealed({ seal_tx_hash: TX, seal_solana_sig: null }), true); + assertEquals(isSealed({ seal_tx_hash: null, seal_solana_sig: SIG }), true); +}); + +Deno.test("planSeal: Solana only, new note -> Solana required", () => { + assertEquals( + planSeal({ monadOn: false, solanaOn: true, sealTx: null, sealSolana: null }), + { monad: false, solana: true, solanaRequired: true }, + ); +}); + +Deno.test("planSeal: Solana only, already sealed -> nothing to send", () => { + assertEquals( + planSeal({ monadOn: false, solanaOn: true, sealTx: null, sealSolana: SIG }), + { monad: false, solana: false, solanaRequired: false }, + ); + // Sealed on Monad by an older build: fill the memo quietly. + assertEquals( + planSeal({ monadOn: false, solanaOn: true, sealTx: TX, sealSolana: null }), + { monad: false, solana: true, solanaRequired: false }, + ); +}); + +Deno.test("planSeal: both on behaves as before (Monad authoritative)", () => { + assertEquals( + planSeal({ monadOn: true, solanaOn: true, sealTx: null, sealSolana: null }), + { monad: true, solana: true, solanaRequired: false }, + ); + assertEquals( + planSeal({ monadOn: true, solanaOn: true, sealTx: TX, sealSolana: null }), + { monad: false, solana: true, solanaRequired: false }, + ); + assertEquals( + planSeal({ monadOn: true, solanaOn: false, sealTx: null, sealSolana: null }), + { monad: true, solana: false, solanaRequired: false }, + ); +}); + +Deno.test("planOpen: Solana only never touches Monad", () => { + assertEquals( + planOpen({ monadOn: false, solanaOn: true, noteSealTx: TX, openTx: null, openSolana: null }), + { monad: false, solana: true }, + ); + assertEquals( + planOpen({ monadOn: false, solanaOn: true, noteSealTx: null, openTx: null, openSolana: SIG }), + { monad: false, solana: false }, + ); +}); + +Deno.test("planOpen: both on behaves as before", () => { + assertEquals( + planOpen({ monadOn: true, solanaOn: true, noteSealTx: TX, openTx: null, openSolana: null }), + { monad: true, solana: true }, + ); + assertEquals( + planOpen({ monadOn: true, solanaOn: true, noteSealTx: TX, openTx: TX, openSolana: null }), + { monad: false, solana: true }, + ); + // A note sealed only on Solana is never opened on Monad (the contract would revert). + assertEquals( + planOpen({ monadOn: true, solanaOn: true, noteSealTx: null, openTx: null, openSolana: null }), + { monad: false, solana: true }, + ); +}); diff --git a/app/supabase/functions/canary/index.ts b/app/supabase/functions/canary/index.ts index 373ae7f..10bd987 100644 --- a/app/supabase/functions/canary/index.ts +++ b/app/supabase/functions/canary/index.ts @@ -5,24 +5,46 @@ // // { action: "create", note_id, owner_hash, copy_count, copies_hash, // expires_in_hours, copies: [{ index, ciphertext, iv }] } -// -> { seal_tx_hash, expires_at } +// -> { seal_tx_hash, seal_solana_sig, expires_at } // { action: "open", note_id, device_id, reader_name } -// -> { copy_index, copy_count, ciphertext, iv, open_tx_hash, opened_at } +// -> { copy_index, copy_count, ciphertext, iv, open_tx_hash, open_solana_sig, opened_at } // { action: "status", note_id, owner_secret } -// -> { copy_count, seal_tx_hash, expires_at, -// copies: [{ copy_index, reader_name, opened_at, open_tx_hash }] } +// -> { copy_count, seal_tx_hash, seal_solana_sig, expires_at, +// copies: [{ copy_index, reader_name, opened_at, open_tx_hash, open_solana_sig }] } +// +// *_solana_sig is the Solana devnet memo signature. *_tx_hash is the Monad +// testnet transaction hash and stays null whenever Monad is off. // // Errors: { error: "", retry?: true } with a 4xx/5xx status. // // The server never sees note text or keys: copies arrive already encrypted -// and the key stays in the link fragment. Monad receives only +// and the key stays in the link fragment. The chains receive only // sha256-based ids and hashes (never names or text). // +// Proof chains (rules in gating.ts): +// - Solana devnet (solana.ts) is the receipt: one SPL Memo per seal and per +// open. With Monad off a note is sealed only once its Solana memo lands, so +// a failed seal memo fails `create` with retry: true. A failed open memo is +// stored as null and sent again on the next open of that copy. +// - Monad testnet is the earlier prototype, kept behind a switch: on only +// while CANARY_CONTRACT_ADDRESS is set. When on, it runs in parallel with +// Solana exactly as before (Monad authoritative; a Solana failure only +// leaves *_solana_sig null). When off: no viem calls, no relayer leases. +// - A note counts as sealed when seal_tx_hash OR seal_solana_sig is set. +// - With neither chain configured, create and open return 503. +// // Secrets (supabase secrets set ...): -// CANARY_CONTRACT_ADDRESS 0x… NoSusCanary on Monad testnet -// CANARY_RELAYER_KEYS comma-separated 0x… private keys (testnet only) // CANARY_TAG_SALT 64 hex chars, random, never shared -// MONAD_RPC_URL optional, default https://testnet-rpc.monad.xyz +// SOLANA_RELAYER_KEYS comma-separated devnet keypairs (base58 64-byte +// secret key or solana-keygen JSON array). Required +// while Monad is off; unset = Solana proof off and +// responses carry null. +// SOLANA_RPC_URL optional, default https://api.devnet.solana.com +// SOLANA_MEMO_PROGRAM optional, default MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr +// CANARY_CONTRACT_ADDRESS optional; 0x… NoSusCanary on Monad testnet. +// Unset or empty = Monad off. +// CANARY_RELAYER_KEYS Monad only: comma-separated 0x… private keys (testnet) +// MONAD_RPC_URL Monad only, default https://testnet-rpc.monad.xyz // SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY are injected automatically. import { createClient, type SupabaseClient } from "https://esm.sh/@supabase/supabase-js@2.39.8"; @@ -34,6 +56,8 @@ import { type Hex, } from "npm:viem@2.56.5"; import { privateKeyToAccount } from "npm:viem@2.56.5/accounts"; +import { loadSolana, openMemo, sealMemo, sendSolanaMemo, type SolanaConfig } from "./solana.ts"; +import { isSealed, monadEnabled, planOpen, planSeal } from "./gating.ts"; const corsHeaders = { "Access-Control-Allow-Origin": "*", @@ -113,8 +137,11 @@ type Chain = { rpcUrl: string; }; -function loadChain(): Chain { - const contract = requireEnv("CANARY_CONTRACT_ADDRESS").trim(); +// Null when Monad is off (CANARY_CONTRACT_ADDRESS unset or empty). Once an +// address is set, a bad Monad config is a 503 as before. +function loadChainOrNull(): Chain | null { + const contract = (Deno.env.get("CANARY_CONTRACT_ADDRESS") ?? "").trim(); + if (!monadEnabled(contract)) return null; if (!/^0x[0-9a-fA-F]{40}$/.test(contract)) { throw new HttpError(503, "canary is not configured (contract address)"); } @@ -132,6 +159,29 @@ function loadChain(): Chain { }; } +// A bad Solana config is logged and treated as "off". With Monad on, a failed +// memo is logged and stored as null; with Monad off, see handleCreate. +function loadSolanaOrNull(): SolanaConfig | null { + try { + return loadSolana(); + } catch (e) { + console.error("canary: solana is misconfigured", e); + return null; + } +} + +function requireProofChain(chain: Chain | null, solana: SolanaConfig | null) { + if (!chain && !solana) { + throw new HttpError(503, "canary is not configured (no proof chain)"); + } +} + +function solanaSig(result: PromiseSettledResult, label: string): string | null { + if (result.status === "fulfilled") return result.value; + console.error(`${label}: solana memo failed`, result.reason); + return null; +} + // Sends one contract call from a leased relayer key and waits for success. // A key is leased for the whole send+confirm so its nonce is never shared. async function sendCanaryTx( @@ -221,12 +271,14 @@ async function handleCreate(admin: SupabaseClient, body: Record return { note_id: noteId, copy_index: index, ciphertext, iv }; }); - const chain = loadChain(); + const chain = loadChainOrNull(); + const solana = loadSolanaOrNull(); + requireProofChain(chain, solana); const chainNoteId = `0x${await sha256Hex(`nosus-canary:${noteId}`)}`; const { data: existing, error: readError } = await admin .from("canary_notes") - .select("owner_hash, seal_tx_hash, expires_at") + .select("owner_hash, seal_tx_hash, seal_solana_sig, expires_at") .eq("id", noteId) .maybeSingle(); if (readError) throw readError; @@ -234,9 +286,6 @@ async function handleCreate(admin: SupabaseClient, body: Record let expiresAt: string; if (existing) { if (existing.owner_hash !== ownerHash) throw new HttpError(409, "This note id is taken."); - if (existing.seal_tx_hash) { - return json({ seal_tx_hash: existing.seal_tx_hash, expires_at: existing.expires_at }); - } expiresAt = existing.expires_at; } else { expiresAt = new Date(Date.now() + hours * 3600 * 1000).toISOString(); @@ -256,26 +305,59 @@ async function handleCreate(admin: SupabaseClient, body: Record } } - const expiresAtSeconds = BigInt(Math.floor(new Date(expiresAt).getTime() / 1000)); - let sealTx: Hex; - try { - sealTx = await sendCanaryTx(admin, chain, "sealNote", [ - chainNoteId, - copyCount, - copiesHash, - expiresAtSeconds, - ]); - } catch (e) { + const expiresAtSeconds = Math.floor(new Date(expiresAt).getTime() / 1000); + const memo = sealMemo({ note: chainNoteId, copies: copyCount, hash: copiesHash, exp: expiresAtSeconds }); + const sealTxBefore: string | null = existing?.seal_tx_hash ?? null; + let sealSolana: string | null = existing?.seal_solana_sig ?? null; + const plan = planSeal({ + monadOn: chain !== null, + solanaOn: solana !== null, + sealTx: sealTxBefore, + sealSolana, + }); + + if (!chain || !plan.monad) { + // Nothing to send on Monad (Monad is off, or the note is sealed there + // already); at most the Solana memo is missing. + if (solana && plan.solana) { + const [sol] = await Promise.allSettled([sendSolanaMemo(solana, memo)]); + if (sol.status === "rejected" && plan.solanaRequired) { + // Solana is the only receipt: no memo means no seal. The row stays, and + // a retry with the same note id takes the existing-note path. + console.error("canary create: solana seal failed", sol.reason); + throw new HttpError(503, "Could not seal the note on Solana. Try again.", true); + } + sealSolana = solanaSig(sol, existing ? "canary create (retry)" : "canary create"); + if (sealSolana) { + await admin.from("canary_notes").update({ seal_solana_sig: sealSolana }).eq("id", noteId); + } + } + if (!isSealed({ seal_tx_hash: sealTxBefore, seal_solana_sig: sealSolana })) { + // Not reachable while requireProofChain holds; never hand out an unsealed link. + throw new HttpError(503, "Could not seal the note. Try again.", true); + } + return json({ seal_tx_hash: sealTxBefore, seal_solana_sig: sealSolana, expires_at: expiresAt }); + } + + // Monad and Solana in parallel. Monad is authoritative; Solana may fail quietly. + const [monad, sol] = await Promise.allSettled([ + sendCanaryTx(admin, chain, "sealNote", [chainNoteId, copyCount, copiesHash, BigInt(expiresAtSeconds)]), + solana && plan.solana ? sendSolanaMemo(solana, memo) : Promise.resolve(sealSolana), + ]); + sealSolana = solanaSig(sol, "canary create"); + if (monad.status === "rejected") { + const e = monad.reason; if (e instanceof HttpError) throw e; console.error("canary create: seal failed", e); throw new HttpError(503, "Could not seal the note on Monad. Try again.", true); } + const sealTx: Hex = monad.value; const { error: updateError } = await admin .from("canary_notes") - .update({ seal_tx_hash: sealTx }) + .update({ seal_tx_hash: sealTx, seal_solana_sig: sealSolana }) .eq("id", noteId); if (updateError) throw updateError; - return json({ seal_tx_hash: sealTx, expires_at: expiresAt }); + return json({ seal_tx_hash: sealTx, seal_solana_sig: sealSolana, expires_at: expiresAt }); } async function handleOpen(admin: SupabaseClient, body: Record) { @@ -292,15 +374,17 @@ async function handleOpen(admin: SupabaseClient, body: Record) const { data: note, error: noteError } = await admin .from("canary_notes") - .select("copy_count, chain_note_id, seal_tx_hash, expires_at") + .select("copy_count, chain_note_id, seal_tx_hash, seal_solana_sig, expires_at") .eq("id", noteId) .maybeSingle(); if (noteError) throw noteError; - if (!note || !note.seal_tx_hash) throw new HttpError(404, "This Canary link is not valid."); + if (!note || !isSealed(note)) throw new HttpError(404, "This Canary link is not valid."); if (new Date(note.expires_at) <= new Date()) throw new HttpError(410, "This Canary link has expired."); const tagSalt = requireEnv("CANARY_TAG_SALT"); - const chain = loadChain(); + const chain = loadChainOrNull(); + const solana = loadSolanaOrNull(); + requireProofChain(chain, solana); const deviceHash = await sha256Hex(`device:${deviceId}`); let assigned: Record | null = null; @@ -321,12 +405,28 @@ async function handleOpen(admin: SupabaseClient, body: Record) if (assigned === null) throw new HttpError(409, "Every copy of this note has been opened."); const copyIndex = Number(assigned.copy_index); + const readerTag = `0x${await sha256Hex(`${tagSalt}:${noteId}:${copyIndex}:${deviceHash}`)}`; + const memo = openMemo({ note: note.chain_note_id, copy: copyIndex, tag: readerTag }); let openTx = (assigned.open_tx_hash as string | null) ?? null; - if (!openTx) { - const readerTag = `0x${await sha256Hex(`${tagSalt}:${noteId}:${copyIndex}:${deviceHash}`)}`; - try { - openTx = await sendCanaryTx(admin, chain, "openCopy", [note.chain_note_id, copyIndex, readerTag]); - } catch (e) { + let openSolana = (assigned.open_solana_sig as string | null) ?? null; + const plan = planOpen({ + monadOn: chain !== null, + solanaOn: solana !== null, + noteSealTx: note.seal_tx_hash ?? null, + openTx, + openSolana, + }); + if (chain && plan.monad) { + // Monad and Solana in parallel. Monad is authoritative; Solana may fail quietly. + const [monad, sol] = await Promise.allSettled([ + sendCanaryTx(admin, chain, "openCopy", [note.chain_note_id, copyIndex, readerTag]), + solana && plan.solana ? sendSolanaMemo(solana, memo) : Promise.resolve(openSolana), + ]); + openSolana = solanaSig(sol, "canary open"); + if (monad.status === "fulfilled") { + openTx = monad.value; + } else { + const e = monad.reason; if (e instanceof HttpError) throw e; const message = e instanceof Error ? e.message : String(e); if (!message.includes("CopyTaken")) { @@ -338,9 +438,26 @@ async function handleOpen(admin: SupabaseClient, body: Record) } await admin .from("canary_copies") - .update({ reader_tag: readerTag, open_tx_hash: openTx }) + .update({ reader_tag: readerTag, open_tx_hash: openTx, open_solana_sig: openSolana }) .eq("note_id", noteId) .eq("copy_index", copyIndex); + } else if (solana && plan.solana) { + // Nothing to send on Monad (Monad is off, or this copy is recorded there + // already); only the Solana memo is missing. A failure stays null and is + // sent again on the next open of this copy. + const firstOpen = !assigned.reader_tag; + const [sol] = await Promise.allSettled([sendSolanaMemo(solana, memo)]); + openSolana = solanaSig(sol, firstOpen ? "canary open" : "canary open (retry)"); + const patch: Record = {}; + if (firstOpen) patch.reader_tag = readerTag; + if (openSolana) patch.open_solana_sig = openSolana; + if (Object.keys(patch).length > 0) { + await admin + .from("canary_copies") + .update(patch) + .eq("note_id", noteId) + .eq("copy_index", copyIndex); + } } return json({ @@ -349,6 +466,7 @@ async function handleOpen(admin: SupabaseClient, body: Record) ciphertext: assigned.ciphertext, iv: assigned.iv, open_tx_hash: openTx, + open_solana_sig: openSolana, opened_at: assigned.opened_at, }); } @@ -360,7 +478,7 @@ async function handleStatus(admin: SupabaseClient, body: Record const { data: note, error: noteError } = await admin .from("canary_notes") - .select("owner_hash, copy_count, seal_tx_hash, expires_at") + .select("owner_hash, copy_count, seal_tx_hash, seal_solana_sig, expires_at") .eq("id", noteId) .maybeSingle(); if (noteError) throw noteError; @@ -369,7 +487,7 @@ async function handleStatus(admin: SupabaseClient, body: Record const { data: copies, error: copiesError } = await admin .from("canary_copies") - .select("copy_index, reader_name, opened_at, open_tx_hash") + .select("copy_index, reader_name, opened_at, open_tx_hash, open_solana_sig") .eq("note_id", noteId) .not("opened_at", "is", null) .order("copy_index"); @@ -378,6 +496,7 @@ async function handleStatus(admin: SupabaseClient, body: Record return json({ copy_count: note.copy_count, seal_tx_hash: note.seal_tx_hash, + seal_solana_sig: note.seal_solana_sig, expires_at: note.expires_at, copies: copies ?? [], }); diff --git a/app/supabase/functions/canary/solana.ts b/app/supabase/functions/canary/solana.ts new file mode 100644 index 0000000..55db5e6 --- /dev/null +++ b/app/supabase/functions/canary/solana.ts @@ -0,0 +1,64 @@ +// Solana devnet receipts for NO SUS Canary. +// +// Every seal and every open is written as one SPL Memo on Solana devnet. +// The memo carries sha256-based ids and hashes and nothing else: never names, +// note text or keys. While SOLANA_RELAYER_KEYS is unset, loadSolana() returns +// null and nothing here runs (create/open then return 503 unless the legacy +// path in index.ts is configured). +// +// The memo format, key parsing and sending live in packages/receipts-ts (spec: +// docs/RECEIPTS_SPEC.md). This file only reads the env and keeps the names +// index.ts imports. +// +// Env (all optional here): +// SOLANA_RELAYER_KEYS comma-separated devnet keypairs, each either a base58 +// 64-byte secret key or a solana-keygen JSON array +// SOLANA_RPC_URL default https://api.devnet.solana.com +// SOLANA_MEMO_PROGRAM default MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr +// (SPL Memo: Solana Explorer shows the memo text). +// Memo4c2pN8afCj432Lb7RMVKi9PbQnnW7ewFFaV3oAH (p-memo) +// is accepted too. + +import { + DEFAULT_MEMO_PROGRAM, + encodeOpenMemo, + encodeSealMemo, + MEMO_PROGRAM_IDS, + parseRelayerKeys, + type SendConfig, + sendMemo, +} from "../../../../packages/receipts-ts/mod.ts"; + +export type SolanaConfig = SendConfig; + +// Null when Solana is off. Throws on a bad config (the message never includes +// key material) so the caller can log it and carry on without Solana. +export function loadSolana(): SolanaConfig | null { + const raw = (Deno.env.get("SOLANA_RELAYER_KEYS") ?? "").trim(); + if (raw === "") return null; + const keys = parseRelayerKeys(raw); + + const memoProgram = (Deno.env.get("SOLANA_MEMO_PROGRAM") ?? "").trim() || DEFAULT_MEMO_PROGRAM; + if (!MEMO_PROGRAM_IDS.includes(memoProgram)) { + throw new Error("SOLANA_MEMO_PROGRAM is not a known Memo program address"); + } + + return { + rpcUrl: Deno.env.get("SOLANA_RPC_URL") ?? "https://api.devnet.solana.com", + keys, + memoProgram, + }; +} + +// {"p":"nosus-canary","v":1,"t":"seal","note":"0x…","copies":N,"hash":"0x…","exp":E} +// exp is unix seconds, 0 when the note never expires. +export const sealMemo = encodeSealMemo; + +// {"p":"nosus-canary","v":1,"t":"open","note":"0x…","copy":N,"tag":"0x…"} +export const openMemo = encodeOpenMemo; + +// Sends one memo from a random relayer key and waits until it is confirmed. +// Returns the base58 signature. +export function sendSolanaMemo(cfg: SolanaConfig, memo: string): Promise { + return sendMemo(cfg, { memo }); +} diff --git a/app/supabase/functions/canary/solana_test.ts b/app/supabase/functions/canary/solana_test.ts new file mode 100644 index 0000000..f310c6e --- /dev/null +++ b/app/supabase/functions/canary/solana_test.ts @@ -0,0 +1,126 @@ +// Offline checks that solana.ts still writes the exact memos already on +// devnet, and that loadSolana keeps its defaults and messages. Run from the +// repo root (env access: loadSolana reads SOLANA_*, and @solana/kit's `ws` +// dependency reads WS_* at import): +// npx -y deno@2 test --allow-env app/supabase/functions/canary/solana_test.ts +import { assertEquals, assertThrows } from "jsr:@std/assert@1.0.19"; +import { + LEGACY_MEMO_PROGRAM_ADDRESS_V3, + SUPPORTED_MEMO_PROGRAM_ADDRESSES, +} from "npm:@solana-program/memo@0.15.0"; +import { MEMO_PROGRAM_IDS } from "../../../../packages/receipts-ts/mod.ts"; +import { loadSolana, openMemo, sealMemo } from "./solana.ts"; + +const NOTE_A = "0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40"; +const NOTE_B = "0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d"; + +Deno.test("sealMemo writes the exact devnet seal memos", () => { + // 2BHqnuCxYyemfegHkncgTsQyMPjpyB9boD1XqYfD1Wtbcf51Fpy3y264UwGhnvRKtcxFKCaSAzHxLrDwFRk512bQ + assertEquals( + sealMemo({ + note: NOTE_A, + copies: 3, + hash: "0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8", + exp: 1791634855, + }), + '{"p":"nosus-canary","v":1,"t":"seal","note":"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40","copies":3,"hash":"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8","exp":1791634855}', + ); + // 62Frr29RyPXhhUkAaxDLQHDKinMztPhrsYeokzvoiAAUjp9JBXbNUn3S6D4gX7QEqt2yfurqG54PAERb7fLKCskF + assertEquals( + sealMemo({ + note: NOTE_B, + copies: 10, + hash: "0x40846d626dd4beb151497162ca5c1de105281a20d076223b76a44ab1d47962df", + exp: 1791719237, + }), + '{"p":"nosus-canary","v":1,"t":"seal","note":"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d","copies":10,"hash":"0x40846d626dd4beb151497162ca5c1de105281a20d076223b76a44ab1d47962df","exp":1791719237}', + ); +}); + +Deno.test("openMemo writes the exact devnet open memos", () => { + // NwoJauec9otkicaGf8yD6UechYgUnXRdYPqnuc5Kpn6uMYym6XVJcMmWdbVnwnRVncKKVgEyuZB2mR3T5REvdSr + assertEquals( + openMemo({ + note: NOTE_A, + copy: 0, + tag: "0x10947d1df8aaba2c25d2088b054593cfdafd46f959c89007447309960b4845e6", + }), + '{"p":"nosus-canary","v":1,"t":"open","note":"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40","copy":0,"tag":"0x10947d1df8aaba2c25d2088b054593cfdafd46f959c89007447309960b4845e6"}', + ); + // 2b9SS9RhwPvMrsDR5upY5a9w3gk7E2zgV4jmC69QTtZseBMmguXxNdBDqSFTZXW23cgLgAs8L9kFV39LyiU4bnTn + assertEquals( + openMemo({ + note: NOTE_B, + copy: 0, + tag: "0xe52417df0e5f0b104525ec1a583ec0bb64a71c2358a3e93d855b121172a4d10e", + }), + '{"p":"nosus-canary","v":1,"t":"open","note":"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d","copy":0,"tag":"0xe52417df0e5f0b104525ec1a583ec0bb64a71c2358a3e93d855b121172a4d10e"}', + ); + // 4NXs89eDP5hm2GyAkuA5rRDBQUNB5e6ssAChQJRCFGTYimyMDa3LmQRbcEVmaezQSXCx8kgt5GRkpUje59WqH2rc + assertEquals( + openMemo({ + note: NOTE_B, + copy: 1, + tag: "0x6ec7e19683ff70ce1d03ebf3df42242872f98407b47baada27b8cb50d934306e", + }), + '{"p":"nosus-canary","v":1,"t":"open","note":"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d","copy":1,"tag":"0x6ec7e19683ff70ce1d03ebf3df42242872f98407b47baada27b8cb50d934306e"}', + ); +}); + +Deno.test("memo builders keep their validation messages", () => { + assertThrows( + () => sealMemo({ note: "0x12", copies: 2, hash: NOTE_A, exp: 0 }), + Error, + "memo note must be 0x + 64 hex chars", + ); + assertThrows( + () => openMemo({ note: NOTE_A, copy: -1, tag: NOTE_A }), + Error, + "memo copy must be a non-negative integer", + ); +}); + +Deno.test("the library accepts the same memo programs as @solana-program/memo", () => { + assertEquals(MEMO_PROGRAM_IDS, [...SUPPORTED_MEMO_PROGRAM_ADDRESSES]); +}); + +const ENV = ["SOLANA_RELAYER_KEYS", "SOLANA_RPC_URL", "SOLANA_MEMO_PROGRAM"]; + +function withEnv(env: Record, fn: () => void) { + const saved = ENV.map((k) => [k, Deno.env.get(k)] as const); + try { + for (const k of ENV) Deno.env.delete(k); + for (const [k, v] of Object.entries(env)) Deno.env.set(k, v); + fn(); + } finally { + for (const [k, v] of saved) v === undefined ? Deno.env.delete(k) : Deno.env.set(k, v); + } +} + +// Test bytes 1..64 only; not a funded key. +const KEY = JSON.stringify(Array.from({ length: 64 }, (_, i) => i + 1)); + +Deno.test("loadSolana: defaults, overrides and messages are unchanged", () => { + withEnv({}, () => assertEquals(loadSolana(), null)); + withEnv({ SOLANA_RELAYER_KEYS: " " }, () => assertEquals(loadSolana(), null)); + withEnv({ SOLANA_RELAYER_KEYS: KEY }, () => { + const cfg = loadSolana()!; + assertEquals(cfg.rpcUrl, "https://api.devnet.solana.com"); + assertEquals(cfg.memoProgram, LEGACY_MEMO_PROGRAM_ADDRESS_V3); + assertEquals(cfg.keys.length, 1); + }); + withEnv({ + SOLANA_RELAYER_KEYS: `${KEY},${KEY}`, + SOLANA_RPC_URL: "http://localhost:8899", + SOLANA_MEMO_PROGRAM: " Memo4c2pN8afCj432Lb7RMVKi9PbQnnW7ewFFaV3oAH ", + }, () => { + const cfg = loadSolana()!; + assertEquals(cfg.rpcUrl, "http://localhost:8899"); + assertEquals(cfg.memoProgram, "Memo4c2pN8afCj432Lb7RMVKi9PbQnnW7ewFFaV3oAH"); + assertEquals(cfg.keys.length, 2); + }); + withEnv({ SOLANA_RELAYER_KEYS: KEY, SOLANA_MEMO_PROGRAM: "11111111111111111111111111111111" }, () => + assertThrows(loadSolana, Error, "SOLANA_MEMO_PROGRAM is not a known Memo program address")); + withEnv({ SOLANA_RELAYER_KEYS: "[1,2,3]" }, () => + assertThrows(loadSolana, Error, "SOLANA_RELAYER_KEYS: a key must be 64 bytes")); +}); diff --git a/app/supabase/migrations/20261010090000_nosus_canary_solana.sql b/app/supabase/migrations/20261010090000_nosus_canary_solana.sql new file mode 100644 index 0000000..ff0fd82 --- /dev/null +++ b/app/supabase/migrations/20261010090000_nosus_canary_solana.sql @@ -0,0 +1,80 @@ +-- NO SUS Canary: Solana devnet proof. Experiment project ffidvfguojalzpclipzi ONLY. +-- Never apply to production (rxfnazmusofikwaggntb). +-- +-- Adds the Solana memo signature next to each Monad transaction hash. Like the +-- Monad hashes these are public identifiers of sha256-based ids; the server +-- still never stores note text, keys, salts or codewords. +-- +-- Apply before deploying the `canary` edge function that selects these columns. +-- +-- Reverse (manual, if ever needed): +-- drop function if exists public.canary_assign_copy(uuid, text, text); +-- alter table public.canary_copies drop column if exists open_solana_sig; +-- alter table public.canary_notes drop column if exists seal_solana_sig; +-- -- then re-create canary_assign_copy and its grants from 20260919090000_nosus_canary.sql + +alter table public.canary_notes + add column if not exists seal_solana_sig text + check (seal_solana_sig is null or seal_solana_sig ~ '^[1-9A-HJ-NP-Za-km-z]{64,100}$'); + +alter table public.canary_copies + add column if not exists open_solana_sig text + check (open_solana_sig is null or open_solana_sig ~ '^[1-9A-HJ-NP-Za-km-z]{64,100}$'); + +-- Same function as before plus open_solana_sig in the result. Postgres cannot +-- change a function's result columns with "or replace", so drop it first; the +-- grants are dropped with it and re-applied below. +drop function if exists public.canary_assign_copy(uuid, text, text); + +-- Give a device its copy: the same copy again if it already has one, +-- otherwise the lowest unassigned copy. Concurrency-safe (SKIP LOCKED + the +-- one-per-device unique index). Returns no row when every copy is taken. +create or replace function public.canary_assign_copy( + p_note_id uuid, + p_device_hash text, + p_reader_name text +) +returns table ( + copy_index integer, + ciphertext text, + iv text, + reader_tag text, + opened_at timestamptz, + open_tx_hash text, + open_solana_sig text +) +language plpgsql +security definer +set search_path = public +as $$ +#variable_conflict use_column +begin + return query + select c.copy_index, c.ciphertext, c.iv, c.reader_tag, c.opened_at, c.open_tx_hash, c.open_solana_sig + from public.canary_copies c + where c.note_id = p_note_id + and c.reader_device_hash = p_device_hash; + if found then + return; + end if; + + return query + update public.canary_copies c + set reader_device_hash = p_device_hash, + reader_name = p_reader_name, + opened_at = now() + where (c.note_id, c.copy_index) = ( + select c2.note_id, c2.copy_index + from public.canary_copies c2 + where c2.note_id = p_note_id + and c2.reader_device_hash is null + order by c2.copy_index + limit 1 + for update skip locked + ) + returning c.copy_index, c.ciphertext, c.iv, c.reader_tag, c.opened_at, c.open_tx_hash, c.open_solana_sig; +end; +$$; + +revoke all on function public.canary_assign_copy(uuid, text, text) from public, anon, authenticated; +grant execute on function public.canary_assign_copy(uuid, text, text) to service_role; diff --git a/app/test/db_test.dart b/app/test/db_test.dart deleted file mode 100644 index 281ce63..0000000 --- a/app/test/db_test.dart +++ /dev/null @@ -1,100 +0,0 @@ -// ignore_for_file: avoid_print -import 'dart:io'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:supabase_flutter/supabase_flutter.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:no_sus/config/supabase_credentials.dart'; - -class EmptyLocalStorage extends LocalStorage { - const EmptyLocalStorage(); - @override - Future initialize() async {} - @override - Future accessToken() async => null; - @override - Future hasAccessToken() async => false; - @override - Future persistSession(String session) async {} - @override - Future removePersistedSession() async {} -} - -void main() { - test('diagnose database', () async { - try { - TestWidgetsFlutterBinding.ensureInitialized(); - HttpOverrides.global = null; - SharedPreferences.setMockInitialValues({}); - await Supabase.initialize( - url: SupabaseCredentials.url, - publishableKey: SupabaseCredentials.anonKey, - authOptions: const FlutterAuthClientOptions( - localStorage: EmptyLocalStorage(), - ), - ); - - final client = Supabase.instance.client; - print('Supabase initialized.'); - - try { - final groups = await client.from('study_groups').select('*'); - print('--- STUDY GROUPS (${groups.length}) ---'); - for (var g in groups) { - print('Group: $g'); - } - } catch (e) { - print('Error fetching study_groups: $e'); - } - - try { - final members = await client.from('study_group_members').select('*'); - print('--- STUDY GROUP MEMBERS (${members.length}) ---'); - } catch (e) { - print('Error fetching study_group_members: $e'); - } - - try { - final profiles = await client.from('profiles').select('*'); - print('--- PROFILES (${profiles.length}) ---'); - for (var p in profiles) { - print('Profile: $p'); - } - } catch (e) { - print('Error fetching profiles: $e'); - } - - try { - final files = await client.from('secure_files').select('*'); - print('--- SECURE FILES (${files.length}) ---'); - for (var f in files) { - print('File: $f'); - } - } catch (e) { - print('Error fetching secure_files: $e'); - } - - final tablesToCheck = [ - 'profiles', - 'study_groups', - 'study_group_members', - 'secure_files', - 'audit_logs', - 'focus_logs', - 'user_notes' - ]; - - for (final table in tablesToCheck) { - try { - await client.from(table).select('*').limit(1); - print('Table "$table" EXISTS.'); - } catch (e) { - print('Table "$table" DOES NOT EXIST or query failed: $e'); - } - } - - } catch (e, s) { - print('Error: $e'); - print(s); - } - }); -} diff --git a/app/test/unit/canary_link_test.dart b/app/test/unit/canary_link_test.dart index 6abcc31..a16e62f 100644 --- a/app/test/unit/canary_link_test.dart +++ b/app/test/unit/canary_link_test.dart @@ -66,4 +66,31 @@ void main() { '0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e', ); }); + + test('explorer links point at the right testnet per chain', () { + final monadHash = '0x${'ab' * 32}'; + // Base58 Solana signatures are 86–88 chars; this one is 88. + final solanaSig = '5' * 88; + + expect( + canaryExplorerTxUrl(monadHash), + 'https://testnet.monadscan.com/tx/$monadHash', + ); + expect( + canarySolanaExplorerTxUrl(solanaSig), + 'https://explorer.solana.com/tx/$solanaSig?cluster=devnet', + ); + expect(CanaryChain.monad.txUrl(monadHash), canaryExplorerTxUrl(monadHash)); + expect( + CanaryChain.solana.txUrl(solanaSig), + canarySolanaExplorerTxUrl(solanaSig), + ); + }); + + test('chain labels read correctly in chips and sentences', () { + expect(CanaryChain.monad.label, 'Monad'); + expect(CanaryChain.solana.label, 'Solana'); + expect(CanaryChain.monad.network, 'Monad testnet'); + expect(CanaryChain.solana.network, 'Solana devnet'); + }); } diff --git a/app/test/unit/canary_models_test.dart b/app/test/unit/canary_models_test.dart new file mode 100644 index 0000000..fc74d38 --- /dev/null +++ b/app/test/unit/canary_models_test.dart @@ -0,0 +1,151 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:no_sus/features/canary/domain/canary_fingerprint.dart'; +import 'package:no_sus/features/canary/domain/canary_models.dart'; + +const _noteId = '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'; +final _monadHash = '0x${'ab' * 32}'; +final _solanaSig = '5' * 88; + +CanaryOwnerRecord _record({String? sealTxHash, String? sealSolanaSig}) => + CanaryOwnerRecord( + noteId: _noteId, + keyHex: 'cd' * 32, + ownerSecret: 'ef' * 32, + saltHex: '01' * 32, + copyCount: 2, + createdAt: DateTime.utc(2026, 10, 10, 12), + expiresAt: DateTime.utc(2026, 10, 11, 12), + readerLink: 'https://x.y/#/canary/$_noteId?k=${'cd' * 32}', + preview: 'The quick brown fox jumps over the lazy dog.', + plan: buildCanaryPlan( + 'The quick brown fox jumps over the lazy dog. ' + 'It was a very big and really nice day for a walk.', + ), + codewords: const [ + [0, 1, 0], + [1, 0, 1], + ], + sealTxHash: sealTxHash, + sealSolanaSig: sealSolanaSig, + ); + +void main() { + test('owner record round-trips with both proofs', () { + final original = _record( + sealTxHash: _monadHash, + sealSolanaSig: _solanaSig, + ); + final json = original.toJson(); + expect(json['v'], 1); + expect(json['sealTxHash'], _monadHash); + expect(json['sealSolanaSig'], _solanaSig); + + final restored = CanaryOwnerRecord.fromJson(json); + expect(restored.noteId, original.noteId); + expect(restored.sealTxHash, _monadHash); + expect(restored.sealSolanaSig, _solanaSig); + expect(restored.codewords, original.codewords); + expect(restored.isSealed, isTrue); + }); + + test('owner record round-trips without a Solana proof', () { + final original = _record(sealTxHash: _monadHash); + final json = original.toJson(); + expect(json.containsKey('sealSolanaSig'), isTrue); + expect(json['sealSolanaSig'], isNull); + + final restored = CanaryOwnerRecord.fromJson(json); + expect(restored.sealTxHash, _monadHash); + expect(restored.sealSolanaSig, isNull); + // A Monad seal alone still counts, so records from the Monad build + // keep working. + expect(restored.isSealed, isTrue); + }); + + test('records saved before Solana proofs load with a null signature', () { + final legacy = _record(sealTxHash: _monadHash).toJson() + ..remove('sealSolanaSig'); + expect(legacy.containsKey('sealSolanaSig'), isFalse); + + final restored = CanaryOwnerRecord.fromJson(legacy); + expect(restored.sealTxHash, _monadHash); + expect(restored.sealSolanaSig, isNull); + expect(restored.isSealed, isTrue); + }); + + test('copyWith adds the Solana proof without dropping the Monad one', () { + final draft = _record(); + expect(draft.isSealed, isFalse); + + final sealed = draft.copyWith( + sealTxHash: _monadHash, + sealSolanaSig: _solanaSig, + ); + expect(sealed.sealTxHash, _monadHash); + expect(sealed.sealSolanaSig, _solanaSig); + + final untouched = sealed.copyWith(expiresAt: DateTime.utc(2027)); + expect(untouched.sealTxHash, _monadHash); + expect(untouched.sealSolanaSig, _solanaSig); + }); + + test('note status settles on Monad alone', () { + final future = DateTime.now().add(const Duration(days: 1)); + final status = CanaryNoteStatus( + copyCount: 1, + sealTxHash: _monadHash, + sealSolanaSig: null, + expiresAt: future, + copies: [ + CanaryCopyStatus( + copyIndex: 0, + readerName: 'Sam', + openedAt: DateTime.now(), + openTxHash: _monadHash, + openSolanaSig: null, + ), + ], + ); + expect(status.isSettled, isTrue); + expect(status.copy(0)?.openSolanaSig, isNull); + }); + + test('a Solana-only seal counts as sealed (Monad off)', () { + final record = _record(sealSolanaSig: _solanaSig); + expect(record.sealTxHash, isNull); + expect(record.isSealed, isTrue); + + final restored = CanaryOwnerRecord.fromJson(record.toJson()); + expect(restored.sealTxHash, isNull); + expect(restored.sealSolanaSig, _solanaSig); + expect(restored.isSealed, isTrue); + }); + + CanaryCopyStatus copy({String? tx, String? sig}) => CanaryCopyStatus( + copyIndex: 0, + readerName: 'Sam', + openedAt: DateTime.now(), + openTxHash: tx, + openSolanaSig: sig, + ); + + CanaryNoteStatus status(CanaryCopyStatus c) => CanaryNoteStatus( + copyCount: 1, + sealTxHash: null, + sealSolanaSig: _solanaSig, + expiresAt: DateTime.now().add(const Duration(days: 1)), + copies: [c], + ); + + test('a copy is recorded by either chain', () { + expect(copy().isRecorded, isFalse); + expect(copy(tx: _monadHash).isRecorded, isTrue); + expect(copy(sig: _solanaSig).isRecorded, isTrue); + }); + + test('note status settles on Solana alone (Monad off)', () { + expect(status(copy(sig: _solanaSig)).isSettled, isTrue); + // The open memo has not landed yet: keep polling. + expect(status(copy()).isSettled, isFalse); + }); +} diff --git a/app/test/unit/monad_receipt_test.dart b/app/test/unit/monad_receipt_test.dart deleted file mode 100644 index 65ac9e3..0000000 --- a/app/test/unit/monad_receipt_test.dart +++ /dev/null @@ -1,122 +0,0 @@ -import 'dart:convert'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:http/http.dart' as http; -import 'package:http/testing.dart'; -import 'package:no_sus/features/monad/domain/monad_receipt.dart'; -import 'package:no_sus/features/monad/data/monad_rpc_repository.dart'; - -void main() { - final id = '0x${'ab' * 32}'; - final sender = '0x${'11' * 20}'; - final recipient = '0x${'22' * 20}'; - final contract = '0x${'33' * 20}'; - String abi({bool opened = false}) => - '0x${[sender.substring(2).padLeft(64, '0'), recipient.substring(2).padLeft(64, '0'), (opened ? recipient.substring(2) : '0').padLeft(64, '0'), 'cd' * 32, 100.toRadixString(16).padLeft(64, '0'), (opened ? 150 : 0).toRadixString(16).padLeft(64, '0'), 200.toRadixString(16).padLeft(64, '0')].join()}'; - - test('only accepts receipt IDs and experiment receipt links', () { - expect(parseMonadDropId(' $id '), id); - expect(parseMonadDropId('https://monad.nosus.foo/#/monad/$id'), id); - for (final input in [ - 'https://app.nosus.foo/#/monad/$id', - 'https://monad.nosus.foo/#/burn/$id?k=secret', - '$id?k=secret', - 'https://monad.nosus.foo/#/monad/$id?k=secret', - '0x123', - 'https://evil.example/#/monad/$id', - ]) { - expect(parseMonadDropId(input), isNull); - } - }); - test('receipt keeps acknowledgement evidence after exact expiry', () { - final receipt = MonadReceipt.fromAbi(id, abi(opened: true)); - expect(receipt.sender, sender); - expect(receipt.opener, recipient); - expect( - receipt.status(DateTime.fromMillisecondsSinceEpoch(199999)), - 'Acknowledged', - ); - expect( - receipt.status(DateTime.fromMillisecondsSinceEpoch(200000)), - 'Acknowledged · access expired', - ); - }); - test('rejects malformed or nonexistent receipts', () { - for (final value in [ - '0x', - '0x${'0' * 448}', - '${abi()}00', - abi().replaceFirst('0000', 'ffff'), - ]) { - expect(() => MonadReceipt.fromAbi(id, value), throwsFormatException); - } - }); - test('RPC verifies testnet and bytecode before reading receipt', () async { - final methods = []; - final client = MockClient((request) async { - final call = jsonDecode(request.body) as Map; - methods.add(call['method'] as String); - final result = switch (call['method']) { - 'eth_chainId' => '0x279f', - 'eth_getCode' => '0x6000', - 'eth_call' => abi(opened: true), - _ => throw StateError('Unexpected RPC call'), - }; - if (call['method'] == 'eth_call') { - expect(call['params'][0], { - 'to': contract, - 'data': '0x72a41fdd${id.substring(2)}', - }); - } - return http.Response( - jsonEncode({'jsonrpc': '2.0', 'id': 1, 'result': result}), - 200, - ); - }); - final repository = MonadRpcRepository( - client: client, - contractAddress: contract, - ); - addTearDown(repository.dispose); - expect((await repository.receiptOf(id)).acknowledged, isTrue); - expect(methods, ['eth_chainId', 'eth_getCode', 'eth_call']); - }); - test('wrong chain, missing bytecode and RPC errors fail closed', () async { - for (final mode in ['wrong-chain', 'no-code', 'error']) { - final client = MockClient((request) async { - final method = jsonDecode(request.body)['method']; - return http.Response( - jsonEncode( - mode == 'error' - ? { - 'id': 1, - 'error': {'message': 'revert'}, - } - : { - 'id': 1, - 'result': method == 'eth_chainId' - ? (mode == 'wrong-chain' ? '0x8f' : '0x279f') - : '0x', - }, - ), - 200, - ); - }); - final repository = MonadRpcRepository( - client: client, - contractAddress: contract, - ); - addTearDown(repository.dispose); - await expectLater(repository.receiptOf(id), throwsStateError); - } - }); - test('unconfigured contract makes no network calls', () async { - final repository = MonadRpcRepository( - client: MockClient( - (_) async => throw StateError('Unexpected network call'), - ), - ); - addTearDown(repository.dispose); - expect(repository.isConfigured, isFalse); - await expectLater(repository.receiptOf(id), throwsStateError); - }); -} diff --git a/app/test/widget/canary_app_test.dart b/app/test/widget/canary_app_test.dart index e45bb7d..f8f1591 100644 --- a/app/test/widget/canary_app_test.dart +++ b/app/test/widget/canary_app_test.dart @@ -2,8 +2,10 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:no_sus/config/app_mode.dart'; import 'package:no_sus/core/providers/theme_provider.dart'; import 'package:no_sus/features/canary/presentation/canary_app.dart'; +import 'package:no_sus/features/canary/presentation/ui/wallet_button.dart'; import 'package:shared_preferences/shared_preferences.dart'; /// Widget tests draw text in a placeholder font whose glyphs are full @@ -56,6 +58,19 @@ void main() { expect(find.text('Every reader gets their own copy.'), findsOneWidget); expect(find.byType(BackButton), findsNothing); + // CANARY_MONAD decides whether any Monad UI exists at all. + final monadText = find.textContaining( + RegExp(r'[Mm]onad|MONAD|\bMON\b'), + ); + if (kCanaryMonad) { + expect(find.byType(WalletButton), findsOneWidget); + expect(monadText, findsWidgets); + } else { + expect(find.byType(WalletButton), findsNothing); + expect(monadText, findsNothing); + expect(find.textContaining('SOLANA'), findsWidgets); + } + await tester.pumpWidget(const SizedBox()); }); } diff --git a/app/test/widget/monad_screen_test.dart b/app/test/widget/monad_screen_test.dart deleted file mode 100644 index 94f2cf9..0000000 --- a/app/test/widget/monad_screen_test.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:no_sus/features/monad/presentation/monad_screen.dart'; -import 'package:no_sus/features/monad/presentation/monad_providers.dart'; - -void main() { - testWidgets('Monad remains visibly unavailable without threshold evidence', ( - tester, - ) async { - tester.view.physicalSize = const Size(390, 1500); - tester.view.devicePixelRatio = 1; - addTearDown(tester.view.reset); - await tester.pumpWidget( - const ProviderScope(child: MaterialApp(home: MonadScreen())), - ); - expect(monadThresholdVerified, isFalse); - expect( - find.text('Encrypted Monad sharing is not available yet'), - findsOneWidget, - ); - final send = tester.widget( - find.widgetWithText(FilledButton, 'Send with a Monad receipt'), - ); - expect(send.onPressed, isNull); - expect(tester.takeException(), isNull); - }); -} diff --git a/app/test/widget/proof_chips_test.dart b/app/test/widget/proof_chips_test.dart new file mode 100644 index 0000000..e833165 --- /dev/null +++ b/app/test/widget/proof_chips_test.dart @@ -0,0 +1,232 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:no_sus/config/app_mode.dart'; +import 'package:no_sus/features/canary/presentation/ui/chain_chip.dart'; +import 'package:no_sus/features/canary/presentation/ui/proof_chips.dart'; +import 'package:no_sus/theme.dart'; + +/// Widget tests draw text in a placeholder font whose glyphs are full +/// squares, which makes the pixel-font labels measure about twice their real +/// width. Load the real bundled fonts so layout checks match the browser. +Future _loadFonts() async { + const families = { + 'Outfit': ['Outfit-Regular', 'Outfit-SemiBold', 'Outfit-Bold'], + 'Inter': ['Inter-Regular', 'Inter-Medium', 'Inter-SemiBold', 'Inter-Bold'], + 'VT323': ['VT323-Regular'], + }; + for (final entry in families.entries) { + final loader = FontLoader(entry.key); + for (final file in entry.value) { + loader.addFont(rootBundle.load('assets/google_fonts/$file.ttf')); + } + await loader.load(); + } +} + +const _monadTx = + '0x9f2c4b1e7d3a5c6b8e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d'; +const _solanaSig = + '5VfYmGZ8s3kQxq2wE1rT9yU4iO6pA7sD8fG0hJ1kL2zX3cV4bN5mQm2p'; + +Widget _host(Widget child, {double? width}) => MaterialApp( + theme: CanaryTokens.theme(), + home: Scaffold( + body: Center( + child: width == null ? child : SizedBox(width: width, child: child), + ), + ), +); + +void main() { + setUpAll(_loadFonts); + + testWidgets('Monad only shows one linked chip and nothing for Solana', ( + tester, + ) async { + await tester.pumpWidget( + _host( + const ProofChips( + monadTxHash: _monadTx, + labelPrefix: 'Sealed on', + showMonad: true, + ), + ), + ); + + expect(find.byType(ChainChip), findsOneWidget); + expect(find.text('Sealed on Monad · 0x9f2c…1c2d'), findsOneWidget); + expect(find.textContaining('Solana'), findsNothing); + expect(find.byType(PendingChainChip), findsNothing); + expect( + find.bySemanticsLabel(RegExp(r'View proof on Monad testnet')), + findsOneWidget, + ); + }); + + testWidgets('Monad + Solana shows both chips with bounded hashes', ( + tester, + ) async { + await tester.pumpWidget( + _host( + const ProofChips( + monadTxHash: _monadTx, + solanaSig: _solanaSig, + labelPrefix: 'Recorded on', + showMonad: true, + ), + ), + ); + + expect(find.byType(ChainChip), findsNWidgets(2)); + expect(find.text('Recorded on Monad · 0x9f2c…1c2d'), findsOneWidget); + // Base58 signature: no 0x prefix, first 4 + last 4. + expect(find.text('Recorded on Solana · 5VfY…Qm2p'), findsOneWidget); + expect( + find.bySemanticsLabel(RegExp(r'View proof on Solana devnet')), + findsOneWidget, + ); + }); + + testWidgets('pending Solana shows a progress ring and no link', ( + tester, + ) async { + await tester.pumpWidget( + _host( + const ProofChips( + monadTxHash: _monadTx, + solanaPending: true, + showMonad: true, + ), + ), + ); + // One frame only: the progress ring animates forever. + await tester.pump(); + + expect(find.byType(ChainChip), findsOneWidget); + expect(find.byType(PendingChainChip), findsOneWidget); + expect(find.byType(CircularProgressIndicator), findsOneWidget); + expect(find.text('Solana…'), findsOneWidget); + expect( + find.bySemanticsLabel(RegExp(r'Recording on Solana devnet')), + findsOneWidget, + ); + expect(find.bySemanticsLabel(RegExp(r'View proof on Solana')), findsNothing); + expect(find.byType(InkWell), findsOneWidget); // only the Monad chip taps + }); + + testWidgets('Solana off (null, not pending) renders nothing for Solana', ( + tester, + ) async { + await tester.pumpWidget( + _host(const ProofChips(monadTxHash: _monadTx, showMonad: true)), + ); + + expect(find.byType(ChainChip), findsOneWidget); + expect(find.byType(PendingChainChip), findsNothing); + expect(find.textContaining('Solana'), findsNothing); + }); + + testWidgets('two chips wrap onto a second row at 320 px without overflow', ( + tester, + ) async { + await tester.pumpWidget( + _host( + const ProofChips( + monadTxHash: _monadTx, + solanaSig: _solanaSig, + labelPrefix: 'Recorded on', + showMonad: true, + ), + width: 320, + ), + ); + + expect(tester.takeException(), isNull); + final chips = find.byType(ChainChip); + expect(chips, findsNWidgets(2)); + final first = tester.getRect(chips.at(0)); + final second = tester.getRect(chips.at(1)); + expect(second.top, greaterThanOrEqualTo(first.bottom)); + expect(first.height, greaterThanOrEqualTo(48)); + expect(second.height, greaterThanOrEqualTo(48)); + expect(first.right, lessThanOrEqualTo(tester.getRect(find.byType(ProofChips)).right)); + }); + + group('Monad hidden (CANARY_MONAD off)', () { + testWidgets('only the Solana chip shows, even when a Monad hash exists', ( + tester, + ) async { + await tester.pumpWidget( + _host( + const ProofChips( + monadTxHash: _monadTx, + solanaSig: _solanaSig, + monadPending: true, + labelPrefix: 'Sealed on', + showMonad: false, + ), + ), + ); + + expect(find.byType(ChainChip), findsOneWidget); + expect(find.text('Sealed on Solana · 5VfY…Qm2p'), findsOneWidget); + expect(find.byType(PendingChainChip), findsNothing); + expect(find.textContaining('Monad'), findsNothing); + expect(find.bySemanticsLabel(RegExp('Monad')), findsNothing); + }); + + testWidgets('a Solana-only proof renders on its own', (tester) async { + await tester.pumpWidget( + _host(const ProofChips(solanaSig: _solanaSig, showMonad: false)), + ); + + expect(find.byType(ChainChip), findsOneWidget); + expect(find.text('Solana · 5VfY…Qm2p'), findsOneWidget); + expect( + find.bySemanticsLabel(RegExp(r'View proof on Solana devnet')), + findsOneWidget, + ); + }); + + testWidgets('pending Solana alone shows only the progress chip', ( + tester, + ) async { + await tester.pumpWidget( + _host( + const ProofChips( + monadPending: true, + solanaPending: true, + showMonad: false, + ), + ), + ); + await tester.pump(); + + expect(find.byType(ChainChip), findsNothing); + expect(find.byType(PendingChainChip), findsOneWidget); + expect(find.text('Solana…'), findsOneWidget); + expect(find.textContaining('Monad'), findsNothing); + }); + + testWidgets('nothing to show renders an empty box', (tester) async { + await tester.pumpWidget( + _host(const ProofChips(monadTxHash: _monadTx, showMonad: false)), + ); + + expect(find.byType(ChainChip), findsNothing); + expect(find.byType(PendingChainChip), findsNothing); + }); + }); + + testWidgets('showMonad defaults to the CANARY_MONAD build flag', ( + tester, + ) async { + await tester.pumpWidget(_host(const ProofChips(monadTxHash: _monadTx))); + + expect( + find.byType(ChainChip), + kCanaryMonad ? findsOneWidget : findsNothing, + ); + }); +} diff --git a/app/tool/canary_fingerprint_harness.dart b/app/tool/canary_fingerprint_harness.dart index 0c95ee1..0ddf472 100644 --- a/app/tool/canary_fingerprint_harness.dart +++ b/app/tool/canary_fingerprint_harness.dart @@ -3,6 +3,7 @@ // It must end with "FAILURES: 0". Its printed report is its output. // ignore_for_file: avoid_print +import 'dart:io'; import 'dart:math'; import 'package:no_sus/features/canary/domain/canary_fingerprint.dart'; @@ -192,4 +193,5 @@ void main() { runFor('LONG NOTE', longNote, 100); print(''); print('FAILURES: $failures'); + if (failures > 0) exitCode = 1; } diff --git a/app/web/account-deletion.html b/app/web/account-deletion.html index 7f1899e..a0eb700 100644 --- a/app/web/account-deletion.html +++ b/app/web/account-deletion.html @@ -30,7 +30,7 @@

Delete in the app (immediate)

This permanently deletes your profile, group memberships, uploaded files and their storage objects, your avatar, and your authentication record. Groups where you were the only admin are removed or ownership is transferred. This cannot be undone.

Request deletion by email

-

If you can't access the app, email shubhamsahu9372580326@gmail.com from the address on your account with the subject "NO SUS account deletion request". Deletion is completed within 30 days.

+

If you can't access the app, email shubhamsahu@nosus.foo from the address on your account with the subject "NO SUS account deletion request". Deletion is completed within 30 days.

What is retained

Tamper-evident group audit entries reference actor IDs; after deletion these no longer resolve to any identity. Feedback you submitted is kept in anonymized form (the link to your account is severed). App usage events (see the privacy policy) are kept with your account ID removed, so they are no longer linked to your account.

diff --git a/app/web/privacy.html b/app/web/privacy.html index af540c0..951ba70 100644 --- a/app/web/privacy.html +++ b/app/web/privacy.html @@ -51,7 +51,7 @@

5. Data deletion

You can delete your account at any time from Profile → Danger Zone → Delete User Account. This permanently removes your profile, group memberships, uploaded files, and auth record. App usage events are not deleted: your account ID is removed from them, detaching them from your account, and the rest of each event is kept. See account deletion for details.

6. Contact

-

Questions or requests: shubhamsahu9372580326@gmail.com

+

Questions or requests: shubhamsahu@nosus.foo

7. Terms of Service

Please also review our Terms of Service, which govern your use of NO SUS.

diff --git a/app/web/terms.html b/app/web/terms.html index 823283d..b0c7db5 100644 --- a/app/web/terms.html +++ b/app/web/terms.html @@ -64,6 +64,6 @@

11. Entire Agreement

These terms, together with our Privacy Policy, constitute the entire agreement between you and NO SUS regarding the use of the service and supersede all prior agreements.

12. Contact

-

Questions or disputes regarding these terms: shubhamsahu9372580326@gmail.com

+

Questions or disputes regarding these terms: shubhamsahu@nosus.foo

diff --git a/assets/readme/banner.svg b/assets/readme/banner.svg index f439c6b..44256c4 100644 --- a/assets/readme/banner.svg +++ b/assets/readme/banner.svg @@ -15,5 +15,5 @@ - + diff --git a/assets/readme/battle.svg b/assets/readme/battle.svg deleted file mode 100644 index 36a0715..0000000 --- a/assets/readme/battle.svg +++ /dev/null @@ -1,58 +0,0 @@ - -Battle text: A wild LEAK appeared! Canary used FINGERPRINT! It's super effective! It was Priya's copy, number 03. - - - - - - - - - - - - - - - diff --git a/assets/readme/btn-judge.svg b/assets/readme/btn-judge.svg deleted file mode 100644 index 57640b3..0000000 --- a/assets/readme/btn-judge.svg +++ /dev/null @@ -1,11 +0,0 @@ - -Judge checklist - - - - - - diff --git a/assets/readme/btn-play.svg b/assets/readme/btn-play.svg deleted file mode 100644 index e4592cc..0000000 --- a/assets/readme/btn-play.svg +++ /dev/null @@ -1,12 +0,0 @@ - -Play live - - - - - - diff --git a/assets/readme/game-over.svg b/assets/readme/game-over.svg deleted file mode 100644 index f91b6da..0000000 --- a/assets/readme/game-over.svg +++ /dev/null @@ -1,11 +0,0 @@ - -Game over? Play again at the live app. - - - - - diff --git a/assets/readme/say-hello.svg b/assets/readme/say-hello.svg deleted file mode 100644 index 60a9435..0000000 --- a/assets/readme/say-hello.svg +++ /dev/null @@ -1,30 +0,0 @@ - -Prof. Canary: Share one link. Every reader gets a secretly different copy. If it leaks, I tell you whose copy it was. - - - - - - - - - diff --git a/assets/readme/story.svg b/assets/readme/story.svg deleted file mode 100644 index 6e49b87..0000000 --- a/assets/readme/story.svg +++ /dev/null @@ -1,60 +0,0 @@ - -Animation: the sender seals a note on Monad, five readers each receive a different copy, Priya's copy leaks, NO SUS scans it and the canary sings: copy 03 is Priya's. - - - - - - - - - - diff --git a/assets/social-preview.png b/assets/social-preview.png new file mode 100644 index 0000000..14e72fa Binary files /dev/null and b/assets/social-preview.png differ diff --git a/contracts/AGENTS.md b/contracts/AGENTS.md deleted file mode 100644 index e2a3525..0000000 --- a/contracts/AGENTS.md +++ /dev/null @@ -1,7 +0,0 @@ -# Contract scope - -Read `README.md` and the root `AGENTS.md` before editing. Preserve a one-open-only record, named -recipient enforcement, and expiry enforcement. Add a test for any contract behavior change. - -No payable flows, owner controls, key commitments, salts, plaintext, filenames, or public key-proof -functions belong here. A wallet acknowledgement is not proof that a human read content. diff --git a/contracts/README.md b/contracts/README.md deleted file mode 100644 index 82aae27..0000000 --- a/contracts/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Smart contracts - -`NoSusMonadDrops` is a deliberately small Monad-testnet receipt contract. It stores only encrypted -ciphertext digests, public wallet addresses, expiry, and acknowledgement state. - -## Public contract - -- `seal(id, ciphertextDigest, recipient, expiresAt)` creates a drop. -- `acknowledgeOpen(id)` records the one eligible opening wallet. -- `canDecrypt(id, account)` is the threshold-custody policy predicate. -- `receiptOf(id)` returns public receipt state. - -The contract does not accept payments, keys, salts, plaintext, filenames, or key proofs. - -## Commands - -```sh -npm install -npm run test -npm run compile -``` - -Set `MONAD_RPC_URL` and `DEPLOYER_PRIVATE_KEY` only in a local ignored `.env`. A testnet deploy also -requires an explicit named-target approval and `CONFIRM_MONAD_DEPLOY=1`. The script refuses to -broadcast without that flag. diff --git a/contracts/contracts/NoSusCanary.sol b/contracts/contracts/NoSusCanary.sol deleted file mode 100644 index 6d93c79..0000000 --- a/contracts/contracts/NoSusCanary.sol +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -/// @title NoSusCanary -/// @notice Public, append-only log for NO SUS Canary notes. -/// The chain never receives note text, keys, reader names, fingerprints or -/// codewords. It stores only: -/// * per note: one hash that commits to every copy, the copy count, expiry; -/// * per opened copy: a salted reader tag and the time it was opened. -/// Only allow-listed NO SUS relayers can write, so nobody can fill a note's -/// copies with junk. The owner (deployer) manages the relayer list. -contract NoSusCanary { - struct Note { - uint64 sealedAt; - uint64 expiresAt; - uint16 copyCount; - uint16 openedCount; - bytes32 copiesHash; - } - - struct Copy { - bytes32 readerTag; - uint64 openedAt; - } - - address public immutable owner; - mapping(address => bool) public isRelayer; - mapping(bytes32 => Note) private notes; - mapping(bytes32 => mapping(uint16 => Copy)) private copies; - - event RelayerSet(address indexed relayer, bool allowed); - event NoteSealed(bytes32 indexed noteId, uint16 copyCount, bytes32 copiesHash, uint64 expiresAt); - event CopyOpened(bytes32 indexed noteId, uint16 indexed copyIndex, bytes32 readerTag, uint64 openedAt); - - error NotOwner(); - error NotRelayer(); - error NoteExists(); - error NoteMissing(); - error InvalidNote(); - error InvalidCopy(); - error CopyTaken(); - error NoteExpired(); - - modifier onlyRelayer() { - if (!isRelayer[msg.sender]) revert NotRelayer(); - _; - } - - constructor() { - owner = msg.sender; - isRelayer[msg.sender] = true; - emit RelayerSet(msg.sender, true); - } - - function setRelayer(address relayer, bool allowed) external { - if (msg.sender != owner) revert NotOwner(); - isRelayer[relayer] = allowed; - emit RelayerSet(relayer, allowed); - } - - /// Commits to every copy of a note before any reader can open one. - function sealNote(bytes32 noteId, uint16 copyCount, bytes32 copiesHash, uint64 expiresAt) - external - onlyRelayer - { - if (notes[noteId].sealedAt != 0) revert NoteExists(); - if ( - noteId == bytes32(0) || copyCount == 0 || copiesHash == bytes32(0) - || (expiresAt != 0 && expiresAt <= block.timestamp) - ) revert InvalidNote(); - - notes[noteId] = Note({ - sealedAt: uint64(block.timestamp), - expiresAt: expiresAt, - copyCount: copyCount, - openedCount: 0, - copiesHash: copiesHash - }); - emit NoteSealed(noteId, copyCount, copiesHash, expiresAt); - } - - /// Records, once, which (salted, anonymous) reader received a copy. - function openCopy(bytes32 noteId, uint16 copyIndex, bytes32 readerTag) external onlyRelayer { - Note storage note = notes[noteId]; - if (note.sealedAt == 0) revert NoteMissing(); - if (note.expiresAt != 0 && block.timestamp >= note.expiresAt) revert NoteExpired(); - if (copyIndex >= note.copyCount || readerTag == bytes32(0)) revert InvalidCopy(); - - Copy storage entry = copies[noteId][copyIndex]; - if (entry.openedAt != 0) revert CopyTaken(); - entry.readerTag = readerTag; - entry.openedAt = uint64(block.timestamp); - note.openedCount += 1; - emit CopyOpened(noteId, copyIndex, readerTag, uint64(block.timestamp)); - } - - function noteOf(bytes32 noteId) external view returns (Note memory) { - Note memory note = notes[noteId]; - if (note.sealedAt == 0) revert NoteMissing(); - return note; - } - - /// Returns zero values for a copy nobody has opened yet. - function copyOf(bytes32 noteId, uint16 copyIndex) external view returns (Copy memory) { - return copies[noteId][copyIndex]; - } -} diff --git a/contracts/contracts/NoSusMonadDrops.sol b/contracts/contracts/NoSusMonadDrops.sol deleted file mode 100644 index dafd05d..0000000 --- a/contracts/contracts/NoSusMonadDrops.sol +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -/// @title NoSusMonadDrops -/// @notice A Monad-testnet receipt for an encrypted drop. The contract never receives content, -/// encryption keys, salts, filenames, or private storage locations. -contract NoSusMonadDrops { - struct Drop { - address sender; - address recipient; - address opener; - bytes32 ciphertextDigest; - uint64 sealedAt; - uint64 openedAt; - uint64 expiresAt; - } - - mapping(bytes32 id => Drop) private drops; - - error DropAlreadyExists(); - error DropDoesNotExist(); - error DropAlreadyOpened(); - error DropExpired(); - error InvalidCiphertextDigest(); - error InvalidExpiry(); - error RecipientOnly(); - - event Sealed( - bytes32 indexed id, - address indexed sender, - address indexed recipient, - bytes32 ciphertextDigest, - uint64 expiresAt - ); - event OpenAcknowledged( - bytes32 indexed id, - address indexed opener, - uint64 openedAt - ); - - function seal( - bytes32 id, - bytes32 ciphertextDigest, - address recipient, - uint64 expiresAt - ) external { - if (drops[id].sender != address(0)) revert DropAlreadyExists(); - if (ciphertextDigest == bytes32(0)) revert InvalidCiphertextDigest(); - if (expiresAt != 0 && expiresAt <= block.timestamp) revert InvalidExpiry(); - - uint64 sealedAt = uint64(block.timestamp); - drops[id] = Drop({ - sender: msg.sender, - recipient: recipient, - opener: address(0), - ciphertextDigest: ciphertextDigest, - sealedAt: sealedAt, - openedAt: 0, - expiresAt: expiresAt - }); - - emit Sealed(id, msg.sender, recipient, ciphertextDigest, expiresAt); - } - - function acknowledgeOpen(bytes32 id) external { - Drop storage drop = drops[id]; - if (drop.sender == address(0)) revert DropDoesNotExist(); - if (drop.opener != address(0)) revert DropAlreadyOpened(); - if (drop.expiresAt != 0 && block.timestamp >= drop.expiresAt) revert DropExpired(); - if (drop.recipient != address(0) && drop.recipient != msg.sender) { - revert RecipientOnly(); - } - - uint64 openedAt = uint64(block.timestamp); - drop.opener = msg.sender; - drop.openedAt = openedAt; - - emit OpenAcknowledged(id, msg.sender, openedAt); - } - - function canDecrypt(bytes32 id, address account) external view returns (bool) { - Drop memory drop = drops[id]; - if (account == address(0) || drop.sender == address(0) || drop.opener != account) return false; - if (drop.expiresAt != 0 && block.timestamp >= drop.expiresAt) return false; - return true; - } - - function receiptOf(bytes32 id) external view returns (Drop memory) { - Drop memory drop = drops[id]; - if (drop.sender == address(0)) revert DropDoesNotExist(); - return drop; - } -} diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts deleted file mode 100644 index fcdb8cf..0000000 --- a/contracts/hardhat.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { HardhatUserConfig } from "hardhat/config"; -import hardhatToolboxViem from "@nomicfoundation/hardhat-toolbox-viem"; - -const monadRpcUrl = process.env.MONAD_RPC_URL ?? "https://testnet-rpc.monad.xyz"; -const deployerPrivateKey = process.env.DEPLOYER_PRIVATE_KEY; - -const config: HardhatUserConfig = { - plugins: [hardhatToolboxViem], - solidity: { - version: "0.8.24", - }, - networks: { - monadTestnet: { - type: "http", - chainType: "generic", - url: monadRpcUrl, - chainId: 10143, - accounts: deployerPrivateKey ? [deployerPrivateKey] : [], - }, - }, -}; - -export default config; diff --git a/contracts/package-lock.json b/contracts/package-lock.json deleted file mode 100644 index 1e7bd58..0000000 --- a/contracts/package-lock.json +++ /dev/null @@ -1,3278 +0,0 @@ -{ - "name": "@nosus-monad/contracts", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@nosus-monad/contracts", - "version": "0.1.0", - "devDependencies": { - "@nomicfoundation/hardhat-toolbox-viem": "5.0.7", - "@types/node": "24.10.1", - "hardhat": "3.16.0", - "typescript": "7.0.2" - } - }, - "node_modules/@actions/core": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.1.tgz", - "integrity": "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@actions/exec": "^3.0.0", - "@actions/http-client": "^4.0.0" - } - }, - "node_modules/@actions/exec": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz", - "integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@actions/io": "^3.0.2" - } - }, - "node_modules/@actions/http-client": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.1.tgz", - "integrity": "sha512-+Nvd1ImaOZBSoPbsUtEhv+1z99H12xzncCkz0a3RuehINE81FZSe2QTj3uvAPTcJX/SCzUQHQ0D1GrPMbrPitg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "tunnel": "^0.0.6", - "undici": "^6.23.0" - } - }, - "node_modules/@actions/io": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz", - "integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@adraffy/ens-normalize": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", - "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@cto.af/wtf8": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@cto.af/wtf8/-/wtf8-0.0.5.tgz", - "integrity": "sha512-LfUFi+Vv4eDzj+XAtR89e3wwjXA/NZjUSwU5NhwbBrLecxPaBYFy3exCuc1j+D4UZeOVdqlsl8G7LmOt18V0tg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=20" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", - "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", - "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", - "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", - "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", - "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", - "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", - "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", - "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", - "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", - "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", - "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", - "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", - "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", - "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", - "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", - "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", - "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", - "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", - "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", - "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", - "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", - "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", - "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", - "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", - "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", - "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@ethersproject/abi": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", - "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", - "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", - "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0" - } - }, - "node_modules/@ethersproject/address": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", - "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/rlp": "^5.8.0" - } - }, - "node_modules/@ethersproject/base64": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", - "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", - "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@ethersproject/bytes": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", - "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", - "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/bignumber": "^5.8.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", - "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/base64": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", - "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", - "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true - }, - "node_modules/@ethersproject/networks": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", - "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", - "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", - "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", - "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "bn.js": "^5.2.1", - "elliptic": "6.6.1", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", - "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", - "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/base64": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@jest/diff-sequences": { - "version": "30.5.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.5.0.tgz", - "integrity": "sha512-OsqBjHXCn8cadasoAZBP6nWYvMsRhpMzGXTpxJ5aO04NlbdhIz+FVe3q49l0AwVhsz/cEmIpBes6gAFl1/dWQg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/get-type": { - "version": "30.5.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.5.0.tgz", - "integrity": "sha512-9/2VUPitAjmBzbvDvqrxmvB7BzWsBW0WmkkojX1ODuxX1NLGxx9gfaZpHB0z8DtJ9uhGNmZG/VXBhf8uO0OV8Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/react-is-18": { - "name": "react-is", - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@jest/react-is-19": { - "name": "react-is", - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.3.0.tgz", - "integrity": "sha512-UpMYezM4v5/18F28aC66AEsjXIgE02kyEMH6yLdgLXu/UTfa1Ntwck/nNLrbqJsEXW7gPb0coNO9FQse9WTovA==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@jest/schemas": { - "version": "30.5.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", - "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@noble/ciphers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.2.1.tgz", - "integrity": "sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/curves": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", - "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.4.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/hashes": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", - "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@nomicfoundation/edr": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.19.0.tgz", - "integrity": "sha512-wzuyAylm4XWIahFjy1pFDQfHny4Xsx73T98d8KJAkGG/Rpgp0M36rqS4lzjbGQ1tXDrWEBG0WRr0v1jrQhQ0xg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 22" - }, - "optionalDependencies": { - "@nomicfoundation/edr-darwin-arm64": "0.19.0", - "@nomicfoundation/edr-darwin-x64": "0.19.0", - "@nomicfoundation/edr-linux-arm64-gnu": "0.19.0", - "@nomicfoundation/edr-linux-arm64-musl": "0.19.0", - "@nomicfoundation/edr-linux-x64-gnu": "0.19.0", - "@nomicfoundation/edr-linux-x64-musl": "0.19.0", - "@nomicfoundation/edr-win32-x64-msvc": "0.19.0" - } - }, - "node_modules/@nomicfoundation/edr-darwin-arm64": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.19.0.tgz", - "integrity": "sha512-Yo2MkZoM85zkasUPJDj8l8QezPdrMzqQUJhp78TUQDq8FQXhdJTZ39k3Jax5OQ3hqjMhMkrGbctn9w9h6mEusg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 22" - } - }, - "node_modules/@nomicfoundation/edr-darwin-x64": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.19.0.tgz", - "integrity": "sha512-RC7RVX1iATg9SlJTnKD57A8jRBIBiUKmAdi8maBN4zhmK5Z7aAeiwdQX6VjPOum3c2Mdpp2Q7JfooJxxF6bCvw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 22" - } - }, - "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.19.0.tgz", - "integrity": "sha512-vhEKPUomGwM0Lsjpwd5q/Jc6yE2hpspJBCRYFkCghzCmwgZHtoYn/2nd1nOLsTt7jqMlvAKJSaLCrhz1HCTCTA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 22" - } - }, - "node_modules/@nomicfoundation/edr-linux-arm64-musl": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.19.0.tgz", - "integrity": "sha512-mlkpVUolkSpMIriZyiJeTbgx/m4Ngm9lQtah2BG92H+dgtwMIMze6Q6OQfZG6oi6wMrhDgu8WEyAy3XgIwlcRg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 22" - } - }, - "node_modules/@nomicfoundation/edr-linux-x64-gnu": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.19.0.tgz", - "integrity": "sha512-d0Z+WVbX5mm6s9ozc5TXrCRjQykdN81tGI+eaM4hQcD/S5VSY9rwKuCXyLJ/GkgeI5S8HEHsyVdXEsDJznPyhA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 22" - } - }, - "node_modules/@nomicfoundation/edr-linux-x64-musl": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.19.0.tgz", - "integrity": "sha512-UIrlNqYj9lbUXpBy++WwHeC0xZqyFw9TXy06/8+0PLffI7Si4kiTKfXqdITGQhP6Vf/JuJ8y+jos8oy6bL8jFQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 22" - } - }, - "node_modules/@nomicfoundation/edr-win32-x64-msvc": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.19.0.tgz", - "integrity": "sha512-pIyEJBiS8l09Yndz+aE/JmkD39FCqtyiRO+wlx6tX426o4290acRfJ0r7GwTBmqqZD5G4pLOOB0uLIMRyDrY+g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 22" - } - }, - "node_modules/@nomicfoundation/hardhat-errors": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-errors/-/hardhat-errors-3.0.21.tgz", - "integrity": "sha512-jXgqgxmI1D7vYcWRQnb6HsRDssxE87a4xJ48FQAdkZUPclB0aVISx6IoVG1Kttx2jJ7tNuo9GasJxpOv7stqyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nomicfoundation/hardhat-utils": "^4.1.5" - } - }, - "node_modules/@nomicfoundation/hardhat-ignition": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-3.1.8.tgz", - "integrity": "sha512-zVsR1SA1gqjd3SF3C+BljttSEMOaIbSIEvHgFhXF/A1IgeecJYD/MqGcvGAW4s51r5ZGQnUSl9t/5VQKvuExlw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@nomicfoundation/hardhat-errors": "^3.0.16", - "@nomicfoundation/hardhat-utils": "^4.1.4", - "@nomicfoundation/ignition-core": "^3.1.8", - "@nomicfoundation/ignition-ui": "^3.1.2", - "json5": "^2.2.3", - "prompts": "^2.4.2" - }, - "peerDependencies": { - "@nomicfoundation/hardhat-verify": "^3.0.0", - "hardhat": "^3.8.0" - } - }, - "node_modules/@nomicfoundation/hardhat-ignition-viem": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-viem/-/hardhat-ignition-viem-3.1.6.tgz", - "integrity": "sha512-ggjHftjDNLQPnHBMEtDcTafYJfTzqTMlorKlAWj0HunzwiDhC5p7ox2MuEGmZHqt2oVjrnPF5E+Dp3G0RlYRgg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@nomicfoundation/hardhat-errors": "^3.0.15" - }, - "peerDependencies": { - "@nomicfoundation/hardhat-ignition": "^3.1.2", - "@nomicfoundation/hardhat-verify": "^3.0.0", - "@nomicfoundation/hardhat-viem": "^3.0.4", - "@nomicfoundation/ignition-core": "^3.0.7", - "hardhat": "^3.8.0", - "viem": "^2.47.6" - } - }, - "node_modules/@nomicfoundation/hardhat-keystore": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-keystore/-/hardhat-keystore-3.0.13.tgz", - "integrity": "sha512-e4RdtlGBSHhgwv66tEyayrF/G5a2DVT70Jv3AGocUCpDtnxSfNDQez4Pmr7fmjNUhn0TSK6mOwtJ+Yjr1IEwrg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@noble/ciphers": "1.2.1", - "@noble/hashes": "1.7.1", - "@nomicfoundation/hardhat-errors": "^3.0.15", - "@nomicfoundation/hardhat-utils": "^4.1.3", - "@nomicfoundation/hardhat-zod-utils": "^3.0.5", - "zod": "^3.23.8" - }, - "peerDependencies": { - "hardhat": "^3.13.0" - } - }, - "node_modules/@nomicfoundation/hardhat-network-helpers": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-3.0.11.tgz", - "integrity": "sha512-3/xuORejAOGbfqBmIen+OCHu9ExK9O8pjE11ILU9NcN37zy3GDbyNCKV9keK1gSjWWVb0okAlAR/yvewfEE4TA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@nomicfoundation/hardhat-errors": "^3.0.16", - "@nomicfoundation/hardhat-utils": "^4.1.4" - }, - "peerDependencies": { - "hardhat": "^3.8.0" - } - }, - "node_modules/@nomicfoundation/hardhat-node-test-reporter": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-node-test-reporter/-/hardhat-node-test-reporter-3.1.1.tgz", - "integrity": "sha512-dGWMfDYM2gg7leFA2w3RMKW3TzIXJm0+8VLOLxCbROQ9bJTzI76nwrPNmVNAeH49Q2cU3WCdgw7YXAp7lcoYRA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@actions/core": "^3.0.1", - "jest-diff": "^30.4.1" - } - }, - "node_modules/@nomicfoundation/hardhat-node-test-runner": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-node-test-runner/-/hardhat-node-test-runner-3.1.0.tgz", - "integrity": "sha512-afuTNxslf1H6tkXApf1r4Is12dyxsew1AscutGvQG+maPTDuk/BuTQ2a9idXBULZA3/6TGfbEEQvki5FxaONWQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@nomicfoundation/hardhat-errors": "^3.0.15", - "@nomicfoundation/hardhat-node-test-reporter": "^3.1.0", - "@nomicfoundation/hardhat-utils": "^4.1.2", - "@nomicfoundation/hardhat-zod-utils": "^3.0.5", - "tsx": "^4.23.1", - "zod": "^3.23.8" - }, - "peerDependencies": { - "hardhat": "^3.12.0" - } - }, - "node_modules/@nomicfoundation/hardhat-toolbox-viem": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox-viem/-/hardhat-toolbox-viem-5.0.7.tgz", - "integrity": "sha512-aHF77tTYmBIbuxY99KKBPx4cLWdcQvvar1PpzWJyrDgC+P6rA7Edi1GpvvPcwO/HdfZXuACQ74zSS2PnmJu3mA==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@nomicfoundation/hardhat-ignition": "^3.0.7", - "@nomicfoundation/hardhat-ignition-viem": "^3.0.7", - "@nomicfoundation/hardhat-keystore": "^3.0.0", - "@nomicfoundation/hardhat-network-helpers": "^3.0.0", - "@nomicfoundation/hardhat-node-test-runner": "^3.0.0", - "@nomicfoundation/hardhat-verify": "^3.0.0", - "@nomicfoundation/hardhat-viem": "^3.0.4", - "@nomicfoundation/hardhat-viem-assertions": "^3.0.5", - "@nomicfoundation/ignition-core": "^3.0.7", - "hardhat": "^3.8.0", - "viem": "^2.47.6" - } - }, - "node_modules/@nomicfoundation/hardhat-utils": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-utils/-/hardhat-utils-4.1.9.tgz", - "integrity": "sha512-vUyHQ2H1VfknTUxO3Vat7z0y9WkDUF69pLrrLZN2K1/+TKJN+TVzEMeXW/2GXJzIhm2uc2qZXOYwQUh+SU9PbQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@streamparser/json-node": "^0.0.22", - "env-paths": "^4.0.0", - "ethereum-cryptography": "^2.2.1", - "fast-equals": "^6.0.0", - "json-stream-stringify": "^3.1.7", - "rfdc": "^1.3.1", - "undici": "^6.28.0" - } - }, - "node_modules/@nomicfoundation/hardhat-vendored": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-vendored/-/hardhat-vendored-3.0.4.tgz", - "integrity": "sha512-RO8Otj1FvRvxJmXzkxh1vTwK/+cqSVPYLqY6RrWkmzHEEcxnAwAFsBYdW7xyTEyW/pVbSSNd2gs3aoGdGZaoNA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@nomicfoundation/hardhat-verify": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-3.1.0.tgz", - "integrity": "sha512-qGaaUr7deSSGnpZP7nZg7jQyaft0QPUzfbGhdO46BygAR9lUHHLppuuWnUpdqwV3d1IMSo8pFSEpVlt/ZtyQvQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/abi": "^5.8.0", - "@nomicfoundation/hardhat-errors": "^3.0.16", - "@nomicfoundation/hardhat-utils": "^4.1.4", - "@nomicfoundation/hardhat-zod-utils": "^3.0.5", - "cbor2": "^2.0.0", - "zod": "^3.23.8" - }, - "peerDependencies": { - "hardhat": "^3.12.0" - } - }, - "node_modules/@nomicfoundation/hardhat-viem": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-viem/-/hardhat-viem-3.0.9.tgz", - "integrity": "sha512-GtQ7l55C70Jj80yrZGdW7Kah0vPmEje29G/xVfcxchVxRRFdj1XyFZFn+7e53b11qhHMWDB787pVN+I8YZae3w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@nomicfoundation/hardhat-errors": "^3.0.15", - "@nomicfoundation/hardhat-utils": "^4.1.2" - }, - "peerDependencies": { - "hardhat": "^3.8.0", - "viem": "^2.47.6" - } - }, - "node_modules/@nomicfoundation/hardhat-viem-assertions": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-viem-assertions/-/hardhat-viem-assertions-3.1.2.tgz", - "integrity": "sha512-vMdyBnvgAD/2uZVzDwWc4ynGekxEQx/1LJ3gIXmsJtAPWENolfBXs3fHCxnA48he7lldyEsymZaNya8MZBLYwA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@nomicfoundation/hardhat-errors": "^3.0.16", - "@nomicfoundation/hardhat-utils": "^4.1.4" - }, - "peerDependencies": { - "@nomicfoundation/hardhat-viem": "^3.0.4", - "hardhat": "^3.8.0", - "viem": "^2.47.6" - } - }, - "node_modules/@nomicfoundation/hardhat-zod-utils": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-zod-utils/-/hardhat-zod-utils-3.0.6.tgz", - "integrity": "sha512-DraBttTle+tRi24wkEfTYUrsX/Cdp74ySXcc4MUzMQPBQNUTFx5YyTH7qFhXQdz3V171iqLAQpOAhNcEqwmq9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nomicfoundation/hardhat-errors": "^3.0.13", - "@nomicfoundation/hardhat-utils": "^4.1.2" - }, - "peerDependencies": { - "zod": "^3.23.8" - } - }, - "node_modules/@nomicfoundation/ignition-core": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-3.1.9.tgz", - "integrity": "sha512-HpAUqg3wh1FnpQMfLc/K10UJFTcyABLcPiZmNk5Rc5Znx1FzMOLPUvyMO/Vl3Ta21u8INQJ2VhmJeCiXpRzgRw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@ethersproject/address": "5.8.0", - "@nomicfoundation/hardhat-errors": "^3.0.16", - "@nomicfoundation/hardhat-utils": "^4.1.4", - "@nomicfoundation/solidity-analyzer": "^0.1.1", - "cbor2": "^2.0.0", - "ethers": "^6.14.0", - "immer": "11.1.15", - "lodash-es": "4.18.1", - "ndjson": "2.0.0" - } - }, - "node_modules/@nomicfoundation/ignition-ui": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-3.1.2.tgz", - "integrity": "sha512-OoS5eQi9WBeiYI6EXurhqrpr6syRVhnaUzdx5fyK/1syKGq9BsjWWHXTNru0qk5ZFQ9f/KMTZotcDZD4eAdCpg==", - "dev": true, - "peer": true - }, - "node_modules/@nomicfoundation/solidity-analyzer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", - "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - }, - "optionalDependencies": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz", - "integrity": "sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz", - "integrity": "sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz", - "integrity": "sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz", - "integrity": "sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz", - "integrity": "sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz", - "integrity": "sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz", - "integrity": "sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@scure/base": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", - "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", - "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.4.0", - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", - "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@sentry/core": { - "version": "9.47.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.47.1.tgz", - "integrity": "sha512-KX62+qIt4xgy8eHKHiikfhz2p5fOciXd0Cl+dNzhgPFq8klq4MGMNaf148GB3M/vBqP4nw/eFvRMAayFCgdRQw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.34.52", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", - "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@streamparser/json": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.22.tgz", - "integrity": "sha512-b6gTSBjJ8G8SuO3Gbbj+zXbVx8NSs1EbpbMKpzGLWMdkR+98McH9bEjSz3+0mPJf68c5nxa3CrJHp5EQNXM6zQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@streamparser/json-node": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@streamparser/json-node/-/json-node-0.0.22.tgz", - "integrity": "sha512-sJT2ptNRwqB1lIsQrQlCoWk5rF4tif9wDh+7yluAGijJamAhrHGYpFB/Zg3hJeceoZypi74ftXk8DHzwYpbZSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@streamparser/json": "^0.0.22" - } - }, - "node_modules/@types/node": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", - "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@typescript/typescript-aix-ppc64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", - "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-darwin-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", - "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-darwin-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", - "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-freebsd-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", - "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-freebsd-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", - "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-arm": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", - "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", - "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-loong64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", - "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-mips64el": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", - "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-ppc64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", - "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-riscv64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", - "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-s390x": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", - "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", - "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-netbsd-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", - "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-netbsd-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", - "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-openbsd-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", - "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-openbsd-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", - "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-sunos-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", - "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-win32-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", - "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-win32-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", - "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/abitype": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz", - "integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3.22.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/adm-zip": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.6.1.tgz", - "integrity": "sha512-Xwrja8nx9e5o2N1my4DsKCeKpdrnACyr1wtbPxBDgGzKzKyE9kRtBFA8mWldI+RVlD7CBZNWY/wQ2+ydwOR6kQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0" - } - }, - "node_modules/aes-js": { - "version": "4.0.0-beta.5", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", - "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/bn.js": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.5.tgz", - "integrity": "sha512-Vq886eXykuP5E6HcKSSStP3bJgrE6In5WKxVUvJ8XGpWWYs2xZHWqUwzCtGgEtBcxyd57KBFDPFoUfNzdaHCNg==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/cbor2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cbor2/-/cbor2-2.3.0.tgz", - "integrity": "sha512-76WB3hq8BoaGkMkBVJ27fW5LJU+qqDLEpgRNCG/SYKhODWXpVPOTD4UcUto3IEzYLA52nsvbhb0wabhHDn3qXg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@cto.af/wtf8": "0.0.5" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/elliptic": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", - "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", - "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/env-paths": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-4.0.0.tgz", - "integrity": "sha512-pxP8eL2SwwaTRi/KHYwLYXinDs7gL3jxFcBYmEdYfZmZXbaVDvdppd0XBU8qVz03rDfKZMXg1omHCbsJjZrMsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-safe-filename": "^0.1.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/esbuild": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", - "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.2", - "@esbuild/android-arm": "0.28.2", - "@esbuild/android-arm64": "0.28.2", - "@esbuild/android-x64": "0.28.2", - "@esbuild/darwin-arm64": "0.28.2", - "@esbuild/darwin-x64": "0.28.2", - "@esbuild/freebsd-arm64": "0.28.2", - "@esbuild/freebsd-x64": "0.28.2", - "@esbuild/linux-arm": "0.28.2", - "@esbuild/linux-arm64": "0.28.2", - "@esbuild/linux-ia32": "0.28.2", - "@esbuild/linux-loong64": "0.28.2", - "@esbuild/linux-mips64el": "0.28.2", - "@esbuild/linux-ppc64": "0.28.2", - "@esbuild/linux-riscv64": "0.28.2", - "@esbuild/linux-s390x": "0.28.2", - "@esbuild/linux-x64": "0.28.2", - "@esbuild/netbsd-arm64": "0.28.2", - "@esbuild/netbsd-x64": "0.28.2", - "@esbuild/openbsd-arm64": "0.28.2", - "@esbuild/openbsd-x64": "0.28.2", - "@esbuild/openharmony-arm64": "0.28.2", - "@esbuild/sunos-x64": "0.28.2", - "@esbuild/win32-arm64": "0.28.2", - "@esbuild/win32-ia32": "0.28.2", - "@esbuild/win32-x64": "0.28.2" - } - }, - "node_modules/ethereum-cryptography": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", - "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/curves": "1.4.2", - "@noble/hashes": "1.4.0", - "@scure/bip32": "1.4.0", - "@scure/bip39": "1.3.0" - } - }, - "node_modules/ethereum-cryptography/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ethers": { - "version": "6.17.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.17.0.tgz", - "integrity": "sha512-BpyrpIPJ3ydEVow8zGaz1DuPS7YU8DcWxuBnY9a0UA/lvAPwrMr+EPXsfrul628SRaekPNeIM4UFh/91GWZang==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/ethers-io/" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@adraffy/ens-normalize": "1.11.1", - "@noble/curves": "1.2.0", - "@noble/hashes": "1.3.2", - "@types/node": "22.7.5", - "aes-js": "4.0.0-beta.5", - "tslib": "2.7.0", - "ws": "8.21.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/ethers/node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@noble/hashes": "1.3.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ethers/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ethers/node_modules/@types/node": { - "version": "22.7.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", - "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/ethers/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/fast-equals": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-6.0.3.tgz", - "integrity": "sha512-IECu4C0fFZFoUC2cA2rDaNUuVIfWIZMwh3tY+ng924vOuD9OaUFFrcIrVwCKbV7TJDkGmrHfhwZ7R0AnHfVhyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/hardhat": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-3.16.0.tgz", - "integrity": "sha512-LWFFR3rYl8AIhwpYVjK2L5y0Z0CqdQFQ8AZWe8gqf1t7KGH+E/EguoIX7rcB4KfyKoWK6ooj+7Jgba4vlQ1feQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nomicfoundation/edr": "0.19.0", - "@nomicfoundation/hardhat-errors": "^3.0.17", - "@nomicfoundation/hardhat-utils": "^4.1.6", - "@nomicfoundation/hardhat-vendored": "^3.0.4", - "@nomicfoundation/hardhat-zod-utils": "^3.0.5", - "@nomicfoundation/solidity-analyzer": "^0.1.1", - "@sentry/core": "^9.4.0", - "adm-zip": "^0.6.0", - "chokidar": "^5.0.0", - "enquirer": "^2.3.0", - "ethereum-cryptography": "^2.2.1", - "micro-eth-signer": "^0.14.0", - "p-map": "^7.0.6", - "resolve.exports": "^2.0.3", - "semver": "^7.8.5", - "tsx": "^4.23.1", - "ws": "^8.21.1", - "zod": "^3.23.8" - }, - "bin": { - "hardhat": "dist/src/cli.js" - } - }, - "node_modules/hardhat/node_modules/ws": { - "version": "8.21.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", - "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/immer": { - "version": "11.1.15", - "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.15.tgz", - "integrity": "sha512-VrNANlmnWQnh5COXIIOQXM9oOJw7naGKlBT74ZOOR6lpVXc3gFEu9FJLDFcpCJ2j+NWr8TIwtWD//T6ZX6TKiQ==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/is-safe-filename": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-safe-filename/-/is-safe-filename-0.1.1.tgz", - "integrity": "sha512-4SrR7AdnY11LHfDKTZY1u6Ga3RuxZdl3YKWWShO5iyuG5h8QS4GD2tOb04peBJ5I7pXbR+CGBNEhTcwK+FzN3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isows": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", - "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "peer": true, - "peerDependencies": { - "ws": "*" - } - }, - "node_modules/jest-diff": { - "version": "30.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.5.1.tgz", - "integrity": "sha512-e3cNNMpv8Kh20MjjphTXs+3Vz7DQyLM1nft7KJhnh46atFhjVJRa+0Hq0beywuwsACtMQUBihQkFl8zxb7gt1Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/diff-sequences": "30.5.0", - "@jest/get-type": "30.5.0", - "chalk": "^4.1.2", - "pretty-format": "30.5.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/json-stream-stringify": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/json-stream-stringify/-/json-stream-stringify-3.1.7.tgz", - "integrity": "sha512-F4MWetLtY42YMaAKw5cV4e47zMD5aOT+tjjQWjX18ACtdkQ5Y/vrcfbcQ107Rh+MXjOCIx4KhW0wPmOvG8iQ5w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=7.10.1" - } - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/lodash-es": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", - "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/micro-eth-signer": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/micro-eth-signer/-/micro-eth-signer-0.14.0.tgz", - "integrity": "sha512-5PLLzHiVYPWClEvZIXXFu5yutzpadb73rnQCpUqIHu3No3coFuWQNfE5tkBQJ7djuLYl6aRLaS0MgWJYGoqiBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.8.1", - "@noble/hashes": "~1.7.1", - "micro-packed": "~0.7.2" - } - }, - "node_modules/micro-eth-signer/node_modules/@noble/curves": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", - "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.7.2" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/micro-eth-signer/node_modules/@noble/hashes": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", - "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/micro-packed": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/micro-packed/-/micro-packed-0.7.3.tgz", - "integrity": "sha512-2Milxs+WNC00TRlem41oRswvw31146GiSaoCT7s3Xi2gMUglW5QBeqlQaZeHr5tJx9nm3i57LNXPqxOOaWtTYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/micro-packed/node_modules/@scure/base": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", - "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ndjson": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-2.0.0.tgz", - "integrity": "sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==", - "dev": true, - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "json-stringify-safe": "^5.0.1", - "minimist": "^1.2.5", - "readable-stream": "^3.6.0", - "split2": "^3.0.0", - "through2": "^4.0.0" - }, - "bin": { - "ndjson": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ox": { - "version": "0.14.44", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.14.44.tgz", - "integrity": "sha512-O54qXXHEk4ySamMSyBpI0AeBegS5frxU6+LA6Jb9Sf6kMOxcTNaxYmwZfpOu22DIQsdKfgQxHq8EsAGaoBQScA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@adraffy/ens-normalize": "^1.11.0", - "@noble/ciphers": "^1.3.0", - "@noble/curves": "1.9.1", - "@noble/hashes": "^1.8.0", - "@scure/bip32": "^1.7.0", - "@scure/bip39": "^1.6.0", - "abitype": "^1.2.3", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/ox/node_modules/@noble/ciphers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", - "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ox/node_modules/@noble/curves": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", - "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ox/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ox/node_modules/@scure/base": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", - "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ox/node_modules/@scure/bip32": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", - "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@noble/curves": "~1.9.0", - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ox/node_modules/@scure/bip39": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", - "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/p-map": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.8.tgz", - "integrity": "sha512-MitaVsCuCFIvOLLPIU7NnfrZvS9H9h7kwMUkDo+T2pEISaJD48IV9S8iIdXB7PsvvdxyYcsSTTrr90XKsbulNw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-format": { - "version": "30.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", - "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/react-is-18": "npm:react-is@^18.3.1", - "@jest/react-is-19": "npm:react-is@^19.2.5", - "@jest/schemas": "30.5.0", - "ansi-styles": "^5.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz", - "integrity": "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/resolve.exports": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", - "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "peer": true - }, - "node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "readable-stream": "3" - } - }, - "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "dev": true, - "license": "0BSD", - "peer": true - }, - "node_modules/tsx": { - "version": "4.23.13", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.13.tgz", - "integrity": "sha512-BL5MGkRln6aDYhb0xbQlEAGw743BaZYWdbWtdJOBriYJboKgUUYCadFp2/FpBBZquBC/ezNBn7wMMPx7FDZUDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "~0.28.0" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, - "node_modules/typescript": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", - "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc" - }, - "engines": { - "node": ">=16.20.0" - }, - "optionalDependencies": { - "@typescript/typescript-aix-ppc64": "7.0.2", - "@typescript/typescript-darwin-arm64": "7.0.2", - "@typescript/typescript-darwin-x64": "7.0.2", - "@typescript/typescript-freebsd-arm64": "7.0.2", - "@typescript/typescript-freebsd-x64": "7.0.2", - "@typescript/typescript-linux-arm": "7.0.2", - "@typescript/typescript-linux-arm64": "7.0.2", - "@typescript/typescript-linux-loong64": "7.0.2", - "@typescript/typescript-linux-mips64el": "7.0.2", - "@typescript/typescript-linux-ppc64": "7.0.2", - "@typescript/typescript-linux-riscv64": "7.0.2", - "@typescript/typescript-linux-s390x": "7.0.2", - "@typescript/typescript-linux-x64": "7.0.2", - "@typescript/typescript-netbsd-arm64": "7.0.2", - "@typescript/typescript-netbsd-x64": "7.0.2", - "@typescript/typescript-openbsd-arm64": "7.0.2", - "@typescript/typescript-openbsd-x64": "7.0.2", - "@typescript/typescript-sunos-x64": "7.0.2", - "@typescript/typescript-win32-arm64": "7.0.2", - "@typescript/typescript-win32-x64": "7.0.2" - } - }, - "node_modules/undici": { - "version": "6.28.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.1.tgz", - "integrity": "sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true, - "license": "MIT" - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/viem": { - "version": "2.56.5", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.56.5.tgz", - "integrity": "sha512-GuEf/oee0PHgy4D6JIA8u0rY1g+sM5nF+p7HyMHO3vjlHC5G/ljfrgnUOnrES9m5Ny/P3RwWCHjDuN2T6HUWzQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@noble/curves": "1.9.1", - "@noble/hashes": "1.8.0", - "@scure/bip32": "1.7.0", - "@scure/bip39": "1.6.0", - "abitype": "1.2.3", - "isows": "1.0.7", - "ox": "0.14.44", - "ws": "8.21.0" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/viem/node_modules/@noble/curves": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", - "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/@scure/base": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", - "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/@scure/bip32": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", - "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@noble/curves": "~1.9.0", - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/@scure/bip39": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", - "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} diff --git a/contracts/package.json b/contracts/package.json deleted file mode 100644 index a9ebe75..0000000 --- a/contracts/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "@nosus-monad/contracts", - "private": true, - "version": "0.1.0", - "type": "module", - "scripts": { - "compile": "hardhat compile", - "test": "hardhat test", - "deploy:monad": "hardhat run scripts/deploy.ts --network monadTestnet" - }, - "devDependencies": { - "@nomicfoundation/hardhat-toolbox-viem": "5.0.7", - "@types/node": "24.10.1", - "hardhat": "3.16.0", - "typescript": "7.0.2" - } -} diff --git a/contracts/scripts/canary-relayers.ts b/contracts/scripts/canary-relayers.ts deleted file mode 100644 index c1763db..0000000 --- a/contracts/scripts/canary-relayers.ts +++ /dev/null @@ -1,46 +0,0 @@ -// Creates (once) and funds the relayer keys the `canary` edge function uses, -// and allow-lists them on NoSusCanary. Safe to re-run: it reuses the saved -// keys, only tops up balances below half the target, and skips relayers that -// are already allowed. -// -// Keys are written to contracts/.canary-relayers.local.json (git-ignored). -// They are TESTNET-ONLY keys. Never print them, commit them or reuse them. -import { existsSync, readFileSync, writeFileSync } from "node:fs"; -import { network } from "hardhat"; -import { parseEther } from "viem"; -import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; - -if (process.env.CONFIRM_MONAD_DEPLOY !== "1") { - throw new Error("Refusing to touch Monad Testnet without CONFIRM_MONAD_DEPLOY=1."); -} -const contract = process.env.CANARY_CONTRACT_ADDRESS; -if (!contract || !/^0x[0-9a-fA-F]{40}$/.test(contract)) { - throw new Error("Set CANARY_CONTRACT_ADDRESS to the deployed NoSusCanary address."); -} -const count = Number(process.env.CANARY_RELAYER_COUNT ?? "6"); -const fundEach = parseEther(process.env.CANARY_RELAYER_FUND_MON ?? "1"); -const file = ".canary-relayers.local.json"; - -const keys: `0x${string}`[] = existsSync(file) ? JSON.parse(readFileSync(file, "utf8")) : []; -while (keys.length < count) keys.push(generatePrivateKey()); -writeFileSync(file, JSON.stringify(keys, null, 2)); - -const { viem } = await network.create("monadTestnet"); -const [owner] = await viem.getWalletClients(); -const publicClient = await viem.getPublicClient(); -const canary = await viem.getContractAt("NoSusCanary", contract as `0x${string}`); - -for (const key of keys) { - const relayer = privateKeyToAccount(key).address; - const balance = await publicClient.getBalance({ address: relayer }); - if (balance < fundEach / 2n) { - const hash = await owner.sendTransaction({ to: relayer, value: fundEach }); - await publicClient.waitForTransactionReceipt({ hash }); - } - if (!(await canary.read.isRelayer([relayer]))) { - const hash = await canary.write.setRelayer([relayer, true]); - await publicClient.waitForTransactionReceipt({ hash }); - } - console.log(`relayer ready: ${relayer}`); -} -console.log(`${keys.length} relayers ready. Keys saved in contracts/${file} (git-ignored).`); diff --git a/contracts/scripts/deploy-canary.ts b/contracts/scripts/deploy-canary.ts deleted file mode 100644 index f97fa1e..0000000 --- a/contracts/scripts/deploy-canary.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { network } from "hardhat"; - -if (process.env.CONFIRM_MONAD_DEPLOY !== "1") { - throw new Error( - "Refusing to deploy to Monad Testnet. After an explicit named-target approval, set CONFIRM_MONAD_DEPLOY=1.", - ); -} - -const connection = await network.create("monadTestnet"); -const { viem } = connection; -const canary = await viem.deployContract("NoSusCanary"); - -console.log(`NoSusCanary deployed at: ${canary.address}`); -console.log("Next: set CANARY_CONTRACT_ADDRESS to this value and run scripts/canary-relayers.ts."); diff --git a/contracts/scripts/deploy.ts b/contracts/scripts/deploy.ts deleted file mode 100644 index 784e024..0000000 --- a/contracts/scripts/deploy.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { network } from "hardhat"; - -if (process.env.CONFIRM_MONAD_DEPLOY !== "1") { - throw new Error( - "Refusing to deploy to Monad Testnet. After an explicit named-target approval, set CONFIRM_MONAD_DEPLOY=1.", - ); -} - -const connection = await network.create("monadTestnet"); -const { viem } = connection; -const drops = await viem.deployContract("NoSusMonadDrops"); - -console.log(`NoSusMonadDrops deployed at: ${drops.address}`); -console.log("Record this address in web/.env.local as NEXT_PUBLIC_DROPS_CONTRACT_ADDRESS."); diff --git a/contracts/test/NoSusCanary.test.ts b/contracts/test/NoSusCanary.test.ts deleted file mode 100644 index 9724b91..0000000 --- a/contracts/test/NoSusCanary.test.ts +++ /dev/null @@ -1,111 +0,0 @@ -import assert from "node:assert/strict"; -import { describe, it } from "node:test"; -import { network } from "hardhat"; - -const noteId = `0x${"11".repeat(32)}` as const; -const otherNoteId = `0x${"22".repeat(32)}` as const; -const copiesHash = "0x1d9f0d2a2e10e3580481170dc38f3dce11399ee6d26c6621dbb3dc401b3c7adf"; -const readerTag = "0xaabbccddeeff00112233445566778899aabbccddeeff00112233445566778899"; -const zero32 = `0x${"0".repeat(64)}` as const; - -async function expectCustomError(action: Promise, name: string) { - await assert.rejects(action, (error: unknown) => - error instanceof Error && error.message.includes(name), - ); -} - -describe("NoSusCanary", () => { - async function deploy() { - const { viem } = await network.getOrCreate(); - const [owner, relayer, stranger] = await viem.getWalletClients(); - const canary = await viem.deployContract("NoSusCanary"); - const publicClient = await viem.getPublicClient(); - const testClient = await viem.getTestClient(); - return { viem, owner, relayer, stranger, canary, publicClient, testClient }; - } - - it("makes the deployer the owner and first relayer", async () => { - const { canary, owner } = await deploy(); - assert.equal((await canary.read.owner()).toLowerCase(), owner.account.address.toLowerCase()); - assert.equal(await canary.read.isRelayer([owner.account.address]), true); - }); - - it("lets only the owner manage relayers", async () => { - const { canary, relayer, stranger } = await deploy(); - await expectCustomError( - canary.write.setRelayer([stranger.account.address, true], { account: stranger.account }), - "NotOwner", - ); - await canary.write.setRelayer([relayer.account.address, true]); - assert.equal(await canary.read.isRelayer([relayer.account.address]), true); - await canary.write.setRelayer([relayer.account.address, false]); - assert.equal(await canary.read.isRelayer([relayer.account.address]), false); - }); - - it("seals a note once and rejects bad input and strangers", async () => { - const { canary, stranger, publicClient } = await deploy(); - const now = BigInt((await publicClient.getBlock()).timestamp); - - await expectCustomError( - canary.write.sealNote([noteId, 20, copiesHash, 0n], { account: stranger.account }), - "NotRelayer", - ); - const hash = await canary.write.sealNote([noteId, 20, copiesHash, now + 3600n]); - const receipt = await publicClient.waitForTransactionReceipt({ hash }); - console.log(` sealNote gasUsed=${receipt.gasUsed}`); - - const note = await canary.read.noteOf([noteId]); - assert.equal(note.copyCount, 20); - assert.equal(note.openedCount, 0); - assert.equal(note.copiesHash, copiesHash); - assert.equal(note.expiresAt, now + 3600n); - - await expectCustomError(canary.write.sealNote([noteId, 20, copiesHash, 0n]), "NoteExists"); - await expectCustomError(canary.write.sealNote([zero32, 20, copiesHash, 0n]), "InvalidNote"); - await expectCustomError(canary.write.sealNote([otherNoteId, 0, copiesHash, 0n]), "InvalidNote"); - await expectCustomError(canary.write.sealNote([otherNoteId, 20, zero32, 0n]), "InvalidNote"); - await expectCustomError(canary.write.sealNote([otherNoteId, 20, copiesHash, now - 1n]), "InvalidNote"); - await expectCustomError(canary.read.noteOf([otherNoteId]), "NoteMissing"); - - const events = await canary.getEvents.NoteSealed({ noteId }, { fromBlock: 0n }); - assert.equal(events.length, 1); - }); - - it("opens each copy exactly once and counts opens", async () => { - const { canary, stranger, publicClient } = await deploy(); - await canary.write.sealNote([noteId, 3, copiesHash, 0n]); - - await expectCustomError( - canary.write.openCopy([noteId, 0, readerTag], { account: stranger.account }), - "NotRelayer", - ); - const hash = await canary.write.openCopy([noteId, 0, readerTag]); - const receipt = await publicClient.waitForTransactionReceipt({ hash }); - console.log(` openCopy gasUsed=${receipt.gasUsed}`); - - const copy = await canary.read.copyOf([noteId, 0]); - assert.equal(copy.readerTag, readerTag); - assert.ok(copy.openedAt > 0n); - assert.equal((await canary.read.noteOf([noteId])).openedCount, 1); - - await expectCustomError(canary.write.openCopy([noteId, 0, readerTag]), "CopyTaken"); - await expectCustomError(canary.write.openCopy([noteId, 3, readerTag]), "InvalidCopy"); - await expectCustomError(canary.write.openCopy([noteId, 1, zero32]), "InvalidCopy"); - await expectCustomError(canary.write.openCopy([otherNoteId, 0, readerTag]), "NoteMissing"); - - const unopened = await canary.read.copyOf([noteId, 2]); - assert.equal(unopened.openedAt, 0n); - const events = await canary.getEvents.CopyOpened({ noteId }, { fromBlock: 0n }); - assert.equal(events.length, 1); - assert.equal(events[0].args.copyIndex, 0); - }); - - it("refuses opens after expiry", async () => { - const { canary, publicClient, testClient } = await deploy(); - const now = BigInt((await publicClient.getBlock()).timestamp); - await canary.write.sealNote([noteId, 5, copiesHash, now + 60n]); - await testClient.increaseTime({ seconds: 120 }); - await testClient.mine({ blocks: 1 }); - await expectCustomError(canary.write.openCopy([noteId, 0, readerTag]), "NoteExpired"); - }); -}); diff --git a/contracts/test/NoSusMonadDrops.test.ts b/contracts/test/NoSusMonadDrops.test.ts deleted file mode 100644 index 22482ee..0000000 --- a/contracts/test/NoSusMonadDrops.test.ts +++ /dev/null @@ -1,128 +0,0 @@ -import assert from "node:assert/strict"; -import { describe, it } from "node:test"; -import { network } from "hardhat"; - -const id = "0x4f4e4f5355535f4d4f4e41445f44524f505f3030303030303030303030303030"; -const digest = "0x1d9f0d2a2e10e3580481170dc38f3dce11399ee6d26c6621dbb3dc401b3c7adf"; -const noRecipient = "0x0000000000000000000000000000000000000000"; - -async function expectCustomError(action: Promise, name: string) { - await assert.rejects(action, (error: unknown) => - error instanceof Error && error.message.includes(name), - ); -} - -describe("NoSusMonadDrops", () => { - async function deployDropContract() { - const { viem } = await network.getOrCreate(); - const [sender, recipient, stranger] = await viem.getWalletClients(); - const drops = await viem.deployContract("NoSusMonadDrops"); - return { viem, sender, recipient, stranger, drops }; - } - - it("seals a ciphertext digest and exposes the initial receipt", async () => { - const { drops, sender, viem } = await deployDropContract(); - const publicClient = await viem.getPublicClient(); - const now = BigInt((await publicClient.getBlock()).timestamp); - const expiry = now + 3600n; - - await drops.write.seal([id, digest, noRecipient, expiry]); - - const receipt = await drops.read.receiptOf([id]); - assert.equal(receipt.sender.toLowerCase(), sender.account.address.toLowerCase()); - assert.equal(receipt.ciphertextDigest, digest); - assert.equal(receipt.opener, noRecipient); - assert.equal(await drops.read.canDecrypt([id, noRecipient]), false); - assert.equal(await drops.read.canDecrypt([id, sender.account.address]), false); - const sealedEvents = await drops.getEvents.Sealed({ id }, { fromBlock: 0n }); - assert.equal(sealedEvents.length, 1); - assert.equal(sealedEvents[0].args.sender?.toLowerCase(), sender.account.address.toLowerCase()); - }); - - it("rejects duplicate IDs and zero ciphertext digests", async () => { - const { drops } = await deployDropContract(); - - await drops.write.seal([id, digest, noRecipient, 0n]); - await expectCustomError(drops.write.seal([id, digest, noRecipient, 0n]), "DropAlreadyExists"); - await expectCustomError( - drops.write.seal([`${id.slice(0, -1)}1`, `0x${"0".repeat(64)}`, noRecipient, 0n]), - "InvalidCiphertextDigest", - ); - }); - - it("allows only the named recipient to acknowledge once", async () => { - const { drops, recipient, stranger } = await deployDropContract(); - await drops.write.seal([id, digest, recipient.account.address, 0n]); - assert.equal(await drops.read.canDecrypt([id, recipient.account.address]), false); - - await expectCustomError( - drops.write.acknowledgeOpen([id], { account: stranger.account }), - "RecipientOnly", - ); - - await drops.write.acknowledgeOpen([id], { account: recipient.account }); - assert.equal(await drops.read.canDecrypt([id, recipient.account.address]), true); - assert.equal(await drops.read.canDecrypt([id, stranger.account.address]), false); - const openedEvents = await drops.getEvents.OpenAcknowledged( - { opener: recipient.account.address }, - { fromBlock: 0n }, - ); - assert.equal(openedEvents.length, 1); - assert.equal(openedEvents[0].args.id, id); - await expectCustomError( - drops.write.acknowledgeOpen([id], { account: recipient.account }), - "DropAlreadyOpened", - ); - }); - - it("refuses an expired drop", async () => { - const { drops, sender, viem } = await deployDropContract(); - const publicClient = await viem.getPublicClient(); - const now = BigInt((await publicClient.getBlock()).timestamp); - - await drops.write.seal([id, digest, noRecipient, now + 60n]); - await publicClient.request({ - method: "evm_increaseTime", - params: [61], - }); - await publicClient.request({ method: "evm_mine", params: [] }); - - await expectCustomError(drops.write.acknowledgeOpen([id]), "DropExpired"); - assert.equal(await drops.read.canDecrypt([id, sender.account.address]), false); - }); - - it("stops decryption after expiry even if already acknowledged", async () => { - const { drops, recipient, viem } = await deployDropContract(); - const publicClient = await viem.getPublicClient(); - const now = BigInt((await publicClient.getBlock()).timestamp); - - await drops.write.seal([id, digest, recipient.account.address, now + 60n]); - await drops.write.acknowledgeOpen([id], { account: recipient.account }); - assert.equal(await drops.read.canDecrypt([id, recipient.account.address]), true); - - await publicClient.request({ - method: "evm_increaseTime", - params: [61], - }); - await publicClient.request({ method: "evm_mine", params: [] }); - - assert.equal(await drops.read.canDecrypt([id, recipient.account.address]), false); - }); - - it("treats the exact expiry timestamp as expired", async () => { - const { drops, recipient, viem } = await deployDropContract(); - const publicClient = await viem.getPublicClient(); - const now = BigInt((await publicClient.getBlock()).timestamp); - const expiry = now + 60n; - - await drops.write.seal([id, digest, recipient.account.address, expiry]); - await publicClient.request({ - method: "evm_increaseTime", - params: [60], - }); - await publicClient.request({ method: "evm_mine", params: [] }); - - await expectCustomError(drops.write.acknowledgeOpen([id], { account: recipient.account }), "DropExpired"); - assert.equal(await drops.read.canDecrypt([id, recipient.account.address]), false); - }); -}); diff --git a/contracts/tsconfig.json b/contracts/tsconfig.json deleted file mode 100644 index 27a8578..0000000 --- a/contracts/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "module": "esnext", - "moduleResolution": "bundler", - "strict": true, - "target": "es2022", - "types": ["node"] - } -} diff --git a/docs/AGENT_COLLABORATION.md b/docs/AGENT_COLLABORATION.md deleted file mode 100644 index ecaa45a..0000000 --- a/docs/AGENT_COLLABORATION.md +++ /dev/null @@ -1,35 +0,0 @@ -# Independent-agent collaboration - -Folder layout reduces context; it does not prevent merge conflicts. Treat each -task as a narrow charter, then isolate it in a worktree. - -## Task charter - -Every agent prompt starts with: objective, allowed paths, forbidden paths, -contracts touched, and acceptance checks. One task owns one path area. If a -change crosses contract/web/backend boundaries, write a short decision in -`docs/` first and create a separate integration task. - -## Worktree pattern - -From the parent directory, give every agent a separate branch and folder: - -```powershell -git -C nosus-monad worktree add ..\nosus-monad- -b codex/ -``` - -Do not let two unconnected agents edit the same folder or shared lockfile. -They each make small commits; an integration agent reviews the diffs, resolves -only intentional conflicts, and runs the focused checks. - -## Current ownership boundaries - -| Area | Owner task type | Forbidden to unrelated tasks | -|---|---|---| -| `contracts/` | contract invariant | web/backend changes | -| `web/` | UI or wallet flow | Solidity/migration changes | -| `supabase/` | isolated backend | production NO SUS or client secrets | -| `docs/` + `.cursor/` | operating model | product behavior without owner approval | - -Main is the integration branch. Merge only after the explicit finalization -gate in `AGENTS.md`; deployment needs a named target. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index b18c2c9..068a462 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -1,30 +1,78 @@ -# Architecture and trust model +# Architecture -## Flow +NO SUS Canary has three parts: the Flutter app (sender and reader), one Supabase Edge Function +called `canary` (the relayer), and Solana devnet (the receipts). The server stores only encrypted +copies; the chain stores only hashes. -1. The creator encrypts a harmless personal test note in the browser with Lit threshold custody. -2. The browser stores only encrypted payload and metadata in the experiment's Supabase project. -3. The creator seals the ciphertext digest and access policy in `NoSusMonadDrops` on Monad testnet. -4. The recipient wallet calls `acknowledgeOpen`. -5. Lit allows only the acknowledged wallet to decrypt after `canDecrypt(dropId, wallet)` succeeds - on Monad Testnet. The Lit access-control condition uses chain key `monadTestnet` and binds the - second argument to the authenticated wallet (`:userAddress`). -6. The acknowledged wallet may retry decryption until expiry. An acknowledgement is not evidence that - decryption succeeded, and the product does not claim to count or prevent repeated local reads. -7. The backend may remove an encrypted object after its retention window, but that deletion is - operational—not publicly or cryptographically provable. +```mermaid +sequenceDiagram + autonumber + participant S as Sender's device + participant F as Relayer (edge function "canary") + participant DB as Postgres + participant SOL as Solana devnet (SPL Memo) + participant R as Reader's browser -## What the receipt proves + S->>S: write note, make N marked copies, encrypt each (AES-256, key in the link fragment) + S->>F: create: note id, owner hash, N ciphertexts, copies hash + F->>DB: insert note + N encrypted copies + F->>SOL: seal memo {"t":"seal", note, copies, hash, exp} + SOL-->>F: signature (confirmed) + F-->>S: seal signature, then S shows the link and "Sealed on Solana" + R->>F: open: note id, device id, typed name + F->>DB: assign the next unused copy to this device + F->>SOL: open memo {"t":"open", note, copy, tag} + SOL-->>F: signature + F-->>R: that copy's ciphertext and signature, decrypted with the key from the link fragment + S->>F: status: note id, owner secret + F-->>S: who opened which copy, with signatures + S->>S: check a leak: match pasted text against every copy's fingerprint, on device +``` -It proves a wallet acknowledged a drop with a committed ciphertext digest at a chain timestamp. It does -not prove a human read it, establish real-world identity, stop screenshots, count decryptions, prove -storage deletion, or create legal evidence by itself. +## Components -## Data boundaries +| Part | Code | Notes | +|---|---|---| +| Sender and reader UI | `app/lib/features/canary/presentation/` | Flutter. The deployed site is the standalone build `--dart-define=NOSUS_CANARY_ONLY=true`. | +| Copy marking and leak matching | `app/lib/features/canary/domain/canary_fingerprint.dart` | Word-twin swaps (`do not`/`don't`, `5`/`five`, …) plus an invisible marker. Up to 100 copies. Matching never leaves the device and names nobody when unsure. | +| Encryption | `app/lib/features/canary/data/canary_crypto.dart` | AES-256 (`package:encrypt`, default SIC/CTR mode), random IV per copy. | +| Local store | `app/lib/features/canary/data/canary_store.dart` | The sender's notes, keys, salts and fingerprints, in browser storage. | +| Screenshot OCR | `app/lib/features/canary/ocr/` | Android only (ML Kit). | +| Relayer | `app/supabase/functions/canary/index.ts` | Actions `create`, `open`, `status`. Deployed with `--no-verify-jwt`; callers use the publishable key. | +| Which receipts to send | `app/supabase/functions/canary/gating.ts` | Pure rules, tested offline in `gating_test.ts`. | +| Solana receipts | `packages/receipts-ts` via `app/supabase/functions/canary/solana.ts` | `@solana/kit` 8.4, `@solana-program/memo` 0.15, v0 transactions, confirmed by polling `getSignatureStatuses`. | +| Schema | `app/supabase/migrations/20260919090000_nosus_canary.sql`, `20261010090000_nosus_canary_solana.sql` | `canary_notes`, `canary_copies`, `canary_assign_copy()`. RLS on, no `anon` grants. | + +## Rules the relayer follows + +- **A link is never handed out unsealed.** `create` returns only after the seal memo is confirmed. + If the memo fails, `create` fails with `retry: true`, and a retry with the same note id reuses + the stored copies. +- **An open is never lost.** If the open memo fails, the copy is still delivered and its + signature is stored as `null`; the next open of that copy from the same device sends it again. +- **One device, one copy.** The device id is hashed and bound to one copy, so reopening shows the + same copy and sends no new memo. +- **Limits.** 2–100 copies, links live 1 hour, 1 day or 7 days, names 1–40 characters, + ciphertexts up to 12,000 characters. + +## Receipt format -| Location | May contain | Must never contain | +One SPL Memo instruction per transaction, compact JSON, hashes only. Full spec: +[RECEIPTS_SPEC.md](RECEIPTS_SPEC.md). + +```text +seal: {"p":"nosus-canary","v":1,"t":"seal","note":"0x…","copies":10,"hash":"0x…","exp":1792501806} +open: {"p":"nosus-canary","v":1,"t":"open","note":"0x…","copy":0,"tag":"0x…"} +``` + +## Costs and timings (devnet, measured) + +| | Value | Source | |---|---|---| -| Monad contract | Drop ID, encrypted-ciphertext digest, wallet addresses, expiry, timestamps | Plaintext, key, salt, filename, content | -| Browser | Plaintext while composing/decrypting, wallet session | Service-role key, deployer private key | -| Supabase | Encrypted payload, Lit metadata, public receipt metadata | Plaintext, Lit private material | -| Lit | Threshold encryption policy and encrypted material | A hidden central-release override | +| Fee per receipt | 5,000 lamports (0.000005 SOL) | Solana base fee for one signature; no priority fee is set | +| Compute per receipt | about 84,500 (open) to 91,600 (seal) CU | sampled receipts on Explorer | +| Memo size | 197 (open) to 218 (seal) bytes | Explorer | +| Confirmation | ~1.1 s | `tool/solana-spike`, 10 Oct 2026 | +| Click "Create" → sealed link | ~2.9 s | live recording, 20 Oct 2026 | + +Security model and threat model: [../SECURITY.md](../SECURITY.md). diff --git a/docs/CURSOR_HANDOFF.md b/docs/CURSOR_HANDOFF.md deleted file mode 100644 index c40aee3..0000000 --- a/docs/CURSOR_HANDOFF.md +++ /dev/null @@ -1,34 +0,0 @@ -# Cursor handover - -This repository is designed to continue cleanly in Cursor without re-reading the production NO SUS -codebase. - -## Open the right folder - -Open `C:\Users\shubh\_Active_Projects\NO_SUS\nosus-monad` in Cursor, not `no_sus`. -Cursor automatically loads root `AGENTS.md` and the versioned `.cursor/rules/*.mdc` rules. The rules are -kept small and scoped so unrelated contract or web context is not loaded. - -## First Cursor prompt - -```text -Read AGENTS.md, docs/STATUS.md, docs/ARCHITECTURE.md, docs/LIT_MONAD_SPIKE.md, and the local README for the area you will touch. -This is the isolated NO SUS — Monad Experiment repository. Continue only the next blocking milestone: -prove Lit threshold decryption against NoSusMonadDrops on Monad testnet using two wallets. Do not touch -the production NO SUS repository, deploy, apply Supabase migrations, or claim the feature is live until -the documented threshold-gate acceptance tests pass. Keep changes small, update STATUS.md, and end your -response with the exact finalization question in AGENTS.md. -``` - -## How to keep Cursor on track - -1. Start each task with the prompt above plus one concrete file/feature request. -2. Let Cursor read only the named local README and files; do not ask it to scan parent directories. -3. Before a new capability, ask it to update `docs/STATUS.md` with the acceptance criteria first. -4. Review `git diff` before allowing a deployment, migration, or contract funding action. -5. When a task is done, commit it and ask Cursor to record the actual check output in `docs/STATUS.md`. - -## Escalation rules - -Stop and ask for direction if threshold custody cannot bind a Monad wallet to `canDecrypt`, if a design -would put a secret into public calldata, or if a change needs production NO SUS credentials or services. diff --git a/docs/DEMO_RUNBOOK.md b/docs/DEMO_RUNBOOK.md deleted file mode 100644 index 62f2420..0000000 --- a/docs/DEMO_RUNBOOK.md +++ /dev/null @@ -1,34 +0,0 @@ -# Demo runbook - -This is a testnet experiment. Use only harmless, personally owned test notes. -Never use credentials, third-party documents, financial records, employment -material, or sensitive personal data. - -## Before the demo - -1. Confirm `docs/STATUS.md` says Gate T1 is verified. If it is not, demonstrate - the receipt interface only; do not claim a threshold unlock exists. -2. Use a fresh isolated Supabase project and testnet-only environment values. -3. Verify the current wallet, Monad network, contract address, explorer URL, - and the explicit gas limit generated for the write. -4. Open the browser at a local preview. Have the recipient QR/link and a - prepared test wallet ready, but do not show seed phrases or private keys. - -## Live flow - -1. State the promise exactly: an eligible recipient wallet can request - decryption only after its acknowledgement is recorded on Monad Testnet. -2. Seal a harmless note. Show the digest and transaction link, never plaintext - in a recording or logs. -3. Scan the recipient link, connect the named test wallet, and acknowledge. -4. Show the new event in the Receipt Wall and the verifier page. -5. If Gate T1 is verified, show the acknowledged wallet decrypting and the - second wallet failing. If it is not, stop at the receipt and say so. - -## What to say when challenged - -- The receipt proves a wallet action against a committed encrypted drop. -- It does not prove a person read or understood content, prevent screenshots, - identify a person, establish legal admissibility, or independently prove - server-side deletion. -- Costs and timing are live testnet measurements, not fixed promises. diff --git a/docs/DESIGN_SYSTEM.md b/docs/DESIGN_SYSTEM.md deleted file mode 100644 index 1b41825..0000000 --- a/docs/DESIGN_SYSTEM.md +++ /dev/null @@ -1,44 +0,0 @@ -# Design system - -The experiment uses the visual language reviewed from the user-provided NO SUS -Burn ad kit on 2026-09-16. That kit is a visual reference only. Its product -components and deployment assumptions belong to production NO SUS and must not -be copied into this separate experiment. - -## Visual rules - -- Use local Geist and Geist Mono assets from `web/src/app/fonts/`. -- Keep the canvas black (`#080808`), with white type, `#888888` secondary copy, - and thin white dividers. Use the small coral error state only for failure. -- Prefer flat rectangular surfaces, 2px corners, a white filled primary action, - and uppercase mono labels. Do not introduce gradients, glows, neon colors, - oversized shadows, or decorative crypto effects. -- Motion is functional and restrained: status may pulse by opacity; never use - motion to imply that a chain or threshold action succeeded. -- The experimental/testnet and trust-limit messages are product content, not - optional decoration. They must remain visible on every flow. - -## Token layers - -`web/src/app/globals.css` is the single source of truth: - -1. Raw palette tokens (`--black`, `--gray-dark`, `--white`) record values. -2. Semantic tokens (`--surface`, `--text-muted`, `--line`) describe purpose. -3. Component tokens (`--button-primary-bg`) describe reusable UI roles. - -Use an existing semantic token before adding a new value. Create a new raw token -only when a real, repeated need exists; then add its semantic alias. - -## Component expectations - -- Keep forms, receipt rows, and verifier fields as bordered information blocks. -- A status chip communicates system state; success styling is never evidence of - a real unlock unless the verified Lit–Monad gate permits it. -- The lock is a recognisable interface mark, not a security claim. Its unlocked - state is available only to a confirmed, unexpired recipient path. -- Preserve visible keyboard focus and `prefers-reduced-motion` support. - -## Before visual changes - -Read `web/README.md`, inspect only the screen you touch, and use localhost for -visual validation. Update this document if a durable visual rule changes. diff --git a/docs/LIT_MONAD_SPIKE.md b/docs/LIT_MONAD_SPIKE.md deleted file mode 100644 index df925de..0000000 --- a/docs/LIT_MONAD_SPIKE.md +++ /dev/null @@ -1,96 +0,0 @@ -# Gate T1 — Lit × Monad threshold-decrypt spike - -This is the first technical gate. Do not enable `web/src/lib/threshold.ts`, add -a fake fallback, or describe threshold unlock as shipped until every acceptance -test below has a recorded result in `STATUS.md`. - -## Preconditions - -- User explicitly approves a named Monad Testnet deployment target. -- `NoSusMonadDrops` is deployed and its bytecode/constructor-free address is - verified in the Monad explorer. -- Two controlled test wallets and only a harmless personal test note are ready. -- A current, supported Lit SDK is selected from Lit’s official documentation. - Do not silently revive the retired V3/`@lit-protocol/lit-node-client` Datil - packages. The selected packages for this spike are `@lit-protocol/lit-client` - **8.3.1**, `@lit-protocol/networks` **8.4.1**, and `@lit-protocol/auth` **8.2.3**, - targeting the Naga Dev network (`naga-dev`). Datil was sunset on 25 February 2026. - -## Selected condition - -The condition to send Lit is built in `web/src/lib/lit-conditions.ts` (browser) -and `tool/threshold-spike/conditions.mjs` (runner). It is an -`evmContractConditions` entry on chain key `monadTestnet` (Lit ACC schema, -chain ID 10143) that calls `canDecrypt(id, :userAddress)` and requires the -boolean result `true`. - -That chain key is published by Lit. It is **not** yet recorded evidence that -Lit nodes evaluate Monad Testnet state. Run `npm run dry-run` in -`tool/threshold-spike` to print the condition. `npm run live` runs the sender, -recipient, and stranger sequence against a named testnet deployment. It needs -three controlled test-wallet keys, not a Supabase project. Set -`THRESHOLD_SPIKE_CHECK_EXPIRY=1` to include the bounded wait-and-deny expiry test. - -## Condition to prove - -The Lit access-control condition must evaluate the deployed contract’s -`canDecrypt(bytes32 dropId, address wallet) -> bool` against Monad Testnet. - -The fixed first argument is the exact drop ID. The second argument must be the -address authenticated by the browser wallet. The condition’s result must equal -`true`. Do not use an off-chain API, a shared signed response, a server-owned -wallet, a key commitment, or a key/salt in transaction calldata. - -Lit’s custom-chain name/configuration is intentionally not assumed here. Record -the supported chain identifier, SDK package version, configuration, and source -link only after the live Lit client successfully reads Monad Testnet state. - -## Required evidence - -For one recorded ciphertext and drop ID, capture the exact command/browser -result (redacting no plaintext is needed because use a harmless note): - -1. Before `acknowledgeOpen`, recipient wallet A fails to decrypt. -2. Wallet A acknowledges and its transaction confirms. Wallet A can decrypt. -3. Wallet B attempts the same ciphertext and fails to decrypt. -4. A second `acknowledgeOpen` attempt reverts and does not change the opener. -5. A short-expiry drop lets no wallet decrypt after expiry. -6. Tampering with stored ciphertext fails integrity/decryption; no plaintext is - logged as part of the failure. - -## Implementation handoff - -When all acceptance tests are clean: - -1. Add the current supported Lit SDK with exact versions and a lockfile. -2. Implement browser-only encrypt/decrypt. Keep capacity credentials and any - server credentials out of `NEXT_PUBLIC_*`; do not turn the server into a - decryption oracle. -3. Persist only ciphertext, Lit metadata, digest, and receipt fields through a - narrow authenticated server route after it validates the sealed transaction. -4. Replace the guarded UI state with the real flow and add focused browser - tests for the six cases above. -5. Update `STATUS.md`, `ARCHITECTURE.md`, and `web/README.md` with the exact - evidence and remaining limitations. - -## Runner environment - -The runner reads values only from the process environment. Never paste a test -wallet private key into a command history, repository file, or `NEXT_PUBLIC_*` -variable. - -```text -THRESHOLD_SPIKE_RUN=1 -DROPS_CONTRACT_ADDRESS=0x... -SENDER_PRIVATE_KEY=0x... -RECIPIENT_PRIVATE_KEY=0x... -STRANGER_PRIVATE_KEY=0x... -SPIKE_DROP_ID=0x... # fresh random 32-byte value -SPIKE_EXPIRY_SECONDS=300 -THRESHOLD_SPIKE_CHECK_EXPIRY=1 # optional, makes the runner wait until expiry -``` - -The runner creates a harmless in-memory probe, prints no plaintext, and leaves -the product gate unchanged regardless of its result. Record the transaction -hashes, SDK versions, and all observed outcomes in `STATUS.md` before enabling -the browser flow. diff --git a/docs/README.md b/docs/README.md index ff68af0..b0c246c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,15 +1,11 @@ -# Documentation index +# Docs -Read this page after the root `AGENTS.md`; then open only the document relevant -to the task. - -| Document | Use it for | +| Document | Read it for | |---|---| -| [STATUS.md](STATUS.md) | Actual completed work, checks, and current blockers | -| [ARCHITECTURE.md](ARCHITECTURE.md) | Data flow and the limits of the receipt | -| [DESIGN_SYSTEM.md](DESIGN_SYSTEM.md) | Visual tokens, component rules, and the Burn-kit boundary | -| [LIT_MONAD_SPIKE.md](LIT_MONAD_SPIKE.md) | First technical gate: real address-bound threshold decrypt | -| [../tool/threshold-spike/README.md](../tool/threshold-spike/README.md) | Dry-run / live runner for that gate | -| [DEMO_RUNBOOK.md](DEMO_RUNBOOK.md) | Safe rehearsal and honest presentation language | -| [CURSOR_HANDOFF.md](CURSOR_HANDOFF.md) | Continuing with Cursor without importing production context | -| [AGENT_COLLABORATION.md](AGENT_COLLABORATION.md) | Isolated worktrees and path ownership for independent agents | +| [ARCHITECTURE.md](ARCHITECTURE.md) | How a note, a copy and a receipt move between device, relayer and Solana | +| [RECEIPTS_SPEC.md](RECEIPTS_SPEC.md) | The memo format (v1) and how to verify a receipt by hand | +| [../SECURITY.md](../SECURITY.md) | What is stored where, how each hash is made, the threat model | +| [SELF_HOSTING.md](SELF_HOSTING.md) | Running your own backend and devnet relayer | +| [STATUS.md](STATUS.md) | What is live, what is in progress, what needs owner approval | +| [canary/VERIFICATION.md](canary/VERIFICATION.md) | Every check that was run, with results | +| [../SUBMISSION.md](../SUBMISSION.md) | Judge FAQ and the 2-minute demo script | diff --git a/docs/RECEIPTS_SPEC.md b/docs/RECEIPTS_SPEC.md new file mode 100644 index 0000000..d417976 --- /dev/null +++ b/docs/RECEIPTS_SPEC.md @@ -0,0 +1,115 @@ +# NO SUS Canary receipts: memo format v1 + +A receipt is one Solana transaction with one SPL Memo instruction. The memo text says what +happened: a note was sealed, or one copy of it was opened. There is one receipt per seal and one +per open. + +The relayer (the Canary edge function) pays for and signs every receipt. Readers need no wallet. + +Code: [packages/receipts-ts](../packages/receipts-ts) (TypeScript, also used by the relayer) and +[packages/receipts-dart](../packages/receipts-dart). Both test against +[packages/test-vectors/receipts.json](../packages/test-vectors/receipts.json). + +## Where receipts live + +- Cluster: Solana devnet. +- Memo program: `MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr` (SPL Memo v3). Readers also accept + `Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo` (SPL Memo v1) and + `Memo4c2pN8afCj432Lb7RMVKi9PbQnnW7ewFFaV3oAH` (p-memo). +- Relayer: `CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx`. It pays the fee and signs the memo. + +## Memo text + +Compact JSON: UTF-8, no spaces, keys in exactly this order. + +```text +seal: {"p":"nosus-canary","v":1,"t":"seal","note":"0x<64 hex>","copies":N,"hash":"0x<64 hex>","exp":E} +open: {"p":"nosus-canary","v":1,"t":"open","note":"0x<64 hex>","copy":N,"tag":"0x<64 hex>"} +``` + +| Key | In | Value | Meaning | +| -------- | ---- | -------------------------- | ------------------------------------------------ | +| `p` | both | `"nosus-canary"` | Protocol name. | +| `v` | both | `1` | Format version. | +| `t` | both | `"seal"` or `"open"` | What happened. | +| `note` | both | bytes32 | Which note: `chainNoteId`. | +| `copies` | seal | integer | How many marked copies (2 to 100 today). | +| `hash` | seal | bytes32 | Commitment to every copy: `copiesHash`. | +| `exp` | seal | integer | Expiry in unix seconds. `0` means never. | +| `copy` | open | integer | Which copy was opened, counting from 0. | +| `tag` | open | bytes32 | Which device opened it, as a salted hash. | + +- bytes32 is `0x` followed by exactly 64 lowercase hex characters. +- Integers are non-negative, at most 2^53 − 1, with no sign, decimal point or exponent. +- A reader must reject any memo that is not byte for byte what an encoder would write. That + includes another key order, extra or missing keys, whitespace, uppercase hex and `3.0`. The + simple way: parse, check each field, encode again, and compare the strings. + +Real example (seal `2BHqnuCx…512bQ`, 217 bytes): + +```json +{"p":"nosus-canary","v":1,"t":"seal","note":"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40","copies":3,"hash":"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8","exp":1791634855} +``` + +## How each value is computed + +Every hash is SHA-256 over UTF-8 text, written as lowercase hex. `+` joins strings. Numbers are +written in decimal. + +| Value | Formula | Who can recompute it | +| --------------- | ------------------------------------------------------------------------ | ------------------------------------ | +| `note` | `"0x" + sha256("nosus-canary:" + noteId)` | Anyone with the note's UUID. | +| copy digest | `sha256(salt + ":" + index + ":" + copyText)` | The note owner. | +| `hash` | `"0x" + sha256(digest_0 + digest_1 + … + digest_n-1)`, no separator | The note owner. | +| device hash | `sha256("device:" + deviceId)` | The relayer. Never on chain. | +| `tag` | `"0x" + sha256(tagSalt + ":" + noteId + ":" + copy + ":" + deviceHash)` | The relayer only. | + +- `noteId` is the lowercase UUID in the reader link (`…/#/canary/?k=…`). +- `salt` is 32 random bytes as hex. It and every copy text stay on the owner's device. +- `tagSalt` is a secret the relayer holds. Without it a tag says nothing about the device. + +## What is never on chain + +- Note text and copy text, in any form other than the hashes above. +- Keys: the note's AES key (it stays in the link fragment), relayer keys, salts. +- Names: reader names and owner names. +- Device ids. Only the salted `tag` is written. + +## Size + +A seal memo is at most 219 bytes today (100 copies, a 10-digit `exp`). An open memo is at most 198 +bytes. Readers reject anything over 566 bytes, the most a single-signer memo transaction can +carry. + +## Verify a receipt by hand + +1. Open the transaction on Solana Explorer: + `https://explorer.solana.com/tx/?cluster=devnet`. +2. Check that it succeeded, that the program is a Memo program from the table above, and that + the signer is the relayer. +3. Read the memo text. Check it has the exact shape above. +4. Recompute `note` from the note's UUID and compare: + + ```sh + printf '%s' 'nosus-canary:' | sha256sum # macOS: shasum -a 256 + ``` + + Put `0x` in front of the result. It must equal `note`. +5. For a seal, check `copies` and `exp`. For an open, `copy` tells you which marked copy was + opened. + +Or let a CLI do steps 1 to 4: + +```sh +deno run --allow-net packages/receipts-ts/cli.ts --note +dart run bin/verify.dart --note # from packages/receipts-dart +``` + +## Versioning + +- `v` goes up on any field change: a field added, removed, renamed or moved, a new meaning, or a + new hash formula. +- A reader for one version rejects every other version. +- A new version gets new vectors in `packages/test-vectors`. Old vectors stay, so old receipts + still verify. +- Package versions (0.1.0 today) are separate from `v`. diff --git a/docs/SELF_HOSTING.md b/docs/SELF_HOSTING.md new file mode 100644 index 0000000..36a6c9d --- /dev/null +++ b/docs/SELF_HOSTING.md @@ -0,0 +1,84 @@ +# Run your own backend and relayer + +You don't need this to try Canary: `flutter run` uses the hosted devnet backend. Follow these steps +only to run Canary on your own Supabase project with your own Solana relayer key. Devnet only. + +You need: the [Supabase CLI](https://supabase.com/docs/guides/cli), Deno 2.x, the +[Solana CLI](https://docs.solana.com/cli/install-solana-cli-tools) (for `solana-keygen`), and a +Supabase project you own. + +## 1. Link the project + +```bash +cd app +supabase link --project-ref +``` + +## 2. Create the tables + +Apply only the two Canary migrations. Don't run `supabase db push`: the rest of +`app/supabase/migrations/` belongs to the full NO SUS app. + +```bash +supabase db query --linked --file supabase/migrations/20260919090000_nosus_canary.sql +supabase db query --linked --file supabase/migrations/20261010090000_nosus_canary_solana.sql +``` + +## 3. Make and fund a devnet relayer key + +```bash +solana-keygen new --no-bip39-passphrase --outfile ~/.config/nosus/relayer-devnet.json +solana-keygen pubkey ~/.config/nosus/relayer-devnet.json +``` + +Fund that address with devnet SOL at https://faucet.solana.com. Each receipt costs 0.000005 SOL, +so 1 SOL covers about 200,000 receipts. Keep the key file outside the repo. + +## 4. Set the function secrets + +```bash +supabase secrets set --project-ref \ + CANARY_TAG_SALT="$(openssl rand -hex 32)" \ + SOLANA_RELAYER_KEYS="$(cat ~/.config/nosus/relayer-devnet.json | tr -d ' \n')" \ + SOLANA_RPC_URL=https://api.devnet.solana.com +``` + +`SOLANA_RELAYER_KEYS` takes up to 32 comma-separated keys, each a base58 secret key or a +`solana-keygen` JSON array. Every secret is listed in [../.env.example](../.env.example). + +## 5. Bundle and deploy the function + +The function imports `packages/receipts-ts`, which is outside `app/`, so bundle it into one file +first and deploy the bundle from a scratch folder: + +```bash +cd .. # repo root +mkdir -p /tmp/canary-deploy/supabase/functions/canary +deno bundle --platform=deno app/supabase/functions/canary/index.ts \ + -o /tmp/canary-deploy/supabase/functions/canary/index.ts +supabase functions deploy canary --project-ref \ + --no-verify-jwt --use-api --workdir /tmp/canary-deploy +``` + +`--no-verify-jwt` is required: callers send only the publishable key. + +## 6. Point the app at your project + +Set `url` and `anonKey` (your publishable key) in `app/lib/config/supabase_credentials.dart`, then: + +```bash +cd app +flutter run -d chrome --dart-define=NOSUS_CANARY_ONLY=true +# or a static build for any host, served under /nosus-canary/: +flutter build web --release --base-href /nosus-canary/ --dart-define=NOSUS_CANARY_ONLY=true +``` + +## 7. Check it end to end + +Create a link, open it in a private window, and click the **Solana** chip. Explorer must show one +Memo instruction whose text starts with `{"p":"nosus-canary","v":1,"t":"open"` and holds hashes +only. Or decode it from the terminal: + +```bash +deno run --allow-net packages/receipts-ts/cli.ts +``` diff --git a/docs/STATUS.md b/docs/STATUS.md index e19259a..521d89d 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -1,79 +1,46 @@ -# Project status - -## NO SUS Canary — 19 Sep 2026 -- Feature: NO SUS Canary (server-gated copy delivery, client-side AES + local fingerprint matching) -- Contract NoSusCanary: Deployed at `0xb1a1858866122c84cf97861ca815fb070e010e68` on Monad Testnet (Chain ID 10143). Verified on Sourcify / Monadscan. 10 relayers funded (0.5 MON each) and authorized. -- Edge function `canary`: Deployed to project `ffidvfguojalzpclipzi` with secrets set (`CANARY_CONTRACT_ADDRESS`, `CANARY_RELAYER_KEYS`, `CANARY_TAG_SALT`, `MONAD_RPC_URL`). Smoke test verified. -- Migration `20260919090000_nosus_canary.sql` applied to ffidvfguojalzpclipzi: Yes (tables `canary_notes`, `canary_copies`, `canary_relayer_leases` verified with RLS active). -- Web app: Live at [http://shubham-sahu.me/nosus-canary/](http://shubham-sahu.me/nosus-canary/) (and [http://shubham-sahu.me/nosus-canary/#/canary](http://shubham-sahu.me/nosus-canary/#/canary)). Deployed standalone build (`NOSUS_CANARY_ONLY=true`) with the signature NO SUS black and white monochrome theme (`NoSusTheme`): opens directly to NO SUS Canary landing page without workspace, login, or back arrow, with a "NO SUS app ↗" link to `https://nosus.foo`. Main NO SUS app has its login/auth gate restored (`AuthScreen`/`WelcomeScreen`), with Canary accessible without an account via `CanaryEntryCard`. -- HTTPS status: Custom domain `shubham-sahu.me` certificate pending in GitHub Pages; GitHub Pages origin `https://https-shubhamsahu.github.io/nosus-canary/` 301-redirects to `http://shubham-sahu.me/nosus-canary/`. Clipboard copy has browser fallback for HTTP. -- APK: Built `NO-SUS-Canary.apk` (34.4 MB, package `foo.nosus.canary`, `--target-platform android-arm64`, screen capture allowed for demo mirroring). -- Flutter app tests: 129 passed, 1 skipped, analyze 0 issues. -- Hardening pass (22 Sep 2026, local only, not deployed): - - Codeword generation is about 4× faster, with byte-identical output. - - Dashboard polling stops once every copy is opened or the link expires. - - Errors from async work after a screen closes are guarded, and raw exception text is no longer shown to users. - - The Verify-on-Monad RPC has a 15 s timeout. - - `docs/canary/reference/` was removed after being merged. The fingerprint harness is now `app/tool/canary_fingerprint_harness.dart` (FAILURES: 0). - - Checks: 133 passed, 1 skipped; analyze 0 issues. -- Hosting (22 Sep 2026): this repo, renamed from `nosus-monad` (old URLs redirect), now also hosts the site. Source is on `main`; the built site is on `gh-pages` and served at http://shubham-sahu.me/nosus-canary/ (`app/` = the Flutter build, `hub/` + `index.html` = landing). - - To deploy: from `app/`, run `flutter build web --release --base-href /nosus-canary/app/ --dart-define=NOSUS_CANARY_ONLY=true` in PowerShell, copy `build/web/.` into `app/` on `gh-pages`, then commit and push. - - The separate site repo was retired. - -## Current state - - -Repository scaffolded on 16 September 2026. Gate T1 is **not** verified. Nothing is -deployed, no Supabase project is linked, and the product latch in -`web/src/lib/threshold.ts` remains `spike-required`. - -## Completed locally - -- `NoSusMonadDrops` records a digest, optional recipient, expiry, sender, and exactly one opener. - It has no owner, payment, key, salt, or plaintext path. `canDecrypt` is false before - acknowledgement, false for any non-opener, and false after expiry even if already opened. -- Contract tests: `6 passing (6 nodejs)` from `contracts/npm test`, including zero-address - denial and the exact-expiry boundary. -- The Next.js experience includes a restrained, flat black-and-white sender view, recipient acknowledgement route, - verifier, and backend-powered-but-empty Receipt Wall. It refuses to create or decrypt a drop - until Gate T1 is verified. The verifier can read `receiptOf` / `canDecrypt` from Monad when a - contract address is configured; that is a public view, not a Lit unlock. -- Lit SDK selection: `@lit-protocol/lit-client` **8.3.1**, `@lit-protocol/networks` **8.4.1**, - and `@lit-protocol/auth` **8.2.3** on **naga-dev**. Retired Datil/`lit-node-client` packages - are not direct dependencies. Nested packages still print retirement warnings at install time. -- The access-control condition uses Lit chain key `monadTestnet` (in - `@lit-protocol/accs-schemas`, chain ID 10143) and `canDecrypt(id, :userAddress)`. -- Gate T1 runner: `tool/threshold-spike` now prepares the sender, recipient, and stranger proof: - recipient denial before acknowledgement, sender seal, recipient acknowledgement and decrypt, - stranger denial, and an optional expiry denial. `npm run check` → 2 passing and `npm run dry-run` - passed. It has not connected to Lit or Monad, and no live wallet/decrypt result has been recorded. -- Web check: `web/npm run check` passed. -- Local visual review passed at `http://127.0.0.1:3017`. The UI uses local Geist assets and the - documented three-layer token system; production Burn components were not imported. -- Navigation check: `node tool/check-repository.mjs` passed. -- Initial isolated Supabase migration was created locally only; it has not been applied anywhere. -- Testnet deploys require `CONFIRM_MONAD_DEPLOY=1` after an explicit named-target approval. - -## Next blocking milestone - -Prove the threshold gate on Monad testnet using two wallets: - -1. An unopened wallet cannot decrypt. -2. The acknowledged wallet can decrypt. -3. A second wallet cannot decrypt. -4. An expired or already-opened drop cannot decrypt. - -Do not build demo claims, real drop creation, public deployment, or substitute a server gate ahead -of this result. See `LIT_MONAD_SPIKE.md` for the exact evidence to collect. The user must still -name a Monad Testnet deployment target and provide two controlled test wallets before a live run. - -## Deliberate decisions - -- Display brand: **NO SUS — Monad Experiment**. -- Separate repository and backend; no future production integration is implied. -- Open wallet connect is the primary demo flow; keep a prepared test wallet as an operator fallback. -- Demo material is limited to harmless personal test notes. -- Lit Protocol is the selected threshold-custody provider. Its Monad evaluation is a technical gate, - not an assumption. The `monadTestnet` ACC chain key is the identifier to try; a live decrypt - result is the only accepted proof. -- Datil / `@lit-protocol/lit-node-client` is retired (sunset 25 February 2026) and is not used. +# Status (20 Oct 2026) + +## Live + +- **Web app:** https://shubham-sahu.me/nosus-canary/ (gh-pages, standalone build + `NOSUS_CANARY_ONLY=true`, base href `/nosus-canary/`). `/nosus-canary/app/` redirects there and + keeps the hash, so older reader links still open. +- **Backend:** Supabase project `ffidvfguojalzpclipzi` (experiment project only; never the NO SUS + production project). It was paused for inactivity and restored on 20 Oct 2026. +- **Relayer:** edge function `canary`, version 7, deployed 20 Oct 2026 from `chore/judge-ready` + (pre-bundled with `deno bundle`, steps in [SELF_HOSTING.md](SELF_HOSTING.md)). It runs + `packages/receipts-ts`. Version 6 (10 Oct) was downloaded as a backup before the deploy. + Secrets set: `CANARY_TAG_SALT`, `SOLANA_RELAYER_KEYS`, `SOLANA_RPC_URL`. `CANARY_CONTRACT_ADDRESS` + is unset, which keeps the legacy EVM prototype path off. +- **Receipts:** Solana devnet, relayer `CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx`. 31 receipts + (19 seals, 12 opens, 0 failed) as of 20 Oct 2026. + +## Changed on 20 Oct 2026 + +- `packages/receipts-ts` and `packages/receipts-dart` (v0.1) and shared test vectors. The relayer's + `solana.ts` imports `packages/receipts-ts`; memo bytes are unchanged (checked against the real + devnet memos in `solana_test.ts`) and the deployed relayer was smoke-tested on devnet. +- Pitch and demo videos are attached to the `v0.1.0` GitHub release. +- Dead prototype code removed: the Solidity contracts, the Next.js threshold-decrypt spike and its + docs. History keeps them (last on `main` at `f1bb47e`). +- CI now runs Flutter analyze and tests, the fingerprint harness, Deno checks and tests for the + relayer and the TS library, and Dart checks and tests for the Dart library. + +## Owner approval needed for + +Deploying the function, applying SQL, setting secrets, funding keys or spending devnet SOL, +changing gh-pages, merging, pushing, and anything made public. + +## Rules worth repeating + +- Never run `supabase db push` against `ffidvfguojalzpclipzi`: its remote migration history holds + only the bootstrap entry, so `db push` would try to re-apply old migrations. Apply single files + with `supabase db query --linked --file …`. +- Deploy `canary` with `--no-verify-jwt`; callers send only the publishable key. +- Keep `CANARY_MONAD` (Flutter) off and `CANARY_CONTRACT_ADDRESS` (function) unset. +- Use harmless test notes only. + +## Next + +See the roadmap in the [README](../README.md#roadmap): mainnet, publishing the receipts library, +the Android app on the Solana dApp Store, PDFs and images, batched receipts, AES-GCM. diff --git a/docs/TECHNICAL_README.md b/docs/TECHNICAL_README.md deleted file mode 100644 index 1d398b4..0000000 --- a/docs/TECHNICAL_README.md +++ /dev/null @@ -1,124 +0,0 @@ -# NO SUS Canary - -> **Every reader gets their own copy. If it leaks, see whose copy it was.** - -[![Monad Testnet](https://img.shields.io/badge/Monad-Testnet%20(Chain%2010143)-836EF9?style=flat&logo=ethereum)](https://testnet.monadscan.com) -[![License: MIT](https://img.shields.io/badge/License-MIT-black.svg)](../LICENSE) -[![Flutter 3.44](https://img.shields.io/badge/Flutter-3.44.4-02569B?logo=flutter)](https://flutter.dev) -[![Supabase](https://img.shields.io/badge/Backend-Supabase%20Edge%20Functions-3ECF8E?logo=supabase)](https://supabase.com) - ---- - -## ⚡ Quick Links (Say all 4 out loud during pitch) - -| Item | Link / Value | -|---|---| -| **1. Live Public App** | **[http://shubham-sahu.me/nosus-canary/](http://shubham-sahu.me/nosus-canary/#/canary)** *(HTTPS mirror: [https://https-shubhamsahu.github.io/nosus-canary/#/canary](https://https-shubhamsahu.github.io/nosus-canary/#/canary))* | -| **2. Public GitHub Repo** | **[https://github.com/https-shubhamsahu/nosus-canary](https://github.com/https-shubhamsahu/nosus-canary)** | -| **3. Smart Contract** | [`0xb1a1858866122c84cf97861ca815fb070e010e68`](https://testnet.monadscan.com/address/0xb1a1858866122c84cf97861ca815fb070e010e68) on Monad Testnet (Chain ID `10143`) · [Verified on Sourcify](https://sourcify.dev/server/repo-ui/10143/0xb1a1858866122c84cf97861ca815fb070e010e68) | -| **4. Live Deployment** | Standalone Flutter Web + Android APK (`foo.nosus.canary`) | - ---- - -## 🎯 What is NO SUS Canary? - -When sensitive information is shared with a group—board members, investors, legal teams, journalists, or beta testers—leaks happen. Traditional watermarks are easily cropped or removed. - -**NO SUS Canary** introduces invisible, cryptographic, and linguistic canary-trapping powered by **Monad**: -1. **Sender creates a note**: The sender inputs a sensitive message. NO SUS uses natural synonym/word-twin permutation (e.g. `don't`/`do not`, `organize`/`organise`, `five`/`5`) and invisible zero-width unicode steganography to generate up to 100 uniquely fingerprinted variations. -2. **Commitment on Monad**: Before distribution, the sender's client hashes all encrypted variations and permanently commits the root hash to Monad testnet via `sealNote()`. The server never receives plaintext or keys. -3. **Recipient receives a personal copy**: When reader "Priya" opens the link, the relayer records an anonymous token on Monad testnet via `openCopy()`. Priya sees her clear text with cryptographic proof. -4. **Instant Leak Detection**: If a screenshot or copied text leaks on Twitter/WhatsApp, the sender pastes the leak (or takes a photo with the Android app's OCR). The sender's device runs a local Bayesian fingerprint match against the original plan and announces: - > **🐤 The canary sang. Copy #7 — Priya.** - ---- - -## 🔬 Why Monad? - -Canary trapping in high-stakes environments requires: -- **Parallel High Throughput**: When a company drops an all-hands memo to 1,000 employees at 9:00 AM, hundreds of concurrent claims hit the blockchain in seconds. Monad's parallel execution engine prevents nonce bottlenecks and dropped transactions. -- **Sub-Second Finality**: Readers get their verified copy instantly (< 1 second) with live explorer receipts. -- **Micro-Gas Cost**: Each copy recording costs ~0.015 MON (~78,000 gas), making enterprise-grade tamper-evident distribution economically practical. - ---- - -## 📋 Judge & Rubrics Checklist (Monad Blitz Mumbai V4) - -### Basic Points (100 / 100) -- [x] **Public GitHub repo**: [https://github.com/https-shubhamsahu/nosus-canary](https://github.com/https-shubhamsahu/nosus-canary) -- [x] **Proper README**: Complete pitch, live URL, contract address, architecture, and reproducible instructions. -- [x] **Smart contracts deployed on Monad Testnet**: [`0xb1a1858866122c84cf97861ca815fb070e010e68`](https://testnet.monadscan.com/address/0xb1a1858866122c84cf97861ca815fb070e010e68) on Chain ID `10143`. -- [x] **Project publicly hosted**: Live on custom domain `shubham-sahu.me` and GitHub Pages. - -### Advance Points — Project Working (100 / 100) -- [x] **All announced functions working**: Note generation, AES encryption, unique copy distribution, Monad transaction logging, and local leak fingerprint matching. -- [x] **Live transaction on-chain during demo**: Every `sealNote` and `openCopy` records live transactions visible on [Monadscan](https://testnet.monadscan.com). -- [x] **Contract verified on explorer**: Source verified on [Sourcify / Monadscan](https://sourcify.dev/server/repo-ui/10143/0xb1a1858866122c84cf97861ca815fb070e010e68). -- [x] **Someone else can run it from README**: Zero-friction setup instructions below. - -### Advance Points — Build in Public (100 / 100) -- [x] **Posted on socials**: Tagging `@monad_dev` and `@geeky_kartikey`. -- [x] **Demo video**: 30+ second running product video. -- [x] **Creative ad video**: Visual walk-through of the leak detection. - -### Bonus Points -- [x] **Public page on custom domain**: `http://shubham-sahu.me/nosus-canary/` (+15 pts). -- [x] **Pre-Market Fit**: Solves real leak paranoia for crypto DAOs, legal teams, boardrooms, and venture funds. -- [x] **Revenue Model**: Freemium for individuals; tiered B2B subscriptions ($99/mo) for team audits and enterprise canary endpoints. -- [x] **Innovation & Originality**: Combines zero-width Unicode steganography, linguistic token perturbation, client-side AES-256, and Monad parallel state logs. - ---- - -## 🚀 How to Run It Yourself (Reproduce in 3 Minutes) - -### Prerequisites -- [Flutter SDK](https://docs.flutter.dev/get-started/install) 3.44+ -- [Node.js](https://nodejs.org/) 20+ - -### 1. Run the Web App -```bash -# Clone the repository -git clone https://github.com/https-shubhamsahu/nosus-canary.git -cd nosus-canary/app - -# Install Flutter dependencies -flutter pub get - -# Run standalone Canary web app -flutter run -d chrome --dart-define=NOSUS_CANARY_ONLY=true -``` - -### 2. Run Contract Tests -```bash -cd ../contracts - -# Install dependencies -npm install - -# Run contract tests (includes gas benchmarks) -npx hardhat test -# Output: 11 passing (sealNote gasUsed ≈ 73,833, openCopy gasUsed ≈ 78,403) -``` - -### 3. Build Android APK -```bash -cd ../app -flutter build apk --release --target-platform android-arm64 --dart-define=NOSUS_ALLOW_SCREEN_CAPTURE=true -``` - ---- - -## 🔒 Security & Honesty Boundaries - -- **Whose copy, not who leaked it**: Canary identifies *which specific copy* was leaked. If an attacker steals Priya's unlocked phone, it reveals Priya's copy was compromised. -- **Zero Plaintext on Chain**: Monad receives only `sha256` commitment digests and salted anonymous reader tags. No plaintext, encryption keys, salts, or reader names ever touch the contract. -- **Client-Side Cryptography**: Encryption is AES-256-CBC executed in the sender's browser; the key resides solely in the `#` URL fragment and is never sent to the server. -- **No False Blame**: The matcher is strict; if a leak is too heavily mixed or partial, it names nobody rather than falsely accusing an innocent reader. - ---- - -## 👥 Team & Acknowledgements - -Built for **Monad Blitz Mumbai V4** (19 September 2026). -- **Author**: Shubham Sahu ([@shubhamsahu](https://github.com/https-shubhamsahu)) -- **Live App**: [http://shubham-sahu.me/nosus-canary/](http://shubham-sahu.me/nosus-canary/) diff --git a/docs/canary/NOSUS_CANARY_BUILD_PLAN.md b/docs/canary/NOSUS_CANARY_BUILD_PLAN.md deleted file mode 100644 index 949e9b0..0000000 --- a/docs/canary/NOSUS_CANARY_BUILD_PLAN.md +++ /dev/null @@ -1,589 +0,0 @@ -# NO SUS Canary — build plan for the Flutter app (Android APK + web) - -> **Status (22 Sep 2026): executed and shipped.** The `reference/` sources were merged into -> `app/` and `contracts/` and the folder was removed, so the copy commands below are historical. -> The live code is the source of truth. Verification log: [VERIFICATION.md](VERIFICATION.md). - -Owner decision (19 Sep 2026): the product is called **NO SUS**. The feature is **NO SUS Canary**. -This plan lets any AI agent, including a less capable one, build and ship it without guessing. -Every piece of code it needs is already written, and has been compiled, analyzed and tested on -this exact machine. It is stored in [`reference/`](reference/). Your job is mostly to **copy -files, run commands and check results**. Do not rewrite the reference code. - ---- - -## 0. Read this first (rules for any agent) - -1. **Work top to bottom.** Every step ends with a **DONE WHEN** check. Do not start the next step - until that check passes. After each step, tick it in the Progress log (section 9). -2. **Copy, don't retype.** Take source files from `docs/canary/reference/` with the copy commands - given here. Retyping code from this document is how mistakes happen. -3. **Owner approval gates.** Steps marked **[OWNER APPROVAL]** touch real services (Monad testnet - funds, the Supabase database, secrets, public GitHub). Ask the owner, in plain words, before - running them, and wait for a clear "yes" to that exact step. A "yes" to one step does not cover - the next one. -4. **Never touch production.** The production Supabase project is `rxfnazmusofikwaggntb`: never - use it. The only backend is the experiment project `ffidvfguojalzpclipzi`. The production app - id is `foo.nosus.app`; this build uses `foo.nosus.canary`. -5. **NEVER run `supabase db push`.** The remote migration history holds only one entry, for the - bootstrap. `db push` would try to re-apply ~21 old migrations and break the database. Apply the - one new SQL file with `supabase db query --linked --file …` (Phase 3). -6. **Secrets never go in chat, commits, logs, or `--dart-define`.** Keys stay in git-ignored - files, or in PowerShell variables that are never printed. -7. **Use PowerShell for every `flutter build` and `gh api` command.** Git Bash rewrites arguments - that start with `/`: it turned `--base-href /nosus-canary/` into - `C:/Program Files/Git/nosus-canary/`, and the build failed. If you must use Git Bash, prefix - the command with `MSYS_NO_PATHCONV=1`. -8. **Line endings.** Most files in `app/` use CRLF, and some lines added later use LF. The - reference edit script handles both. If you edit by hand and an exact-text match fails, line - endings are the likely cause. -9. **Stop and ask the owner if** any DONE WHEN check fails twice, if a step needs a production - credential, or if something in this plan contradicts what you see on disk. -10. `nosus-monad/AGENTS.md` asks you to end every response that changed files with its - finalization question. Keep doing that. - -**Flutter SDK:** `C:\Users\shubh\AppData\Local\flutter\bin\flutter.bat` (Flutter 3.44.4, Dart 3.12.2). -This document writes Flutter commands as `FLUTTER `. **At the start of every new PowerShell -session**, run this once so those commands work exactly as written: -```powershell -Set-Alias FLUTTER "C:\Users\shubh\AppData\Local\flutter\bin\flutter.bat" -``` - ---- - -## 1. What we are building - -**One line:** *Every reader gets their own copy. If it leaks, see whose copy it was.* - -### Flows - -| Who | What they do | What happens | -|---|---|---| -| **Sender** (APK or web, no account needed) | Welcome or Workspace → **NO SUS Canary** → **New Canary note** → types the note (or taps **Use the demo note**) → chooses the number of readers (10/20/50/100) and the expiry (1 h/1 day/7 days) → **Create Canary link** | The phone builds N copies that differ only in small word choices (e.g. "don't"/"do not", "organize"/"organise", "five"/"5"), plus an invisible marker. It encrypts each copy with one AES key and uploads **only ciphertext**. The key stays in the link's `#` fragment. Monad testnet records a hash committing to all copies (`sealNote`). The sender gets one link, a QR code and a "See the magic" view. | -| **Reader** (any phone browser, no install) | Opens the link → types their name → **Open my copy** | The server gives this device the next unused copy (the same copy again on refresh). Monad records "copy #i was opened" with an anonymous tag (`openCopy`). The phone decrypts and shows **"Copy 7 of 50 · made for Priya"** plus a proof link. | -| **Sender** | Note dashboard → **Seen by** list (updates every 3 s) → **Check a leak** → paste the leaked text (or, on Android, **Read a screenshot**) | Matching runs **on the sender's device**: "🐤 The canary sang. Copy #7 — Priya", with the open time and a Monad proof link. | - -### Honesty rules (they are already in the UI copy; keep them) -- Canary shows **whose copy** leaked, not **who shared it**. It never claims to block screenshots. -- If two readers compare and mix their copies, the result can point at the wrong copy. The matcher - is deliberately strict and names nobody when no single copy fits. -- The server hands out encrypted copies (it decides which reader gets which copy) and cannot read - them. This is **not** threshold custody (Lit/Gate T1). Canary does not change Gate T1 or - `monadThresholdVerified`. -- Monad testnet receives only hashes and anonymous tags, never text or names. - ---- - -## 2. Verified facts about this machine and repo (checked 19 Sep 2026) - -| Fact | Value / consequence | -|---|---| -| Repo | `C:\Users\shubh\_Active_Projects\NO_SUS\nosus-monad`, branch `codex/flutter-monad-integration`, with uncommitted changes. **`app/` is untracked** (never committed). | -| Flutter app | `nosus-monad/app` (package `no_sus`), Riverpod 3, Supabase, `encrypt` (the same AES used by Burn Notes). Baseline `flutter analyze`: **no issues**. | -| Tools | Node 22.17.0, npm 11.5.2, Supabase CLI 2.105.0 (logged in, `app/supabase` linked to `ffidvfguojalzpclipzi`), Docker 29.6.2, gh 2.95 (logged in as **https-shubhamsahu**), Vercel CLI 50.25.4, Java 17, adb at `C:\Users\shubh\AppData\Local\Android\Sdk\platform-tools\adb.exe` | -| Experiment backend | Live: `burn_notes` and `remote_configs` exist, and the function `create-redemption-code` is deployed. **Remote migration history = only `20260917205606`** (hence rule 5). | -| Monad RPC | `https://testnet-rpc.monad.xyz` **works** (chain 10143, gas price ≈ 102 gwei). `https://rpc.testnet.monad.xyz`, the default in `contracts/hardhat.config.ts`, **does not respond**, so always set `MONAD_RPC_URL`. | -| Explorer | `https://testnet.monadscan.com/tx/` responds. The app uses it. | -| Web hosting | `monad.nosus.foo` is **not live**. Production `app.nosus.foo` is on GitHub Pages. Canary web goes to **GitHub Pages: `https://https-shubhamsahu.github.io/nosus-canary/`**. | -| `web/CNAME` | Contains `monad.nosus.foo` and is copied into `build/web`. It **must be deleted** before publishing to GitHub Pages, or Pages tries to use that dead domain. | -| Android identity | The copied app used production `applicationId "foo.nosus.app"`. This plan changes it to **`foo.nosus.canary`**, which avoids the signature-conflict error "App not installed" and keeps it off the production Play identity. `namespace` stays `foo.nosus.app` because the Kotlin sources live in that package. | -| Screen capture | `MainActivity.onCreate` sets `FLAG_SECURE`, and so does `ScreenshotGuard.initialize()` (screenshots and mirroring show black). A demo build passes `NOSUS_ALLOW_SCREEN_CAPTURE=true`, which calls the existing `disableSecure` channel. | -| APK build time | About 10 minutes for a full release build. Use `--target-platform android-arm64` for a faster, smaller APK. Do not run other heavy jobs at the same time: one attempt died with "Could not start thread DartWorker" while another job was running. | -| Contract gas (measured) | `sealNote` 73,833 and `openCopy` 78,403. The limit used is **150,000**. Monad charges the gas **limit**, so each write costs about **0.0153 MON** at 102 gwei. | -| Fingerprint accuracy (measured, 20–100 copies, 15-slot demo note) | Full copy, marker stripped, OCR-style text: **300/300** correct. 2% character noise: 300/300 correct, **0 wrong names**. Partial excerpts: **0 wrong names** out of 600. Two copies mixed together: 1 wrong name in 600 (20 copies) to 23/600 (100 copies). This is why the UI says "strong hint, not proof" and why at least 10 swappable words are required. | -| New packages (resolve cleanly) | `qr_flutter 4.1.0`, `image_picker 1.2.3` (already a transitive dependency), `google_mlkit_text_recognition 0.17.1` (Android only; kept out of web by a conditional export). | -| Verification of the reference code | In a copy of `app/`: `flutter analyze` **no issues**; full `flutter test` **129 passed, 1 skipped**; `flutter build web --release --base-href /nosus-canary/` **OK**; release APK (arm64) **built, 34.4 MB, package `foo.nosus.canary`**; contract `hardhat test` **5 passing**; edge function `deno check` **OK**. Details: [VERIFICATION.md](VERIFICATION.md). The SQL and the live flow have **not** run yet (they need approvals). | - ---- - -## 3. Architecture - -``` - SENDER DEVICE (APK or web) SUPABASE (ffidvfguojalzpclipzi) MONAD TESTNET - ───────────────────────────── ───────────────────────────────── ───────────── - note text ─► buildCanaryPlan (slots) - ─► N random codewords (secret) - ─► N copies (+ invisible marker) - ─► AES encrypt each (key K) ──POST create──► edge fn `canary` - digests = sha256(salt:i:copy) ├─ insert canary_notes / canary_copies - copiesHash = sha256(all digests) └─ relayer key ── sealNote(noteId32, N, copiesHash, expiry) ──► NoSusCanary - owner record (plan, codewords, key, salt, - ownerSecret) saved ONLY on this device - link = /#/canary/?k= - - READER BROWSER - ────────────── - opens link, types name ──POST open──► edge fn `canary` - ├─ canary_assign_copy(note, sha256(device), name) (same copy on retry) - └─ relayer key ── openCopy(noteId32, i, readerTag) ──► NoSusCanary - ◄── copy i ciphertext + tx hash ── - decrypt with K from fragment → "Copy i+1 of N · made for " - - SENDER DASHBOARD ──POST status (ownerSecret)──► list of opened copies (name, time, tx) - LEAK CHECK: matchCanaryLeak(leak, plan, codewords) runs locally → copy i → name from status -``` - -### IDs and encodings (the contract between the components; do not change) - -| Thing | Format | Made by | -|---|---|---| -| `noteId` | UUID v4, lowercase with dashes | sender app (`Uuid().v4()`) | -| Chain note id | `0x` + sha256(`"nosus-canary:" + noteId`), 32 bytes | app **and** edge function (must match). Known answer: noteId `1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed` → `0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e` | -| Key `k` | 64 lowercase hex characters (AES-256) | sender app. Only ever in the link fragment | -| Per-copy IV | 32 hex characters (16 bytes), stored beside the ciphertext | sender app | -| Ciphertext | base64 from `encrypt` package `Encrypter(AES(key)).encrypt(text, iv:)`, the same setup as Burn Notes | sender app | -| Copy digest | sha256(`"::"`) hex | sender app (the salt never leaves the device) | -| `copies_hash` | `0x` + sha256(concatenation of the digests in index order) | sender app → chain | -| Owner secret | 64 hex characters. The server stores `sha256(ownerSecret)` as `owner_hash` | sender app | -| Device id | UUID v4 per browser or app install (SharedPreferences) | reader app. The server stores sha256(`"device:" + id`) | -| Reader tag (on chain) | `0x` + sha256(`":::"`) | edge function | -| Reader link | `/#/canary/?k=` | sender app | -| Invisible marker | U+2060, then 12 bits as U+200B (0) / U+200C (1), then U+2060. 10 data bits hold copyIndex+1 and 2 check bits hold popcount%4. Inserted after the 1st, 11th, 21st… word | fingerprint engine | - -### Components -- **Contract** `NoSusCanary.sol`: `sealNote`, `openCopy`, `noteOf`, `copyOf`, `setRelayer`. Writes are relayer-only; the owner manages relayers. -- **DB** (`20260919090000_nosus_canary.sql`): tables `canary_notes`, `canary_copies` and `canary_relayer_leases`, and functions `canary_assign_copy`, `canary_lease_relayer` and `canary_release_relayer`. RLS is on with **no policies**, so only the service role can read or write. -- **Edge function** `canary` (one function, actions `create`/`open`/`status`): uses viem to send transactions from a **pool of relayer keys**. Each key is leased for one in-flight transaction, so nonces never collide. -- **Flutter** `lib/features/canary/`: domain (fingerprint engine, link, models), data (crypto, API, store, repository) and presentation (entry card, home, composer, created/QR, note dashboard, leak check, reader), plus `ocr/` (ML Kit on Android, stub on web). - ---- - -## 4. File map - -All sources are in `docs/canary/reference/`, in the same relative layout as their destination. - -| Destination (relative to `nosus-monad/`) | Action | Phase | -|---|---|---| -| `app/lib/features/canary/**` (19 files) | copy | 1 | -| `app/test/unit/canary_fingerprint_test.dart`, `canary_link_test.dart` | copy | 1 | -| `app/lib/main.dart`, `app/lib/core/utils/web_links.dart`, `app/lib/services/screenshot_guard.dart`, `app/lib/features/monad/presentation/experiment_frame.dart`, `app/lib/features/onboarding/presentation/screens/welcome_screen.dart`, `app/lib/features/workspace/presentation/pages/workspace_tab.dart`, `app/web/index.html`, `app/web/manifest.json`, `app/android/app/build.gradle.kts`, `app/android/app/src/main/AndroidManifest.xml`, `app/android/app/proguard-rules.pro` | **edited by script** `reference/tools/canary_edits.js` (never by hand) | 1 | -| `app/pubspec.yaml`, `app/pubspec.lock` | `flutter pub add …` | 1 | -| `contracts/contracts/NoSusCanary.sol`, `contracts/test/NoSusCanary.test.ts`, `contracts/scripts/deploy-canary.ts`, `contracts/scripts/canary-relayers.ts` | copy | 2 | -| `app/supabase/migrations/20260919090000_nosus_canary.sql` | copy | 3 | -| `app/supabase/functions/canary/index.ts` | copy | 4 | -| `app/supabase/config.toml` | append 2 lines | 4 | -| `.gitignore` | append 2 lines | 0 | -| `AGENTS.md`, `app/AGENTS.md`, `docs/STATUS.md` | small documented edits | 0 / 7 | - ---- - -## 5. Phases - -### Phase 0 — Preflight (15 min) - -**0.1 Check location and state** (Git Bash or PowerShell): -```bash -cd /c/Users/shubh/_Active_Projects/NO_SUS/nosus-monad -git status --short | head -20 -git branch --show-current -``` -DONE WHEN: you are in `nosus-monad`, and the branch is `codex/flutter-monad-integration` or `feat/nosus-canary`. - -**0.2 Create the work branch.** `-c` carries the uncommitted work along; nothing is lost: -```bash -git switch -c feat/nosus-canary -``` -DONE WHEN: `git branch --show-current` prints `feat/nosus-canary`. - -**0.3 Ignore rules.** Append these two lines to `nosus-monad/.gitignore`. The first stops the -Supabase CLI temp files (the pooler URL and bootstrap SQL) from being committed. The second keeps -the relayer key file out of git. -``` -app/supabase/.temp/ -*.local.json -``` -DONE WHEN: `git check-ignore -v app/supabase/.temp/project-ref contracts/.canary-relayers.local.json` prints a rule for both paths. (The second file does not exist yet; `check-ignore` still reports the matching rule.) - -**0.4 [OWNER APPROVAL] Baseline commit.** Ask: *"May I commit the current uncommitted work -(including the untracked Flutter `app/`) as a baseline on `feat/nosus-canary`, so the Canary -changes can be reviewed as a clean diff?"* If yes: -```bash -git add -A -git status --short | grep -E "\.env|\.local\.json|supabase/\.temp" && echo "STOP: secret-like file staged" || true -git commit -m "chore: baseline Flutter app before NO SUS Canary" -``` -If the grep prints anything, run `git reset` and stop. DONE WHEN: `git status --short` is empty. - -**0.5 Record the owner decision in `AGENTS.md`.** This lets later agents work on Canary without -being blocked by the older naming and Gate T1 rules. It should already have been done when this plan -was written; check that a section titled `## Current workstream: NO SUS Canary` exists near the -top of `nosus-monad/AGENTS.md`. If it does not, add the section shown in Appendix A. -DONE WHEN: the section exists. - -### Phase 1 — Flutter code (40 min, no approvals needed) - -**1.1 Copy the new Canary files** (Git Bash): -```bash -cd /c/Users/shubh/_Active_Projects/NO_SUS/nosus-monad -cp -r docs/canary/reference/app/lib/features/canary app/lib/features/ -cp docs/canary/reference/app/test/unit/canary_fingerprint_test.dart app/test/unit/ -cp docs/canary/reference/app/test/unit/canary_link_test.dart app/test/unit/ -find app/lib/features/canary -type f | sort -``` -DONE WHEN: the listing shows exactly these 19 files (under `app/lib/features/canary/`): -- `data/`: `canary_api.dart`, `canary_crypto.dart`, `canary_repository.dart`, `canary_store.dart` -- `domain/`: `canary_fingerprint.dart`, `canary_link.dart`, `canary_models.dart` -- `ocr/`: `canary_ocr.dart`, `canary_ocr_mlkit.dart`, `canary_ocr_stub.dart` -- `presentation/`: `canary_composer_screen.dart`, `canary_created_screen.dart`, - `canary_entry_card.dart`, `canary_home_screen.dart`, `canary_leak_check_screen.dart`, - `canary_note_screen.dart`, `canary_providers.dart`, `canary_reader_screen.dart`, `canary_ui.dart` - -**1.2 Apply the edits to existing files with the script. Run it exactly once.** -```bash -cd /c/Users/shubh/_Active_Projects/NO_SUS/nosus-monad/app -node ../docs/canary/reference/tools/canary_edits.js -``` -DONE WHEN: it prints `ALL EDITS APPLIED`. If it prints `ANCHOR NOT FOUND`, the file already -differs from what the script expects. Run `git diff `. If the Canary edit is already -there, the script ran before, so skip this step. Otherwise stop and ask the owner. **Never run the -script twice on the same files.** - -What the script changes (so you can review `git diff`): -- `main.dart`: imports, `extractCanaryToken()`, the standalone reader branch (runs before the - redemption branch), the Android link routing branch, `title: 'NO SUS'`, and the `'/canary'` route. -- `experiment_frame.dart`: banner text → `NO SUS · Monad testnet · use harmless test notes only`. -- `web_links.dart`: `kWebAppOrigin` and `kWebAppBasePath` read `--dart-define`s (`WEB_APP_ORIGIN`, - `WEB_APP_BASE_PATH`) so links minted by the APK point at the deployed web app. -- `screenshot_guard.dart`: with `NOSUS_ALLOW_SCREEN_CAPTURE=true` it calls `disableSecure` and skips - the screenshot popups (for projector mirroring). -- `welcome_screen.dart` and `workspace_tab.dart`: the `MonadEntryCard` is replaced by `CanaryEntryCard`. - (The Monad screen still exists at route `/monad`.) -- `web/index.html` and `web/manifest.json`: names → `NO SUS`. -- `android/app/build.gradle.kts`: `applicationId = "foo.nosus.canary"`. -- `AndroidManifest.xml`: removes the `app.nosus.foo` App Links filter and fixes its comment. -- `proguard-rules.pro`: appends 4 `-dontwarn` rules for ML Kit's optional script recognizers. - Without them, the release APK fails at R8 with "Missing class …ChineseTextRecognizerOptions" - (verified). - -**1.3 Add the packages** (PowerShell): -```powershell -Set-Location C:\Users\shubh\_Active_Projects\NO_SUS\nosus-monad\app -FLUTTER pub add qr_flutter image_picker google_mlkit_text_recognition -``` -DONE WHEN: `pubspec.yaml` lists all three under `dependencies:`. The expected resolved versions are -qr_flutter 4.1.0, image_picker 1.2.3 and google_mlkit_text_recognition 0.17.1. - -**1.4 Check** (PowerShell, in `app`): -```powershell -FLUTTER analyze -FLUTTER test test/unit/canary_fingerprint_test.dart test/unit/canary_link_test.dart test/unit/deep_link_parsing_test.dart test/widget/welcome_screen_test.dart test/widget/monad_screen_test.dart -FLUTTER test -``` -DONE WHEN: analyze prints `No issues found!` and both test commands end with `All tests passed!`. -(The first analyze run takes about 3 minutes.) - -**1.5 [OWNER APPROVAL] Commit:** `git add -A && git commit -m "feat(canary): NO SUS Canary Flutter feature"` - -### Phase 2 — Contract (30 min; deploy and relayers need approval and MON) - -**2.1 Copy and test** (Git Bash): -```bash -cd /c/Users/shubh/_Active_Projects/NO_SUS/nosus-monad -cp docs/canary/reference/contracts/contracts/NoSusCanary.sol contracts/contracts/ -cp docs/canary/reference/contracts/test/NoSusCanary.test.ts contracts/test/ -cp docs/canary/reference/contracts/scripts/deploy-canary.ts contracts/scripts/ -cp docs/canary/reference/contracts/scripts/canary-relayers.ts contracts/scripts/ -cd contracts && npx hardhat test -``` -DONE WHEN: the output shows `11 passing` (6 existing NoSusMonadDrops tests plus 5 NoSusCanary tests) -and prints `sealNote gasUsed≈73833` and `openCopy gasUsed≈78403`. - -**2.2 Owner prepares the deployer wallet (owner does this, not the agent):** -1. Use a **testnet-only** wallet. Get ≥ 10 MON from the Blitz platform (https://blitz.devnads.com, - 50 MON per attendee) or a Monad faucet. -2. Create `nosus-monad/contracts/.env` (git-ignored by the `.env` rule) containing: - ``` - DEPLOYER_PRIVATE_KEY=0x<64 hex> - MONAD_RPC_URL=https://testnet-rpc.monad.xyz - ``` -DONE WHEN: the owner confirms the file exists. The agent must never print it: use -`Test-Path contracts/.env` only. - -**2.3 [OWNER APPROVAL] Deploy** (PowerShell, in `contracts`). The env loader keeps the key out of -command history: -```powershell -Set-Location C:\Users\shubh\_Active_Projects\NO_SUS\nosus-monad\contracts -Get-Content .env | ForEach-Object { if ($_ -match '^\s*([A-Z0-9_]+)\s*=\s*(.+?)\s*$') { Set-Item -Path ("Env:" + $matches[1]) -Value $matches[2] } } -$env:CONFIRM_MONAD_DEPLOY = "1" -npx hardhat run scripts/deploy-canary.ts --network monadTestnet -``` -DONE WHEN: it prints `NoSusCanary deployed at: 0x…`. Save that address as `CANARY_CONTRACT_ADDRESS` -in the Progress log and in `docs/STATUS.md`. Open `https://testnet.monadscan.com/address/
` -to see it. - -**2.4 [OWNER APPROVAL] Relayers.** Relayers are 10 fresh testnet keys, 0.5 MON each: about 5 MON -total, enough for about 320 opens. Same PowerShell session as 2.3: -```powershell -$env:CANARY_CONTRACT_ADDRESS = "0x
" -$env:CANARY_RELAYER_COUNT = "10" -$env:CANARY_RELAYER_FUND_MON = "0.5" -npx hardhat run scripts/canary-relayers.ts --network monadTestnet -``` -DONE WHEN: it prints `relayer ready: 0x…` 10 times and then `10 relayers ready`. The keys are in -`contracts/.canary-relayers.local.json`, which is git-ignored. **Never print or commit it.** It is -safe to re-run: it tops up balances and skips relayers that are already allowed. - -### Phase 3 — Database (10 min; needs approval) - -**3.1 Copy the migration** (Git Bash): -```bash -cd /c/Users/shubh/_Active_Projects/NO_SUS/nosus-monad -cp docs/canary/reference/app/supabase/migrations/20260919090000_nosus_canary.sql app/supabase/migrations/ -``` - -**3.2 [OWNER APPROVAL] Apply it to the experiment project ONLY.** Run from `app` (PowerShell), -and check the project ref first: -```powershell -Set-Location C:\Users\shubh\_Active_Projects\NO_SUS\nosus-monad\app -Get-Content supabase\.temp\project-ref # MUST print ffidvfguojalzpclipzi — otherwise STOP -supabase db query --linked --file supabase/migrations/20260919090000_nosus_canary.sql -``` -DONE WHEN: no error is printed. Then verify: -```powershell -supabase db query --linked "select to_regclass('public.canary_notes') as notes, to_regclass('public.canary_copies') as copies, to_regclass('public.canary_relayer_leases') as leases;" -``` -All three columns must be non-null. Then confirm the public key cannot read the table (Git Bash): -```bash -curl -s "https://ffidvfguojalzpclipzi.supabase.co/rest/v1/canary_copies?select=*&limit=1" \ - -H "apikey: sb_publishable_D_mmlb1jjS9Cl6QCuFwEJw_zPAb6kHS" \ - -H "Authorization: Bearer sb_publishable_D_mmlb1jjS9Cl6QCuFwEJw_zPAb6kHS" -``` -It must return `permission denied` (code 42501) or `[]`, never rows. **Do not** run `supabase db push`. - -### Phase 4 — Edge function (20 min; needs approval) - -**4.1 Copy and configure** (Git Bash): -```bash -cd /c/Users/shubh/_Active_Projects/NO_SUS/nosus-monad -mkdir -p app/supabase/functions/canary -cp docs/canary/reference/app/supabase/functions/canary/index.ts app/supabase/functions/canary/index.ts -printf '\n[functions.canary]\nverify_jwt = false\n' >> app/supabase/config.toml -tail -3 app/supabase/config.toml -``` -DONE WHEN: the tail shows `[functions.canary]` and `verify_jwt = false`. - -**4.2 [OWNER APPROVAL] Secrets** (PowerShell; the values are never printed): -```powershell -Set-Location C:\Users\shubh\_Active_Projects\NO_SUS\nosus-monad\contracts -$keys = node -e "console.log(require('./.canary-relayers.local.json').join(','))" -$salt = node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" -supabase secrets set --project-ref ffidvfguojalzpclipzi "CANARY_CONTRACT_ADDRESS=$env:CANARY_CONTRACT_ADDRESS" "CANARY_RELAYER_KEYS=$keys" "CANARY_TAG_SALT=$salt" "MONAD_RPC_URL=https://testnet-rpc.monad.xyz" -supabase secrets list --project-ref ffidvfguojalzpclipzi -``` -DONE WHEN: the list shows CANARY_CONTRACT_ADDRESS, CANARY_RELAYER_KEYS, CANARY_TAG_SALT and -MONAD_RPC_URL (as digests only). Never change `CANARY_TAG_SALT` after readers have opened copies. - -**4.3 [OWNER APPROVAL] Deploy** (PowerShell, in `app`; `--use-api` avoids Docker): -```powershell -Set-Location C:\Users\shubh\_Active_Projects\NO_SUS\nosus-monad\app -supabase functions deploy canary --project-ref ffidvfguojalzpclipzi --no-verify-jwt --use-api -``` -DONE WHEN: the output says the function was deployed. - -**4.4 Smoke test** (Git Bash). These must return exactly these errors: -```bash -K="sb_publishable_D_mmlb1jjS9Cl6QCuFwEJw_zPAb6kHS"; U="https://ffidvfguojalzpclipzi.supabase.co/functions/v1/canary" -curl -s -X POST "$U" -H "apikey: $K" -H "Content-Type: application/json" -d '{"action":"nope"}' -# -> {"error":"Unknown action"} -curl -s -X POST "$U" -H "apikey: $K" -H "Content-Type: application/json" -d '{"action":"status","note_id":"00000000-0000-4000-8000-000000000000","owner_secret":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}' -# -> {"error":"Note not found."} -curl -s -X POST "$U" -H "apikey: $K" -H "Content-Type: application/json" -d '{"action":"open","note_id":"00000000-0000-4000-8000-000000000000","device_id":"00000000-0000-4000-8000-000000000001","reader_name":"Test"}' -# -> {"error":"This Canary link is not valid."} -``` -If you get `canary is not configured (…)`, a secret is missing (see 4.2). If you get 401, the -function was deployed without `--no-verify-jwt`. - -### Phase 5 — Web build and GitHub Pages (20 min; the public repo needs approval) - -**5.1 Build** (PowerShell): -```powershell -Set-Location C:\Users\shubh\_Active_Projects\NO_SUS\nosus-monad\app -FLUTTER build web --release --base-href /nosus-canary/ -Remove-Item build\web\CNAME -ErrorAction SilentlyContinue -Select-String -Path build\web\index.html -Pattern '' -``` -DONE WHEN: `Select-String` prints the base tag and `build\web\CNAME` no longer exists. - -**5.2 Local check before publishing:** -`FLUTTER run -d chrome --web-port 8686`, then walk through Phase 7 steps 1–6 on -`http://localhost:8686/#/canary`. - -**5.3 [OWNER APPROVAL] First publish.** This creates the **public** repo `https-shubhamsahu/nosus-canary` -(PowerShell): -```powershell -$Web = "C:\Users\shubh\_Active_Projects\NO_SUS\nosus-monad\app\build\web" -$Pub = "C:\Users\shubh\_Active_Projects\NO_SUS\nosus-canary-pages" -if (Test-Path $Pub) { Remove-Item -Recurse -Force $Pub } -New-Item -ItemType Directory -Force $Pub | Out-Null -Copy-Item -Recurse "$Web\*" $Pub -New-Item -ItemType File -Force "$Pub\.nojekyll" | Out-Null -Set-Location $Pub -git init -b main -git add -A -git commit -m "Deploy NO SUS Canary web" -gh repo create nosus-canary --public --source . --push -gh api -X POST repos/https-shubhamsahu/nosus-canary/pages -f "source[branch]=main" -``` -**Later redeploys** (after rebuilding with 5.1), in PowerShell: -```powershell -$Web = "C:\Users\shubh\_Active_Projects\NO_SUS\nosus-monad\app\build\web" -$Pub = "C:\Users\shubh\_Active_Projects\NO_SUS\nosus-canary-pages" -Set-Location $Pub -Get-ChildItem -Force | Where-Object { $_.Name -ne '.git' } | Remove-Item -Recurse -Force -Copy-Item -Recurse "$Web\*" $Pub -Remove-Item "$Pub\CNAME" -ErrorAction SilentlyContinue -New-Item -ItemType File -Force "$Pub\.nojekyll" | Out-Null -git add -A; git commit -m "Redeploy NO SUS Canary web"; git push -``` - -DONE WHEN (within about 3 minutes): `curl -sI https://https-shubhamsahu.github.io/nosus-canary/` -returns `200`, and the page shows NO SUS. - -### Phase 6 — APK (15 min build time) - -**6.1 Build** (PowerShell, one line; do not run other heavy jobs at the same time): -```powershell -Set-Location C:\Users\shubh\_Active_Projects\NO_SUS\nosus-monad\app -FLUTTER build apk --release --target-platform android-arm64 --dart-define=WEB_APP_ORIGIN=https://https-shubhamsahu.github.io --dart-define=WEB_APP_BASE_PATH=/nosus-canary --dart-define=NOSUS_ALLOW_SCREEN_CAPTURE=true -Copy-Item build\app\outputs\flutter-apk\app-release.apk C:\Users\shubh\_Active_Projects\NO_SUS\NO-SUS-Canary.apk -``` -DONE WHEN: `Built build\app\outputs\flutter-apk\app-release.apk` is printed and `NO-SUS-Canary.apk` -exists. Signing falls back to the debug key because there is no `key.properties`. That is fine for -sideloading; **never upload this APK to Play.** - -**6.2 Install** (phone with USB debugging on): -```powershell -& "C:\Users\shubh\AppData\Local\Android\Sdk\platform-tools\adb.exe" install -r build\app\outputs\flutter-apk\app-release.apk -``` -DONE WHEN: it prints `Success` and the phone shows an app called **NO SUS**. The package is -`foo.nosus.canary`. If the Play Store NO SUS is also installed, both icons say NO SUS; for the -demo, uninstall the store one or move it to another screen. - -### Phase 7 — End-to-end acceptance (20 min) - -Use the deployed web app, a laptop and at least two phones. Tick each step: -1. Open `https://https-shubhamsahu.github.io/nosus-canary/#/canary` → **Use the demo note** → - 100 readers → 1 day → **Create Canary link**. The link, the QR code and "Sealed on Monad testnet · - view proof" appear, and the proof opens monadscan. -2. Phone A scans the QR → name "Asha" → **Open my copy** → it shows "Copy N of 100 · made for Asha" - and the proof link works. -3. Phone A refreshes the page and opens again → **same** copy number. -4. Phone B (or an incognito window) → name "Ben" → a **different** copy number. -5. On the laptop, **Who opened it** shows Asha and Ben within about 3 s, each with ✓. -6. Ben selects all his text and copies it → laptop **Check a leak** → paste → **Find the copy** → - "🐤 The canary sang. Copy #… — Ben". -7. Paste the original demo note → "This is your own original text". -8. Paste `the quick brown fox` → "Not enough of the note to tell" (no name). -9. APK: Welcome → **NO SUS Canary** → create a note on the phone → open it from another phone → - take a screenshot of that reader's copy → on the APK, **Check a leak → Read a screenshot** → - the right copy is named. -10. Mirror the APK screen (e.g. scrcpy) → it is **not** black. -11. Record the results and the contract address in `docs/STATUS.md` (Appendix B template). - -### Phase 8 — Demo runbook (peer vote at the event) - -**Setup:** -- Create the demo note on the **presenter phone (APK)** with **100 readers**. Leak checks work - only on the device that created the note. -- Mirror the phone to the projector (for example scrcpy over USB). Only the owner may install - software. -- Show the QR (**Show link & QR**) on the projector. - -**The flow (about 90 s):** -1. "Everyone scan this — it's our team's secret." -2. The Seen-by list fills live. -3. A volunteer screenshots their copy and posts it in a WhatsApp group shown on screen. -4. On the phone, **Check a leak → Read a screenshot** → "🐤 Copy #37 — Priya". -5. One line on Monad: "Which copy is whose was recorded on Monad before anyone could read it, so - nobody can reshuffle the blame afterwards." - -**Fallbacks:** -- If OCR misreads the screenshot, paste the text instead. -- If mirroring fails, create the note on the laptop web app instead and use paste. -- If the venue Wi-Fi is slow, use a phone hotspot for the presenter devices. - -### Phase 9 — After the hackathon -- Delete `docs/canary/reference/` after its files are committed in their real locations. The - constitution says: no duplicate files. -- Stretch goals: an owner link to move leak checks to another device, Google sign-in for readers, - and alerts when a copy is opened. - ---- - -## 6. Troubleshooting - -| Symptom | Cause | Fix | -|---|---|---| -| `--base-href should start and end with /` with `C:/Program Files/Git/...` | Git Bash path conversion | Use PowerShell, or `MSYS_NO_PATHCONV=1` | -| `ANCHOR NOT FOUND` from `canary_edits.js` | The file changed, or the script already ran | `git diff `; do not run it twice (step 1.2) | -| APK build: `Could not start thread DartWorker` | Out of memory or threads | Close other heavy jobs and rebuild | -| APK build fails in `R8Task` / "Missing class com.google.mlkit.vision.text.chinese…" | The ML Kit `-dontwarn` rules are missing | Step 1.2 adds them. Check the end of `android/app/proguard-rules.pro`; `build/app/outputs/mapping/release/missing_rules.txt` lists what R8 wants | -| Phone: "App not installed" | Old APK with the same id but a different signature | `adb uninstall foo.nosus.canary`, then install again | -| Reader: "NO SUS is busy" | All relayer keys have transactions in flight | Tap again. For big rooms add relayers: re-run 2.4 with a higher count, then 4.2 and 4.3 | -| Reader: "Could not record your copy on Monad" | RPC hiccup, or a relayer is out of MON | Retry. Check relayer balances on monadscan and top up with 2.4 | -| Reader: "Every copy of this note has been opened" | All N copies are taken | Create a new note with more readers | -| Function returns 401 | Deployed with JWT verification | Redeploy with `--no-verify-jwt` | -| `canary is not configured (X)` | Secret X is missing | Step 4.2 | -| Contract deploy hangs or fails with network errors | Default RPC `rpc.testnet.monad.xyz` is dead | Set `MONAD_RPC_URL=https://testnet-rpc.monad.xyz` in `contracts/.env` | -| Pages shows 404 or redirects to monad.nosus.foo | `CNAME` was published | Delete `CNAME` from the publish folder and push | -| Screenshot or mirror shows black | Built without `NOSUS_ALLOW_SCREEN_CAPTURE=true` | Rebuild with the define (6.1) | -| Composer: "Found X of the Y swappable words" | Note too short for that many readers | Longer note, fewer readers, or the demo note | -| Leak check names nobody | Too little text, or text edited or mixed from several copies | Paste more of the leak. Working as designed | - -## 7. If time runs out, cut in this order -1. OCR "Read a screenshot" (paste still works). 2. "See the magic". 3. The APK: demo from the -laptop web app plus phone browsers. **Never cut:** the reader flow, Seen by, the leak check by paste. - -## 8. Appendix A — AGENTS.md section (owner decision) -``` -## Current workstream: NO SUS Canary (owner decision, 19 Sep 2026) -- Brand: "NO SUS". Feature: "NO SUS Canary". This supersedes the "NO SUS — Monad Experiment" - naming rule for user-facing text. -- Build plan: docs/canary/NOSUS_CANARY_BUILD_PLAN.md (follow it step by step). -- Canary is server-gated copy delivery, disclosed as such. It does not use Lit, does not change - Gate T1, and does not change monadThresholdVerified. -- Still requires explicit owner approval each time: contract deploys, funding wallets, applying - SQL, setting secrets, deploying functions, creating public repos or Pages, commits and pushes. -``` - -## 8b. Appendix B — STATUS.md entry template -``` -## NO SUS Canary — -- Contract NoSusCanary:
(monadscan link) -- Relayers: , funded MON each -- Migration 20260919090000_nosus_canary.sql applied to ffidvfguojalzpclipzi: -- Edge function `canary` deployed: -- Web: https://shubham-sahu.me/nosus-canary/#/canary -- APK: NO-SUS-Canary.apk (foo.nosus.canary, debug-signed, sideload only) -- Acceptance (Phase 7): steps 1–10 -``` - -## 9. Progress log (tick as you go; add dates, notes and addresses) -- [x] 0.1 location/branch checked -- [x] 0.2 branch `feat/nosus-canary` -- [x] 0.3 .gitignore rules -- [x] 0.4 baseline commit (owner OK) -- [x] 0.5 AGENTS.md section present -- [x] 1.1 Canary files copied -- [x] 1.2 edit script applied once -- [x] 1.3 packages added -- [x] 1.4 analyze clean, tests green -- [x] 1.5 commit (owner OK) -- [x] 2.1 contract tests 11 passing -- [x] 2.2 deployer .env ready (owner) -- [x] 2.3 deployed: CANARY_CONTRACT_ADDRESS = 0xb1a1858866122c84cf97861ca815fb070e010e68 -- [x] 2.4 relayers ready (count 10, 0.5 MON each) -- [x] 3.2 migration applied + verified -- [x] 4.2 secrets set -- [x] 4.3 function deployed -- [x] 4.4 smoke tests pass -- [x] 5.1 web built, CNAME removed -- [x] 5.3 Pages live at https://shubham-sahu.me/nosus-canary/#/canary -- [x] 6.1 APK built → NO-SUS-Canary.apk -- [ ] 6.2 installed on demo phone -- [ ] 7 acceptance 1–10 passed -- [ ] 8 demo rehearsed twice - -Reference-code verification when this plan was written (19 Sep 2026): analyze clean; full test suite -129 passed; web release build OK; arm64 release APK built (34.4 MB, `foo.nosus.canary`); hardhat 5/5 -for NoSusCanary; deno check OK for the edge function. See `VERIFICATION.md`. diff --git a/docs/canary/VERIFICATION.md b/docs/canary/VERIFICATION.md index c35f072..4e73aa9 100644 --- a/docs/canary/VERIFICATION.md +++ b/docs/canary/VERIFICATION.md @@ -1,27 +1,45 @@ -# How NO SUS Canary was verified (19 Sep 2026) +# Verification log -The reference sources this log describes were merged into `app/` and `contracts/`, and the -`docs/canary/reference/` copies were removed on 22 Sep 2026. The fingerprint harness now lives at -`app/tool/canary_fingerprint_harness.dart`: run `dart run tool/canary_fingerprint_harness.dart` from -`app/` after changing the word list; it must end with `FAILURES: 0`. +Every check below was run on the owner's machine. "Live" rows touched the real devnet backend with +owner approval. -All checks ran on the owner's machine, in a scratch copy of `nosus-monad/app` (the real repo was -not modified). The steps were: copy `app/`, copy the reference files in, run -`tools/canary_edits.js` once, run `flutter pub add qr_flutter image_picker google_mlkit_text_recognition`, -then run the checks below. +## 20 Oct 2026 (branch `chore/judge-ready`) | Check | Command | Result | |---|---|---| -| Static analysis | `flutter analyze` | **No issues found** | -| Full Flutter test suite (existing + 2 new Canary files) | `flutter test` | **All tests passed** (129 passed, 1 skipped) | -| Web release build | `flutter build web --release --base-href /nosus-canary/` (PowerShell) | **OK**. ``; `build/web/CNAME` present → must be deleted before Pages | -| Android release APK | `flutter build apk --release --target-platform android-arm64 --dart-define=WEB_APP_ORIGIN=https://https-shubhamsahu.github.io --dart-define=WEB_APP_BASE_PATH=/nosus-canary --dart-define=NOSUS_ALLOW_SCREEN_CAPTURE=true` (PowerShell) | **Built app-release.apk (34.4 MB)**. `aapt`: package `foo.nosus.canary`, label `NO SUS`, minSdk 24. The first attempt failed in R8 until the ML Kit `-dontwarn` rules were added (now part of `canary_edits.js`) | -| Edit script | `node tools/canary_edits.js` on fresh copies of the 11 target files | `ALL EDITS APPLIED` (tested twice from pristine files) | -| Contract | `npx hardhat test` (Hardhat 3, viem) | **5 passing** for NoSusCanary. Gas: `sealNote` 73,833, `openCopy` 78,403 | -| Edge function | `npx -y deno@2 check index.ts` | **OK**. Resolves `npm:viem@2.56.5` and `esm.sh supabase-js@2.39.8` | -| Fingerprint engine | `dart run tool/canary_fingerprint_harness.dart` (from `app/`) | **FAILURES: 0**. With the 15-slot demo note: full, stripped and OCR-style copies 300/300; 2% character noise 300/300 with 0 wrong names; excerpts 0 wrong out of 600; two-copy blends named an innocent in 1/600 (20 copies), 8/600 (50) and 23/600 (100). A 9-slot note is rejected on purpose | - -**Not verified here** (these need owner-approved live services, so they are done in the plan's -Phases 2–7): deploying to Monad testnet, applying the SQL to `ffidvfguojalzpclipzi`, deploying the -edge function, and the live end-to-end flow. The SQL and the edge-function logic were reviewed but -not executed against a database. +| Static analysis | `flutter analyze` (from `app/`) | No issues found | +| Flutter tests | `flutter test` (from `app/`) | 145 passed, 1 skipped (live-network diagnostic `db_test.dart` removed; `supabase_service_test.dart` stays skipped) | +| Fingerprint harness | `dart run tool/canary_fingerprint_harness.dart` (from `app/`) | `FAILURES: 0` | +| Relayer type-check | `deno check index.ts` (from `app/supabase/functions/canary/`) | Clean | +| Relayer tests | `deno test --allow-env` (same folder) | `gating_test.ts` 7 passed, `solana_test.ts` 5 passed | +| Relayer bundle | `deno bundle --platform=deno app/supabase/functions/canary/index.ts -o /index.ts` | OK, 2.3 MB | +| TS library | `deno check`, `deno lint`, `deno fmt --check`, `deno test` (from `packages/receipts-ts/`) | All clean, 19 passed | +| Dart library | `dart analyze`, `dart format --set-exit-if-changed .`, `dart test` (from `packages/receipts-dart/`) | No issues, 16 passed | +| Secret scan | All 46 commits on 17 refs plus unreachable objects | No secrets; only the Supabase publishable key (public by design) | +| Live end to end | Scripted Chrome on https://shubham-sahu.me/nosus-canary/ at 1280×720: create (10 copies, 1 hour) → Priya and Ben open → dashboard → leak check → Explorer | Sealed in 2.9 s; leak check named "Priya · Copy 1 / 10"; receipts below | +| Relayer redeploy (version 7, uses `packages/receipts-ts`) | `supabase functions deploy canary --no-verify-jwt --use-api` from a bundle; then `create` → `open` → `status` against the live function with a throwaway 2-copy note | All 200; [seal](https://explorer.solana.com/tx/6raNrS3Lccq68vqbmyBJrQqKKMJkiZETc1j9ZLPdXcPr1x2M7qRxgdLem7VD4tsPt1g2WzigJoajioREutkPZ5f?cluster=devnet) and [open](https://explorer.solana.com/tx/3s7bXFakuoDbcuLz6BA13oAXqNmbj71QHuyR31g3m4Q2c3bybFp2Hro4ktTo7Nwq6eHau8z8G7SVK7dEW7AypU8p?cluster=devnet) decode with `cli.ts --note` (match) | + +Receipts from the live run: +[seal](https://explorer.solana.com/tx/QqdiqT84UfFyHNhpfLrK32HfqbUB5vF8qtC4DiAQ7wZZGn2MkUVJGGpVPpgmk4MCxVLtkhmZm6rbuBxqyuL11wb?cluster=devnet), +[Priya's open](https://explorer.solana.com/tx/5TXFPfTDFWyVe98DVPph7r55uRdJAcih6vKMBBRJKA96KtWT7Q4MUoFQG6GwH8N1FFkiMMbZzPssGtqtoW3wAsy2?cluster=devnet), +[Ben's open](https://explorer.solana.com/tx/3tqhYUQ2BppvWh6dy8q5u7U23NpZ7FqfAnd34B58GTriGVZXtykcPj1i4sF7bNh4t8ShnhQokySNz7Uwh7GMTcT1?cluster=devnet). +Two earlier attempts the same day sealed a note each (one also recorded one open) before the +recording script failed; those three memos are harmless test data. + +## 10 Oct 2026 (Solana receipts) + +| Check | Result | +|---|---| +| Spike against devnet (`tool/solana-spike/send_memo.ts`) | Seal [`2BHqnuCx…`](https://explorer.solana.com/tx/2BHqnuCxYyemfegHkncgTsQyMPjpyB9boD1XqYfD1Wtbcf51Fpy3y264UwGhnvRKtcxFKCaSAzHxLrDwFRk512bQ?cluster=devnet) and open [`NwoJauec…`](https://explorer.solana.com/tx/NwoJauec9otkicaGf8yD6UechYgUnXRdYPqnuc5Kpn6uMYym6XVJcMmWdbVnwnRVncKKVgEyuZB2mR3T5REvdSr?cluster=devnet), ~1.1 s each, 5,000 lamports, memo round trip OK | +| Migration `20261010090000_nosus_canary_solana.sql` on `ffidvfguojalzpclipzi` | Applied with `supabase db query --linked --file`; columns and the 7-column `canary_assign_copy` verified; `anon` has no execute | +| Live end to end | Create (10 copies) → 2 opens → dashboard chips → leak check named copy 1 → Explorer memo with hashes only | +| `flutter analyze` / `flutter test` | No issues / 153 passed, 1 skipped | +| `deno check index.ts` / `gating_test.ts` | Clean / 7 passed | + +## 19–22 Sep 2026 (Canary feature) + +| Check | Result | +|---|---| +| Fingerprint harness | `FAILURES: 0` (see the table in [SECURITY.md](../../SECURITY.md#threat-model)) | +| Web release build | `flutter build web --release --base-href /nosus-canary/` OK | +| Android release APK | Built (34.4 MB, package `foo.nosus.canary`, minSdk 24) | diff --git a/docs/media/canary-demo.gif b/docs/media/canary-demo.gif new file mode 100644 index 0000000..e80f892 Binary files /dev/null and b/docs/media/canary-demo.gif differ diff --git a/docs/media/canary-demo.mp4 b/docs/media/canary-demo.mp4 new file mode 100644 index 0000000..5e8a93c Binary files /dev/null and b/docs/media/canary-demo.mp4 differ diff --git a/docs/media/compose.png b/docs/media/compose.png new file mode 100644 index 0000000..cf7cb27 Binary files /dev/null and b/docs/media/compose.png differ diff --git a/docs/media/dashboard.png b/docs/media/dashboard.png new file mode 100644 index 0000000..957d390 Binary files /dev/null and b/docs/media/dashboard.png differ diff --git a/docs/media/explorer-receipt.png b/docs/media/explorer-receipt.png new file mode 100644 index 0000000..7e2a3b9 Binary files /dev/null and b/docs/media/explorer-receipt.png differ diff --git a/docs/media/landing.png b/docs/media/landing.png new file mode 100644 index 0000000..eed9e69 Binary files /dev/null and b/docs/media/landing.png differ diff --git a/docs/media/leak-check.png b/docs/media/leak-check.png new file mode 100644 index 0000000..d5b6c2b Binary files /dev/null and b/docs/media/leak-check.png differ diff --git a/docs/media/reader-copy.png b/docs/media/reader-copy.png new file mode 100644 index 0000000..c9017ed Binary files /dev/null and b/docs/media/reader-copy.png differ diff --git a/packages/receipts-dart/.gitignore b/packages/receipts-dart/.gitignore new file mode 100644 index 0000000..cb3e7cf --- /dev/null +++ b/packages/receipts-dart/.gitignore @@ -0,0 +1 @@ +.dart_tool/ diff --git a/packages/receipts-dart/README.md b/packages/receipts-dart/README.md new file mode 100644 index 0000000..cabb385 --- /dev/null +++ b/packages/receipts-dart/README.md @@ -0,0 +1,91 @@ +# nosus_receipts (Dart) + +Encode, parse and fetch NO SUS Canary receipts. Pure Dart; works in Flutter apps and on the +command line. + +NO SUS Canary gives each reader a uniquely marked copy of a note. Every seal and every open is +written as one SPL Memo transaction on Solana. That memo is the receipt. This package reads and +writes it, so anyone can check a receipt without trusting the NO SUS server. The format is in +[docs/RECEIPTS_SPEC.md](../../docs/RECEIPTS_SPEC.md). + +**Status:** v0.1 · devnet · not yet published to JSR/npm/pub.dev — use a path or git dependency. + +## Install + +Path, from a clone of this repo: + +```yaml +dependencies: + nosus_receipts: + path: ../packages/receipts-dart +``` + +Git: + +```yaml +dependencies: + nosus_receipts: + git: + url: https://github.com/https-shubhamsahu/nosus-canary.git + path: packages/receipts-dart + ref: +``` + +Dependencies: `crypto` and `http` only. Needs Dart 3.13 or newer. + +## Usage + +```dart +import 'package:nosus_receipts/nosus_receipts.dart'; + +final client = SolanaReceiptClient(SolanaCluster.devnet.rpcUrl); +final r = await client.fetch('2BHqnuCxYyemfegHkncgTsQyMPjpyB9boD1XqYfD1Wtbcf51Fpy3y264UwGhnvRKtcxFKCaSAzHxLrDwFRk512bQ'); +client.close(); + +// Is this the receipt for my note? noteId is the UUID in the reader link. +final mine = r.receipt.note == chainNoteId('1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'); +final text = switch (r.receipt) { + SealReceipt(:final copies) => 'sealed, $copies copies', + OpenReceipt(:final copy) => 'copy $copy opened', +}; +print('$text ${explorerTxUrl(r.signature)}'); +``` + +- `SealReceipt` / `OpenReceipt`: `encode()` gives the memo text byte for byte as on chain. The + constructors throw `ReceiptFormatException` on a bad field. +- `ReceiptMemo.parse(memo)`: strict parse, or throws `ReceiptFormatException`. +- `chainNoteId`, `copyDigest`, `copiesHash`, `deviceHash`, `readerTag`: the hashes in the memo. +- `SolanaReceiptClient.fetch(signature)`: one `getTransaction` call. Throws + `ReceiptFetchException` when the transaction is missing, failed, or has no NO SUS memo. +- `explorerTxUrl(signature, cluster: ...)`: Solana Explorer link. + +Sending memos is not in this package. The relayer is TypeScript (`packages/receipts-ts`). + +## CLI + +From `packages/receipts-dart`: + +```sh +dart run bin/verify.dart [--cluster devnet|mainnet-beta] [--rpc URL] [--note ] +``` + +It prints the decoded receipt and its Explorer link. With `--note`, it also checks that the +memo's `note` equals `chainNoteId(uuid)`. Exit codes: 0 ok, 1 receipt error or note mismatch, 2 +bad usage. Same output as the TypeScript CLI. + +## Tests + +From `packages/receipts-dart`: + +```sh +dart pub get +dart analyze +dart format --set-exit-if-changed . +dart test # offline; uses ../test-vectors and saved devnet responses +``` + +The TypeScript package tests against the same vectors in `packages/test-vectors`. + +## License + +Apache-2.0. diff --git a/packages/receipts-dart/analysis_options.yaml b/packages/receipts-dart/analysis_options.yaml new file mode 100644 index 0000000..572dd23 --- /dev/null +++ b/packages/receipts-dart/analysis_options.yaml @@ -0,0 +1 @@ +include: package:lints/recommended.yaml diff --git a/packages/receipts-dart/bin/verify.dart b/packages/receipts-dart/bin/verify.dart new file mode 100644 index 0000000..56f6f1c --- /dev/null +++ b/packages/receipts-dart/bin/verify.dart @@ -0,0 +1,112 @@ +// Verify a NO SUS Canary receipt from the command line: +// dart run bin/verify.dart [--cluster devnet|mainnet-beta] [--rpc URL] [--note ] +// Prints the decoded receipt and its Explorer link. With --note, also checks +// that the memo's note equals sha256("nosus-canary:" + uuid); exit 1 if not. +// Exit codes: 0 ok, 1 receipt error or note mismatch, 2 bad usage. + +import 'dart:io'; + +import 'package:nosus_receipts/nosus_receipts.dart'; + +const _usage = + 'usage: dart run bin/verify.dart ' + '[--cluster devnet|mainnet-beta] [--rpc URL] [--note ]'; +final _uuid = RegExp( + r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$', +); + +Future main(List args) async => exitCode = await _run(args); + +String _time(int seconds) => DateTime.fromMillisecondsSinceEpoch( + seconds * 1000, + isUtc: true, +).toIso8601String().replaceFirst('.000Z', 'Z'); + +Future _run(List args) async { + final opts = {}; + final positional = []; + for (var i = 0; i < args.length; i++) { + final eq = args[i].indexOf('='); + final flag = eq < 0 ? args[i] : args[i].substring(0, eq); + if (flag == '-h' || flag == '--help') { + stdout.writeln(_usage); + return 0; + } + if (!flag.startsWith('-')) { + positional.add(args[i]); + continue; + } + if (!const ['--cluster', '--rpc', '--note'].contains(flag)) { + return _bad('unknown option $flag'); + } + final value = eq >= 0 + ? args[i].substring(eq + 1) + : (++i < args.length ? args[i] : null); + if (value == null) return _bad('$flag needs a value'); + opts[flag.substring(2)] = value; + } + if (positional.length != 1) { + return _bad('give exactly one transaction signature'); + } + final cluster = SolanaCluster.byId(opts['cluster'] ?? 'devnet'); + if (cluster == null) return _bad('--cluster must be devnet or mainnet-beta'); + final note = opts['note']?.toLowerCase(); + if (note != null && !_uuid.hasMatch(note)) { + return _bad('--note must be a note UUID'); + } + + final client = SolanaReceiptClient(opts['rpc'] ?? cluster.rpcUrl); + final FetchedReceipt r; + try { + r = await client.fetch(positional.single); + } on Exception catch (e) { + stderr.writeln( + 'error: ${switch (e) { + ReceiptFetchException(:final message) => message, + FormatException(:final message) => message, + _ => '$e', + }}', + ); + return 1; + } finally { + client.close(); + } + + final rc = r.receipt; + final rows = <(String, Object)>[ + ('signature', r.signature), + ('slot', r.slot), + ('time', r.blockTime == null ? 'unknown' : _time(r.blockTime!)), + ('fee payer', r.feePayer), + ('program', r.memoProgram), + ('note', rc.note), + ...switch (rc) { + SealReceipt(:final copies, :final hash, :final exp) => [ + ('copies', copies), + ('hash', hash), + ('expires', exp == 0 ? 'never (0)' : '${_time(exp)} ($exp)'), + ], + OpenReceipt(:final copy, :final tag) => [('copy', copy), ('tag', tag)], + }, + ('explorer', explorerTxUrl(r.signature, cluster: cluster)), + ]; + stdout.writeln('NO SUS Canary ${rc.type} receipt (format v$receiptVersion)'); + for (final (k, v) in rows) { + stdout.writeln(' ${k.padRight(10)} $v'); + } + + if (note != null) { + final expected = chainNoteId(note); + if (expected != rc.note) { + stderr.writeln('note check: MISMATCH. chainNoteId($note) is $expected'); + return 1; + } + stdout.writeln('note check: ok, sha256("nosus-canary:$note") matches'); + } + return 0; +} + +int _bad(String problem) { + stderr.writeln('$problem\n$_usage'); + return 2; +} diff --git a/packages/receipts-dart/lib/nosus_receipts.dart b/packages/receipts-dart/lib/nosus_receipts.dart new file mode 100644 index 0000000..ebbf80b --- /dev/null +++ b/packages/receipts-dart/lib/nosus_receipts.dart @@ -0,0 +1,8 @@ +/// NO SUS Canary receipts: encode, parse and fetch the SPL Memo that records +/// each seal and each open on Solana. Spec: docs/RECEIPTS_SPEC.md. +library; + +export 'src/client.dart'; +export 'src/explorer.dart'; +export 'src/ids.dart'; +export 'src/memo.dart'; diff --git a/packages/receipts-dart/lib/src/client.dart b/packages/receipts-dart/lib/src/client.dart new file mode 100644 index 0000000..fbb923b --- /dev/null +++ b/packages/receipts-dart/lib/src/client.dart @@ -0,0 +1,177 @@ +// Reads one receipt back from the chain with a plain JSON-RPC getTransaction +// call. + +import 'dart:convert'; + +import 'package:http/http.dart' as http; + +import 'memo.dart'; + +/// A receipt as read from the chain. +class FetchedReceipt { + const FetchedReceipt({ + required this.signature, + required this.slot, + required this.blockTime, + required this.feePayer, + required this.memoProgram, + required this.receipt, + }); + + final String signature; + final int slot; + + /// Unix seconds; null when the node does not know it. + final int? blockTime; + + /// First account key: the relayer that paid for and signed the memo. + final String feePayer; + final String memoProgram; + final ReceiptMemo receipt; +} + +/// The transaction could not be read, or carries no NO SUS Canary receipt. +class ReceiptFetchException implements Exception { + const ReceiptFetchException(this.message); + + final String message; + + @override + String toString() => 'ReceiptFetchException: $message'; +} + +final _signature = RegExp(r'^[1-9A-HJ-NP-Za-km-z]{64,88}$'); +const _base58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; + +class SolanaReceiptClient { + /// [client] is closed by [close] only when this class created it. + SolanaReceiptClient(this.rpcUrl, {http.Client? client}) + : _client = client ?? http.Client(), + _ownsClient = client == null; + + final String rpcUrl; + final http.Client _client; + final bool _ownsClient; + + /// Fetches a transaction and decodes its NO SUS Canary memo. Throws + /// [ReceiptFetchException] when the transaction is missing or failed, has + /// no memo or a foreign memo, and [ReceiptFormatException] when the memo is + /// not exactly format v1. + Future fetch(String signature) async { + if (!_signature.hasMatch(signature)) { + throw const ReceiptFetchException( + 'signature must be a base58 transaction signature', + ); + } + final res = await _client.post( + Uri.parse(rpcUrl), + headers: {'content-type': 'application/json'}, + body: jsonEncode({ + 'jsonrpc': '2.0', + 'id': 1, + 'method': 'getTransaction', + 'params': [ + signature, + { + 'encoding': 'jsonParsed', + 'maxSupportedTransactionVersion': 0, + 'commitment': 'confirmed', + }, + ], + }), + ); + if (res.statusCode < 200 || res.statusCode > 299) { + throw ReceiptFetchException( + 'getTransaction failed: HTTP ${res.statusCode}', + ); + } + final body = jsonDecode(utf8.decode(res.bodyBytes)) as Map; + final error = body['error']; + if (error != null) { + final message = error is Map ? error['message'] : null; + throw ReceiptFetchException( + 'getTransaction failed: ${message ?? 'RPC error'}', + ); + } + + final tx = body['result'] as Map?; + if (tx == null) { + throw ReceiptFetchException( + 'transaction $signature not found on this cluster', + ); + } + final meta = tx['meta'] as Map?; + if (meta?['err'] != null) { + throw ReceiptFetchException('transaction $signature failed on chain'); + } + + final message = + (tx['transaction'] as Map)['message'] + as Map; + final memos = [ + for (final ix in (message['instructions'] as List).cast()) + if (memoProgramIds.contains(ix['programId'])) + (program: ix['programId'] as String, text: _memoText(ix)), + ]; + if (memos.isEmpty) { + throw ReceiptFetchException( + 'transaction $signature has no memo instruction', + ); + } + final ours = memos + .where((m) => m.text.startsWith('{"p":"$receiptProtocol",')) + .toList(); + if (ours.isEmpty) { + throw ReceiptFetchException( + 'transaction $signature memo is not a NO SUS Canary receipt', + ); + } + if (ours.length > 1) { + throw ReceiptFetchException( + 'transaction $signature has more than one NO SUS Canary memo', + ); + } + + final keys = message['accountKeys'] as List; + return FetchedReceipt( + signature: signature, + slot: tx['slot'] as int, + blockTime: tx['blockTime'] as int?, + feePayer: keys.isEmpty ? '' : (keys.first as Map)['pubkey'] as String, + memoProgram: ours.single.program, + receipt: ReceiptMemo.parse(ours.single.text), + ); + } + + void close() { + if (_ownsClient) _client.close(); + } +} + +// RPC nodes decode SPL Memo v1/v3 into `parsed`; other memo programs (p-memo) +// come back as base58 `data`. +String _memoText(Map ix) { + final parsed = ix['parsed']; + if (parsed is String) return parsed; + final data = ix['data']; + if (data is String) { + return utf8.decode(_base58Decode(data), allowMalformed: true); + } + return ''; +} + +List _base58Decode(String text) { + var n = BigInt.zero; + for (final c in text.split('')) { + final digit = _base58.indexOf(c); + if (digit < 0) throw const ReceiptFetchException('memo data is not base58'); + n = n * BigInt.from(58) + BigInt.from(digit); + } + final bytes = []; + for (; n > BigInt.zero; n = n >> 8) { + bytes.add((n & BigInt.from(0xff)).toInt()); + } + // Each leading "1" is a leading zero byte. + final zeros = text.length - text.replaceFirst(RegExp('^1+'), '').length; + return [...List.filled(zeros, 0), ...bytes.reversed]; +} diff --git a/packages/receipts-dart/lib/src/explorer.dart b/packages/receipts-dart/lib/src/explorer.dart new file mode 100644 index 0000000..6d76ca4 --- /dev/null +++ b/packages/receipts-dart/lib/src/explorer.dart @@ -0,0 +1,27 @@ +enum SolanaCluster { + devnet('devnet', 'https://api.devnet.solana.com'), + mainnetBeta('mainnet-beta', 'https://api.mainnet-beta.solana.com'); + + const SolanaCluster(this.id, this.rpcUrl); + + /// The name Solana tools use: 'devnet' or 'mainnet-beta'. + final String id; + + /// Default public RPC endpoint. + final String rpcUrl; + + /// Null for an unknown id. + static SolanaCluster? byId(String id) => + values.where((c) => c.id == id).firstOrNull; +} + +/// Solana Explorer page for a transaction. Mainnet takes no cluster param. +String explorerTxUrl( + String signature, { + SolanaCluster cluster = SolanaCluster.devnet, +}) { + final base = 'https://explorer.solana.com/tx/$signature'; + return cluster == SolanaCluster.mainnetBeta + ? base + : '$base?cluster=${cluster.id}'; +} diff --git a/packages/receipts-dart/lib/src/ids.dart b/packages/receipts-dart/lib/src/ids.dart new file mode 100644 index 0000000..233f11f --- /dev/null +++ b/packages/receipts-dart/lib/src/ids.dart @@ -0,0 +1,36 @@ +// The sha256-based ids and hashes a receipt carries. Inputs are hashed as +// UTF-8 text; outputs are lowercase hex. Same formulas as the Canary app and +// the edge function, so anyone can recompute them. + +import 'dart:convert'; + +import 'package:crypto/crypto.dart'; + +String _sha256Hex(String text) => sha256.convert(utf8.encode(text)).toString(); + +/// The memo `note`: "0x" + sha256("nosus-canary:" + noteId). noteId is a +/// lowercase UUID. +String chainNoteId(String noteId) => '0x${_sha256Hex('nosus-canary:$noteId')}'; + +/// sha256("device:" + deviceId), no 0x. Only ever stored or hashed again, +/// never on chain. +String deviceHash(String deviceId) => _sha256Hex('device:$deviceId'); + +/// The open memo `tag`: +/// `"0x" + sha256(":::")`. +/// tagSalt is the relayer's secret, so only the relayer can recompute it. +String readerTag({ + required String tagSalt, + required String noteId, + required int copyIndex, + required String deviceHash, +}) => '0x${_sha256Hex('$tagSalt:$noteId:$copyIndex:$deviceHash')}'; + +/// Commitment to one copy: `sha256("::")`, no 0x. +String copyDigest(String saltHex, int index, String copyText) => + _sha256Hex('$saltHex:$index:$copyText'); + +/// The seal memo `hash`: "0x" + sha256 of the copy digests joined in copy +/// order. +String copiesHash(List copyDigests) => + '0x${_sha256Hex(copyDigests.join())}'; diff --git a/packages/receipts-dart/lib/src/memo.dart b/packages/receipts-dart/lib/src/memo.dart new file mode 100644 index 0000000..26e7c49 --- /dev/null +++ b/packages/receipts-dart/lib/src/memo.dart @@ -0,0 +1,192 @@ +// NO SUS Canary receipt memo, format v1 (spec: docs/RECEIPTS_SPEC.md). +// +// One SPL Memo per seal and per open. The memo is compact JSON with a fixed +// key order, so the same receipt is always the same bytes: +// {"p":"nosus-canary","v":1,"t":"seal","note":"0x…","copies":N,"hash":"0x…","exp":E} +// {"p":"nosus-canary","v":1,"t":"open","note":"0x…","copy":N,"tag":"0x…"} + +import 'dart:convert'; + +const receiptProtocol = 'nosus-canary'; +const receiptVersion = 1; + +/// Longest memo a single-signer transaction can carry. +const maxMemoBytes = 566; + +/// SPL Memo v3 (Solana Explorer shows the memo text). +const defaultMemoProgram = 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'; + +/// Memo programs a receipt may be written with: SPL Memo v1, v3 and p-memo. +const memoProgramIds = [ + 'Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo', + defaultMemoProgram, + 'Memo4c2pN8afCj432Lb7RMVKi9PbQnnW7ewFFaV3oAH', +]; + +/// A memo or memo field that is not exactly format v1. +class ReceiptFormatException extends FormatException { + const ReceiptFormatException(super.message); + + @override + String toString() => 'ReceiptFormatException: $message'; +} + +final _bytes32 = RegExp(r'^0x[0-9a-f]{64}$'); +const _maxSafeInteger = 9007199254740991; +const _sealKeys = 'p,v,t,note,copies,hash,exp'; +const _openKeys = 'p,v,t,note,copy,tag'; + +String _checkBytes32(String name, Object? value) { + if (value is String && _bytes32.hasMatch(value)) return value; + throw ReceiptFormatException('memo $name must be 0x + 64 hex chars'); +} + +// Safe integers only (2^53 - 1, as in JavaScript), so every encoded memo +// parses back to the same bytes in both packages. 3.0 passes here and is +// rejected later as not canonical, exactly like the TypeScript parser. +int _checkUint(String name, Object? value) { + if (value is num && + value >= 0 && + value <= _maxSafeInteger && + value == value.truncate()) { + return value.toInt(); + } + throw ReceiptFormatException('memo $name must be a non-negative integer'); +} + +/// One receipt: a [SealReceipt] or an [OpenReceipt]. +sealed class ReceiptMemo { + const ReceiptMemo(); + + /// Strict parse: accepts only the exact bytes [encode] would write. Throws + /// [ReceiptFormatException] otherwise. + factory ReceiptMemo.parse(String memo) { + if (utf8.encode(memo).length > maxMemoBytes) { + throw const ReceiptFormatException( + 'memo is longer than $maxMemoBytes bytes', + ); + } + final Object? m; + try { + m = jsonDecode(memo); + } on FormatException { + throw const ReceiptFormatException('memo is not JSON'); + } + if (m is! Map) { + throw const ReceiptFormatException('memo is not a JSON object'); + } + if (m['p'] != receiptProtocol) { + throw const ReceiptFormatException('memo p must be "$receiptProtocol"'); + } + if (m['v'] != receiptVersion) { + throw const ReceiptFormatException('memo v must be $receiptVersion'); + } + final t = m['t']; + if (t != 'seal' && t != 'open') { + throw const ReceiptFormatException('memo t must be "seal" or "open"'); + } + + final keys = t == 'seal' ? _sealKeys : _openKeys; + if (m.keys.join(',') != keys) { + throw ReceiptFormatException('memo keys must be $keys in this order'); + } + + final ReceiptMemo receipt = t == 'seal' + ? SealReceipt( + note: _checkBytes32('note', m['note']), + copies: _checkUint('copies', m['copies']), + hash: _checkBytes32('hash', m['hash']), + exp: _checkUint('exp', m['exp']), + ) + : OpenReceipt( + note: _checkBytes32('note', m['note']), + copy: _checkUint('copy', m['copy']), + tag: _checkBytes32('tag', m['tag']), + ); + // Catches whitespace, 3.0 / 3e0, duplicate keys and anything else that + // jsonDecode forgives. + if (receipt.encode() != memo) { + throw const ReceiptFormatException('memo is not in canonical form'); + } + return receipt; + } + + /// 'seal' or 'open', the memo's `t`. + String get type; + + /// The memo `note`: [chainNoteId] of the note. + String get note; + + /// The exact memo text written on chain. + String encode(); +} + +/// A sealed note: [copies] marked copies committed to by [hash]. +final class SealReceipt extends ReceiptMemo { + /// Throws [ReceiptFormatException] on a bad field. + SealReceipt({ + required this.note, + required this.copies, + required this.hash, + required this.exp, + }) { + _checkBytes32('note', note); + _checkUint('copies', copies); + _checkBytes32('hash', hash); + _checkUint('exp', exp); + } + + @override + final String note; + final int copies; + + /// [copiesHash] of the copy digests. + final String hash; + + /// Unix seconds; 0 when the note never expires. + final int exp; + + @override + String get type => 'seal'; + + @override + String encode() => jsonEncode({ + 'p': receiptProtocol, + 'v': receiptVersion, + 't': 'seal', + 'note': note, + 'copies': copies, + 'hash': hash, + 'exp': exp, + }); +} + +/// One opened copy: copy number [copy], reader [tag]. +final class OpenReceipt extends ReceiptMemo { + /// Throws [ReceiptFormatException] on a bad field. + OpenReceipt({required this.note, required this.copy, required this.tag}) { + _checkBytes32('note', note); + _checkUint('copy', copy); + _checkBytes32('tag', tag); + } + + @override + final String note; + final int copy; + + /// [readerTag] for the device that opened the copy. + final String tag; + + @override + String get type => 'open'; + + @override + String encode() => jsonEncode({ + 'p': receiptProtocol, + 'v': receiptVersion, + 't': 'open', + 'note': note, + 'copy': copy, + 'tag': tag, + }); +} diff --git a/packages/receipts-dart/pubspec.lock b/packages/receipts-dart/pubspec.lock new file mode 100644 index 0000000..3b86631 --- /dev/null +++ b/packages/receipts-dart/pubspec.lock @@ -0,0 +1,413 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "48e48f73a431eb269eec66d243a63a07ed90ef9417a74047a3b98d52338626ad" + url: "https://pub.dev" + source: hosted + version: "109.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "6d377901d198536b648172974d9d4f277910502cad92193466869cac0ff34990" + url: "https://pub.dev" + source: hosted + version: "14.5.0" + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + async: + dependency: transitive + description: + name: async + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 + url: "https://pub.dev" + source: hosted + version: "2.13.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + cli_config: + dependency: transitive + description: + name: cli_config + sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec + url: "https://pub.dev" + source: hosted + version: "0.2.0" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: "89b8801ba49f8b593fbf2d3e59efd0f566c46cd4ba6837ae2610c72b52a0f899" + url: "https://pub.dev" + source: hosted + version: "0.6.0" + collection: + dependency: transitive + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + coverage: + dependency: transitive + description: + name: coverage + sha256: ff89e37c19355194e279d26dafe8e4bece46c9ea63a30be4dc68214f5bc290d3 + url: "https://pub.dev" + source: hosted + version: "1.16.0" + crypto: + dependency: "direct main" + description: + name: crypto + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + url: "https://pub.dev" + source: hosted + version: "3.0.7" + ffi: + dependency: transitive + description: + name: ffi + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: "404dbf9bce29beafbe9dcb19219447b6f7d49900cd42b8d3b7af102b24508e25" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + glob: + dependency: transitive + description: + name: glob + sha256: "218aeb56050c714f62a3182775320dfa04602b55074873e24e31bbd39bda96fb" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + http: + dependency: "direct main" + description: + name: http + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" + url: "https://pub.dev" + source: hosted + version: "1.6.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://pub.dev" + source: hosted + version: "3.2.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" + io: + dependency: transitive + description: + name: io + sha256: "2635216ca6a737e60de577ffa1a48a0bec76ca8a62917cfc1bb88c14c570646f" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + lints: + dependency: "direct dev" + description: + name: lints + sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" + url: "https://pub.dev" + source: hosted + version: "6.1.0" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" + url: "https://pub.dev" + source: hosted + version: "0.12.20" + meta: + dependency: transitive + description: + name: meta + sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9" + url: "https://pub.dev" + source: hosted + version: "1.19.0" + mime: + dependency: transitive + description: + name: mime + sha256: bd47de35f07e27267e69c8c8b22edf9473bfee170a60d60fcc93730c5144b7f6 + url: "https://pub.dev" + source: hosted + version: "2.1.0" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + package_config: + dependency: transitive + description: + name: package_config + sha256: ffcf4cf3d6c0b74ac43708d9f56625506e8a68aa935abe9d267a7330f320eb5d + url: "https://pub.dev" + source: hosted + version: "3.0.0" + path: + dependency: transitive + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + pool: + dependency: transitive + description: + name: pool + sha256: "4177f68c237ea2128d1bee66ac17b2ce05ba3dbaafcbdd54c5d40a39d0b6b11c" + url: "https://pub.dev" + source: hosted + version: "1.5.3" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "261236774e8b1d69cfc6b9eabbc96c40f25e7a2d6b171f3385d4f65d5734fb24" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: e75e9cf311d7fd712048038cc17c25199c38536c20330d53e7db058b543d5a48 + url: "https://pub.dev" + source: hosted + version: "1.4.3" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: "480504af9e5323899c5be26a4f6c2fc4437d50954d39842f0290f4ae733d57b4" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "14c2945847669b44089bb1222f66873d7ff7103c58911917f2a63c5a62327898" + url: "https://pub.dev" + source: hosted + version: "0.10.14" + source_span: + dependency: transitive + description: + name: source_span + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" + url: "https://pub.dev" + source: hosted + version: "1.10.2" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "277654b3034d17ac6f9f1cb5595db011b1d5d41e8806866db28e0abaa101c490" + url: "https://pub.dev" + source: hosted + version: "1.12.2" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test: + dependency: "direct dev" + description: + name: test + sha256: "44b2fccf4407bcdb5e105c064c5d6b5e2a640c87761f8b03cdce8cf532d98cfa" + url: "https://pub.dev" + source: hosted + version: "1.33.0" + test_api: + dependency: transitive + description: + name: test_api + sha256: "47481c58bb92d0b1d218f0510ff5647e768f8e1256d07077a151fb520923b51d" + url: "https://pub.dev" + source: hosted + version: "0.7.15" + test_core: + dependency: transitive + description: + name: test_core + sha256: "9dec4c178bd61493e1cd2060ffe701fcb61c43da2493e99590fb1b0cc82eb4af" + url: "https://pub.dev" + source: hosted + version: "0.6.21" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "89b11d62e1040ee681af3b4f1c97a803ecbf010c6e8b9c5896ee5b08c3bf7b78" + url: "https://pub.dev" + source: hosted + version: "15.4.0" + watcher: + dependency: transitive + description: + name: watcher + sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + url: "https://pub.dev" + source: hosted + version: "3.0.3" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: f67cdd8e07d3c6329146aaef1ba043542b3134c12489f553ca9a7435d1068aea + url: "https://pub.dev" + source: hosted + version: "3.1.4" +sdks: + dart: ">=3.13.0 <4.0.0" diff --git a/packages/receipts-dart/pubspec.yaml b/packages/receipts-dart/pubspec.yaml new file mode 100644 index 0000000..f46a831 --- /dev/null +++ b/packages/receipts-dart/pubspec.yaml @@ -0,0 +1,17 @@ +name: nosus_receipts +description: >- + Encode, parse and fetch NO SUS Canary receipts: the SPL Memo that records + each seal and each open on Solana. +version: 0.1.0 +publish_to: none + +environment: + sdk: ^3.13.0 + +dependencies: + crypto: ^3.0.6 + http: ^1.2.0 + +dev_dependencies: + lints: ^6.1.0 + test: ^1.31.1 diff --git a/packages/receipts-dart/test/client_test.dart b/packages/receipts-dart/test/client_test.dart new file mode 100644 index 0000000..6759f18 --- /dev/null +++ b/packages/receipts-dart/test/client_test.dart @@ -0,0 +1,174 @@ +// SolanaReceiptClient against saved devnet getTransaction responses. Offline: +// the http client is a MockClient and never reaches the network. +import 'dart:convert'; + +import 'package:http/http.dart' as http; +import 'package:http/testing.dart'; +import 'package:nosus_receipts/nosus_receipts.dart'; +import 'package:test/test.dart'; + +import 'vectors.dart'; + +const _rpc = 'http://rpc.test'; + +/// Answers every request with [body] and records the request bodies. +(SolanaReceiptClient, List) _client(Object? body, {int status = 200}) { + final requests = []; + final mock = MockClient((req) async { + expect(req.url.toString(), _rpc); + requests.add(jsonDecode(req.body)); + return http.Response(jsonEncode(body), status); + }); + return (SolanaReceiptClient(_rpc, client: mock), requests); +} + +Map get _seal => + readVector((section('devnet').first)['fixture'] as String); + +/// A copy of the seal fixture with its single instruction replaced. +Map _withInstruction(Object ix) { + final copy = _seal; + ((copy['result'] as Map)['transaction'] as Map)['message']['instructions'] = [ + ix, + ]; + return copy; +} + +Matcher _fails(String message) => + throwsA(isA().having((e) => '$e', 'message', contains(message))); + +void main() { + final sig = section('devnet').first['signature'] as String; + + test('fetch decodes every real devnet receipt', () async { + for (final v in section('devnet')) { + final (client, _) = _client(readVector(v['fixture'] as String)); + final r = await client.fetch(v['signature'] as String); + expect(r.signature, v['signature']); + expect(r.slot, v['slot']); + expect(r.blockTime, v['blockTime']); + expect(r.feePayer, v['feePayer']); + expect(r.memoProgram, v['memoProgram']); + expect(r.receipt.encode(), v['memo']); + } + }); + + test('fetch sends one jsonParsed getTransaction at confirmed', () async { + final (client, requests) = _client(_seal); + await client.fetch(sig); + expect(requests, [ + { + 'jsonrpc': '2.0', + 'id': 1, + 'method': 'getTransaction', + 'params': [ + sig, + { + 'encoding': 'jsonParsed', + 'maxSupportedTransactionVersion': 0, + 'commitment': 'confirmed', + }, + ], + }, + ]); + }); + + test( + 'fetch reads base58 data from memo programs the node does not parse', + () async { + final raw = vectors['rawMemoInstruction'] as Map; + final (client, _) = _client( + _withInstruction({ + 'accounts': [section('devnet').first['feePayer']], + 'data': raw['data'], + 'programId': raw['programId'], + 'stackHeight': 1, + }), + ); + final r = await client.fetch(sig); + expect(r.memoProgram, raw['programId']); + expect(r.receipt.encode(), raw['memo']); + }, + ); + + test('fetch errors', () async { + final memoIx = Map.from( + (((_seal['result'] as Map)['transaction'] as Map)['message'] + as Map)['instructions'][0] + as Map, + ); + final failed = _seal; + (failed['result'] as Map)['meta']['err'] = { + 'InstructionError': [0, 'Custom'], + }; + final twice = _seal; + ((twice['result'] as Map)['transaction'] as Map)['message']['instructions'] + .add(memoIx); + final v2 = section('invalidMemos').firstWhere((v) => v['name'] == 'v=2'); + + final cases = <(Object?, int, Matcher)>[ + ( + {'jsonrpc': '2.0', 'result': null, 'id': 1}, + 200, + _fails( + 'transaction $sig not found on this cluster', + ), + ), + ( + { + 'jsonrpc': '2.0', + 'error': {'code': -32602, 'message': 'Invalid param'}, + 'id': 1, + }, + 200, + _fails('getTransaction failed: Invalid param'), + ), + ({}, 503, _fails('HTTP 503')), + ( + failed, + 200, + _fails('transaction $sig failed on chain'), + ), + ( + _withInstruction({ + 'parsed': {'type': 'transfer', 'info': {}}, + 'program': 'system', + 'programId': '11111111111111111111111111111111', + }), + 200, + _fails( + 'transaction $sig has no memo instruction', + ), + ), + ( + _withInstruction({...memoIx, 'parsed': 'gm'}), + 200, + _fails( + 'transaction $sig memo is not a NO SUS Canary receipt', + ), + ), + ( + twice, + 200, + _fails('more than one NO SUS Canary memo'), + ), + ( + _withInstruction({...memoIx, 'parsed': v2['memo']}), + 200, + _fails(v2['error'] as String), + ), + ]; + for (final (body, status, matcher) in cases) { + final (client, _) = _client(body, status: status); + await expectLater(client.fetch(sig), matcher); + } + + final (client, _) = _client({}); + await expectLater( + client.fetch('not a signature!'), + _fails( + 'signature must be a base58 transaction signature', + ), + ); + }); +} diff --git a/packages/receipts-dart/test/ids_test.dart b/packages/receipts-dart/test/ids_test.dart new file mode 100644 index 0000000..8f9416d --- /dev/null +++ b/packages/receipts-dart/test/ids_test.dart @@ -0,0 +1,66 @@ +import 'package:nosus_receipts/nosus_receipts.dart'; +import 'package:test/test.dart'; + +import 'vectors.dart'; + +void main() { + test('chainNoteId', () { + for (final v in section('chainNoteId')) { + expect(chainNoteId(v['noteId'] as String), v['expected']); + } + }); + + test('deviceHash', () { + for (final v in section('deviceHash')) { + expect(deviceHash(v['deviceId'] as String), v['expected']); + } + }); + + test('copyDigest hashes the copy text as UTF-8', () { + for (final v in section('copyDigest')) { + expect( + copyDigest( + v['saltHex'] as String, + v['index'] as int, + v['copyText'] as String, + ), + v['expected'], + ); + } + }); + + test('copiesHash', () { + for (final v in section('copiesHash')) { + expect(copiesHash((v['digests'] as List).cast()), v['expected']); + } + }); + + test('readerTag', () { + for (final v in section('readerTag')) { + expect( + readerTag( + tagSalt: v['tagSalt'] as String, + noteId: v['noteId'] as String, + copyIndex: v['copyIndex'] as int, + deviceHash: v['deviceHash'] as String, + ), + v['expected'], + ); + } + }); + + test('explorerTxUrl: devnet has a cluster param, mainnet has none', () { + for (final v in section('explorerTxUrl')) { + final cluster = SolanaCluster.byId(v['cluster'] as String)!; + expect( + explorerTxUrl(v['signature'] as String, cluster: cluster), + v['expected'], + ); + } + expect( + explorerTxUrl('abc'), + 'https://explorer.solana.com/tx/abc?cluster=devnet', + ); + expect(SolanaCluster.byId('testnet'), isNull); + }); +} diff --git a/packages/receipts-dart/test/memo_test.dart b/packages/receipts-dart/test/memo_test.dart new file mode 100644 index 0000000..d754532 --- /dev/null +++ b/packages/receipts-dart/test/memo_test.dart @@ -0,0 +1,95 @@ +import 'dart:convert'; + +import 'package:nosus_receipts/nosus_receipts.dart'; +import 'package:test/test.dart'; + +import 'vectors.dart'; + +SealReceipt _seal(Map i) => SealReceipt( + note: i['note'] as String, + copies: i['copies'] as int, + hash: i['hash'] as String, + exp: i['exp'] as int, +); + +OpenReceipt _open(Map i) => OpenReceipt( + note: i['note'] as String, + copy: i['copy'] as int, + tag: i['tag'] as String, +); + +void main() { + test('seal memos encode to the exact vector bytes and parse back', () { + for (final v in section('sealMemo')) { + final input = v['input'] as Map; + expect(_seal(input).encode(), v['memo'], reason: v['name'] as String); + final parsed = ReceiptMemo.parse(v['memo'] as String) as SealReceipt; + expect( + [parsed.type, parsed.note, parsed.copies, parsed.hash, parsed.exp], + ['seal', input['note'], input['copies'], input['hash'], input['exp']], + ); + } + }); + + test('open memos encode to the exact vector bytes and parse back', () { + for (final v in section('openMemo')) { + final input = v['input'] as Map; + expect(_open(input).encode(), v['memo'], reason: v['name'] as String); + final parsed = ReceiptMemo.parse(v['memo'] as String) as OpenReceipt; + expect( + [parsed.type, parsed.note, parsed.copy, parsed.tag], + ['open', input['note'], input['copy'], input['tag']], + ); + } + }); + + test('the largest memo today is 219 bytes', () { + final sizes = [ + ...section('sealMemo'), + ...section('openMemo'), + ].map((v) => utf8.encode(v['memo'] as String).length); + expect(sizes.reduce((a, b) => a > b ? a : b), 219); + expect(maxMemoBytes, vectors['maxMemoBytes']); + }); + + test('constructors reject bad fields with the shared messages', () { + for (final v in section('encodeErrors')) { + final input = v['input'] as Map; + expect( + () => v['kind'] == 'seal' ? _seal(input) : _open(input), + throwsA( + isA().having( + (e) => e.message, + 'message', + v['error'], + ), + ), + reason: v['name'] as String, + ); + } + }); + + test('parse rejects every invalid vector with the shared message', () { + for (final v in section('invalidMemos')) { + expect( + () => ReceiptMemo.parse(v['memo'] as String), + throwsA( + isA().having( + (e) => e.message, + 'message', + v['error'], + ), + ), + reason: v['name'] as String, + ); + } + }); + + test('memo program ids', () { + expect(memoProgramIds, contains(defaultMemoProgram)); + expect( + memoProgramIds, + contains((vectors['rawMemoInstruction'] as Map)['programId']), + ); + }); +} diff --git a/packages/receipts-dart/test/vectors.dart b/packages/receipts-dart/test/vectors.dart new file mode 100644 index 0000000..11a5b2b --- /dev/null +++ b/packages/receipts-dart/test/vectors.dart @@ -0,0 +1,13 @@ +import 'dart:convert'; +import 'dart:io'; + +/// The shared vectors in packages/test-vectors. `dart test` runs from the +/// package root. +final Map vectors = readVector('receipts.json'); + +Map readVector(String path) => + jsonDecode(File('../test-vectors/$path').readAsStringSync()) + as Map; + +List> section(String name) => + (vectors[name] as List).cast>(); diff --git a/packages/receipts-ts/README.md b/packages/receipts-ts/README.md new file mode 100644 index 0000000..66bec65 --- /dev/null +++ b/packages/receipts-ts/README.md @@ -0,0 +1,82 @@ +# @nosus/receipts (TypeScript) + +Encode, parse, send and fetch NO SUS Canary receipts. + +NO SUS Canary gives each reader a uniquely marked copy of a note. Every seal and every open is +written as one SPL Memo transaction on Solana. That memo is the receipt. This package reads and +writes it, so anyone can check a receipt without trusting the NO SUS server. The format is in +[docs/RECEIPTS_SPEC.md](../../docs/RECEIPTS_SPEC.md). + +**Status:** v0.1 · devnet · not yet published to JSR/npm/pub.dev — use a path or git dependency. + +## Install + +Path, from a clone of this repo: + +```ts +import { fetchReceipt } from "./packages/receipts-ts/mod.ts"; +``` + +Git, pinned to a commit: + +```ts +import { fetchReceipt } from "https://raw.githubusercontent.com/https-shubhamsahu/nosus-canary//packages/receipts-ts/mod.ts"; +``` + +Dependencies are pinned inline (`npm:@solana/kit@8.4.0`, `npm:@solana-program/memo@0.15.0`), so no +import map is needed. Only `sendMemo` uses them. `@solana/kit` pulls in `ws`, which reads +`WS_NO_BUFFER_UTIL` and `WS_NO_UTF_8_VALIDATE` when it loads, so a program that imports `mod.ts` +needs `--allow-env` for those two names. + +## Usage + +```ts +import { chainNoteId, encodeOpenMemo, explorerTxUrl, fetchReceipt } from "./mod.ts"; + +const sig = + "2BHqnuCxYyemfegHkncgTsQyMPjpyB9boD1XqYfD1Wtbcf51Fpy3y264UwGhnvRKtcxFKCaSAzHxLrDwFRk512bQ"; +const { receipt, feePayer } = await fetchReceipt(sig); // devnet unless you pass rpcUrl +console.log(receipt.t, receipt.note, feePayer, explorerTxUrl(sig)); + +// Is this the receipt for my note? noteId is the UUID in the reader link. +const mine = receipt.note === await chainNoteId("1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"); + +// Build a memo. Throws ReceiptFormatError on a bad field. +const memo = encodeOpenMemo({ note: receipt.note, copy: 0, tag: "0x" + "ab".repeat(32) }); +``` + +| Export | What it does | +| -------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `encodeSealMemo`, `encodeOpenMemo` | Memo text, byte for byte as on chain. | +| `parseReceiptMemo` | Strict parse to `SealReceipt` or `OpenReceipt`, or throws. | +| `chainNoteId`, `copyDigest`, `copiesHash`, `deviceHash`, `readerTag` | The hashes in the memo (async, WebCrypto). | +| `fetchReceipt` | One `getTransaction` call; returns slot, time, fee payer, receipt. | +| `explorerTxUrl` | Solana Explorer link for a signature. | +| `parseRelayerKeys`, `sendMemo` | Relayer side: parse keys and send a memo. Needs funded devnet keys. | + +## CLI + +```sh +deno run --allow-net packages/receipts-ts/cli.ts [--cluster devnet|mainnet-beta] [--rpc URL] [--note ] +``` + +It prints the decoded receipt and its Explorer link. With `--note`, it also checks that the memo's +`note` equals `chainNoteId(uuid)`. Exit codes: 0 ok, 1 receipt error or note mismatch, 2 bad usage. +The CLI does not load `@solana/kit`, so `--allow-net` is the only permission. + +## Tests + +From `packages/receipts-ts`: + +```sh +deno test # offline; uses ../test-vectors and saved devnet responses +deno check +deno lint +deno fmt --check +``` + +The Dart package tests against the same vectors in `packages/test-vectors`. + +## License + +Apache-2.0. diff --git a/packages/receipts-ts/cli.ts b/packages/receipts-ts/cli.ts new file mode 100644 index 0000000..6826504 --- /dev/null +++ b/packages/receipts-ts/cli.ts @@ -0,0 +1,89 @@ +// Verify a NO SUS Canary receipt from the command line: +// deno run --allow-net cli.ts [--cluster devnet|mainnet-beta] [--rpc URL] [--note ] +// Prints the decoded receipt and its Explorer link. With --note, also checks +// that the memo's note equals sha256("nosus-canary:" + uuid); exit 1 if not. +// Exit codes: 0 ok, 1 receipt error or note mismatch, 2 bad usage. + +import { chainNoteId } from "./src/ids.ts"; +import { type Cluster, DEFAULT_RPC_URLS, explorerTxUrl } from "./src/explorer.ts"; +import { type FetchedReceipt, fetchReceipt } from "./src/fetch.ts"; + +const USAGE = + "usage: cli.ts [--cluster devnet|mainnet-beta] [--rpc URL] [--note ]"; +const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/; + +function time(seconds: number): string { + return new Date(seconds * 1000).toISOString().replace(".000Z", "Z"); +} + +async function main(args: string[]): Promise { + const opts: Record = {}; + const positional: string[] = []; + for (let i = 0; i < args.length; i++) { + const [flag, inline] = args[i].split(/=(.*)/s); + if (flag === "-h" || flag === "--help") { + console.log(USAGE); + return 0; + } + if (!flag.startsWith("-")) { + positional.push(args[i]); + continue; + } + if (!["--cluster", "--rpc", "--note"].includes(flag)) return usage(`unknown option ${flag}`); + const value = inline ?? args[++i]; + if (value === undefined) return usage(`${flag} needs a value`); + opts[flag.slice(2)] = value; + } + if (positional.length !== 1) return usage("give exactly one transaction signature"); + const cluster = (opts.cluster ?? "devnet") as Cluster; + if (!Object.hasOwn(DEFAULT_RPC_URLS, cluster)) { + return usage("--cluster must be devnet or mainnet-beta"); + } + const note = opts.note?.toLowerCase(); + if (note !== undefined && !UUID_RE.test(note)) return usage("--note must be a note UUID"); + + const signature = positional[0]; + let r: FetchedReceipt; + try { + r = await fetchReceipt(signature, { rpcUrl: opts.rpc ?? DEFAULT_RPC_URLS[cluster] }); + } catch (e) { + console.error(`error: ${e instanceof Error ? e.message : String(e)}`); + return 1; + } + + const rc = r.receipt; + const rows: [string, string | number][] = [ + ["signature", r.signature], + ["slot", r.slot], + ["time", r.blockTime === null ? "unknown" : time(r.blockTime)], + ["fee payer", r.feePayer], + ["program", r.memoProgram], + ["note", rc.note], + ]; + if (rc.t === "seal") { + rows.push(["copies", rc.copies], ["hash", rc.hash]); + rows.push(["expires", rc.exp === 0 ? "never (0)" : `${time(rc.exp)} (${rc.exp})`]); + } else { + rows.push(["copy", rc.copy], ["tag", rc.tag]); + } + rows.push(["explorer", explorerTxUrl(r.signature, cluster)]); + console.log(`NO SUS Canary ${rc.t} receipt (format v${rc.v})`); + for (const [k, v] of rows) console.log(` ${k.padEnd(10)} ${v}`); + + if (note !== undefined) { + const expected = await chainNoteId(note); + if (expected !== rc.note) { + console.error(`note check: MISMATCH. chainNoteId(${note}) is ${expected}`); + return 1; + } + console.log(`note check: ok, sha256("nosus-canary:${note}") matches`); + } + return 0; +} + +function usage(problem: string): number { + console.error(`${problem}\n${USAGE}`); + return 2; +} + +if (import.meta.main) Deno.exit(await main(Deno.args)); diff --git a/packages/receipts-ts/deno.json b/packages/receipts-ts/deno.json new file mode 100644 index 0000000..a512426 --- /dev/null +++ b/packages/receipts-ts/deno.json @@ -0,0 +1,30 @@ +{ + "name": "@nosus/receipts", + "version": "0.1.0", + "license": "Apache-2.0", + "exports": "./mod.ts", + "tasks": { + "test": "deno test", + "check": "deno check mod.ts cli.ts test/", + "lint": "deno lint", + "fmt": "deno fmt --check" + }, + "fmt": { + "lineWidth": 100 + }, + "lint": { + "rules": { + "exclude": [ + "no-import-prefix" + ] + } + }, + "publish": { + "include": [ + "mod.ts", + "cli.ts", + "src/", + "README.md" + ] + } +} diff --git a/packages/receipts-ts/deno.lock b/packages/receipts-ts/deno.lock new file mode 100644 index 0000000..8371be9 --- /dev/null +++ b/packages/receipts-ts/deno.lock @@ -0,0 +1,472 @@ +{ + "version": "5", + "specifiers": { + "jsr:@std/assert@1.0.19": "1.0.19", + "jsr:@std/internal@^1.0.12": "1.0.14", + "npm:@solana-program/memo@0.15.0": "0.15.0_@solana+kit@8.4.0", + "npm:@solana/kit@8.4.0": "8.4.0" + }, + "jsr": { + "@std/assert@1.0.19": { + "integrity": "eaada96ee120cb980bc47e040f82814d786fe8162ecc53c91d8df60b8755991e", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/internal@1.0.14": { + "integrity": "291516b3d4c35024d6ffbc0a9df5bf4c64116e05b50012cf846710152d2ffdf7" + } + }, + "npm": { + "@solana-program/memo@0.15.0_@solana+kit@8.4.0": { + "integrity": "sha512-OofePobs2d+mZpCYq/dJ1Mv4//TVBHiYZN1is9CfsrkuMJboVK3ghv9T1bzdbM4OcywGLEyvZ4HjCByfg3RWwg==", + "dependencies": [ + "@solana/kit" + ] + }, + "@solana/accounts@8.4.0": { + "integrity": "sha512-YklERWeG5UD2fzxR0zwWgzCVyuHRqg6eTIyGBAe8hOWIim8TYS1aPBVFAlVkSZiAXaFRxmu1E3IRfeCe/QSQmg==", + "dependencies": [ + "@solana/addresses", + "@solana/codecs-core", + "@solana/codecs-strings", + "@solana/errors", + "@solana/rpc-spec", + "@solana/rpc-types" + ] + }, + "@solana/addresses@8.4.0": { + "integrity": "sha512-5nF1AAaCtmaSEHcFIIs6TPMIWplaYBxeJ2ZR0z5oPIY+fjpWb9lxCuJyYQxYKHIvp4OdSiueW0q11yXrnyqM+A==", + "dependencies": [ + "@solana/assertions", + "@solana/codecs-core", + "@solana/codecs-strings", + "@solana/errors", + "@solana/nominal-types" + ] + }, + "@solana/assertions@8.4.0": { + "integrity": "sha512-Pg/PKw/fA+KIHp6X6aGx4fIkr6S7k7wUw7v8Rkr3TkY4tzrbjZDnXEgv1/8dxGh+IX3UNb+5stD8rtAAscxW1g==", + "dependencies": [ + "@solana/errors" + ] + }, + "@solana/codecs-core@8.4.0": { + "integrity": "sha512-HOsIB3Ic/qnlXv4V0Q5gpxFxBy5pBiINpEMtCzGtHRnj7mI3Amsh8HKR7x9nbP1SBDuDlOrP/Mds9yIqyKn8TQ==", + "dependencies": [ + "@solana/errors" + ] + }, + "@solana/codecs-data-structures@8.4.0": { + "integrity": "sha512-qx9EnKGZzpiNonUoYNMZC4gfw86jfu4uShh0bcWb1o9dPU1kgZ/xCsCgTRf/5WEPZU2fbPNGtvVMr4dKWCTjzw==", + "dependencies": [ + "@solana/codecs-core", + "@solana/codecs-numbers", + "@solana/errors" + ] + }, + "@solana/codecs-numbers@8.4.0": { + "integrity": "sha512-A9SlaBylkTFjtBiVrFUX3We5SZK4L/Q6SKpPyazZQ1MTCO0FyTuKyZwDART2Pzg+C/5xLWjSns+FSTR8FhD/Rg==", + "dependencies": [ + "@solana/codecs-core", + "@solana/errors" + ] + }, + "@solana/codecs-strings@8.4.0": { + "integrity": "sha512-jQhRrJT3ZoeDoSA5DtGxPmI5ODJi3STTCrtIXIniLr1J1cXUSlPfYe8BKOurNwC+SlEJyRmKfpVze+qeLacmmw==", + "dependencies": [ + "@solana/codecs-core", + "@solana/codecs-numbers", + "@solana/errors" + ] + }, + "@solana/codecs@8.4.0": { + "integrity": "sha512-mY7CpMQ4nbecxQIyvslEw7nEreiY0QVvg+aZOPbrBjIiZxu2qj9fyhCrDXJdQlcJ+aYh1sInbR8KARpmHgJLQg==", + "dependencies": [ + "@solana/codecs-core", + "@solana/codecs-data-structures", + "@solana/codecs-numbers", + "@solana/codecs-strings", + "@solana/fixed-points", + "@solana/options" + ] + }, + "@solana/errors@8.4.0": { + "integrity": "sha512-t59ageeK8xa6LrCzj93QEhYtVr5t3GdnTH3qJMGqrCFMYM6IvNFLljlz4N75X+xYktj3sRABTrNoCfekeQlckA==", + "dependencies": [ + "chalk", + "commander" + ], + "bin": true + }, + "@solana/fast-stable-stringify@8.4.0": { + "integrity": "sha512-XKVKeocf0T9hjmUHKrOG+exxfZmv+IPQrdkvuTdegyB6V5X4aOlR6IfrJQiTMsJx6IY4EAW3aisxTgZmH5OlYg==" + }, + "@solana/fixed-points@8.4.0": { + "integrity": "sha512-YzWZDPn3B6o3j+leuOhxH7Soip12NJVx5lJaRpEeBB4AcJczTiKGCQMSsxQglGSRHc0jwfrH4+Uxla1BlCkgBg==", + "dependencies": [ + "@solana/codecs-core", + "@solana/errors" + ] + }, + "@solana/functional@8.4.0": { + "integrity": "sha512-q5pEoqAtEGFsJXK3mnlemLinzRJHvOMjGmuLoWU6c33NQHjfpTEz80hjnRA25BABMLC0l/vhymeLh+YhUv/szw==" + }, + "@solana/instruction-plans@8.4.0": { + "integrity": "sha512-+qY9d2Jzt2uxzjXs/ZZi448MbpMH0fiB3pWy8krUbCxW8eTl8tMuqIZvltMe05FldFR432xi6xFeMVl0Bw4CWA==", + "dependencies": [ + "@solana/errors", + "@solana/instructions", + "@solana/keys", + "@solana/promises", + "@solana/transaction-messages", + "@solana/transactions" + ] + }, + "@solana/instructions@8.4.0": { + "integrity": "sha512-muT/BBKDTl0UsHsnKySVaNBWIcHbs8nn8nOd1GI9J0OvX4gV/pNtaJfrEW+ETX9SjcIB4AcBQZsIr3LjavvrKQ==", + "dependencies": [ + "@solana/codecs-core", + "@solana/errors" + ] + }, + "@solana/keys@8.4.0": { + "integrity": "sha512-arjjFlJLBnGq0PWWswqO1n8kHxW02EbP9KTCoZo/TYDcSDcPdC4gL4fjAxbP6t5fVXTIu1tM3QGmab6FZxnmJg==", + "dependencies": [ + "@solana/assertions", + "@solana/codecs-core", + "@solana/codecs-strings", + "@solana/errors", + "@solana/nominal-types", + "@solana/promises" + ] + }, + "@solana/kit@8.4.0": { + "integrity": "sha512-jbexijXuCqQ7MV5lFzPDEsVScreFENkhUOUVofniTkBsfi67cYGgEeGzJa7oskHGyXcWaEogW0VPVh4ep3cWnw==", + "dependencies": [ + "@solana/accounts", + "@solana/addresses", + "@solana/codecs", + "@solana/errors", + "@solana/functional", + "@solana/instruction-plans", + "@solana/instructions", + "@solana/keys", + "@solana/offchain-messages", + "@solana/plugin-core", + "@solana/plugin-interfaces", + "@solana/program-client-core", + "@solana/programs", + "@solana/promises", + "@solana/rpc", + "@solana/rpc-api", + "@solana/rpc-parsed-types", + "@solana/rpc-spec-types", + "@solana/rpc-subscriptions", + "@solana/rpc-types", + "@solana/signers", + "@solana/subscribable", + "@solana/sysvars", + "@solana/transaction-confirmation", + "@solana/transaction-introspection", + "@solana/transaction-messages", + "@solana/transactions" + ] + }, + "@solana/nominal-types@8.4.0": { + "integrity": "sha512-01LNXtH3THaR0SFXbJ9iXhaZAVBfLJoHWYC/x2GdNIontc45qMX8wFtglZe4RaT528/kre6J+f+4NGGGd4+YPA==" + }, + "@solana/offchain-messages@8.4.0": { + "integrity": "sha512-vE28aDf14XldqoYGwwRG1OvsUKVal1FTxM+O1p1bPHho0bQgUiHvqtsDvQtTZBPJpx7d4l5Xo7TKN4DVZ+VgTQ==", + "dependencies": [ + "@solana/addresses", + "@solana/codecs-core", + "@solana/codecs-data-structures", + "@solana/codecs-numbers", + "@solana/codecs-strings", + "@solana/errors", + "@solana/keys", + "@solana/nominal-types" + ] + }, + "@solana/options@8.4.0": { + "integrity": "sha512-3fnmCT/WNWOMpD5uhyi1/aI4fwtb13MQSEqiTqsboZhHClli1WAOyPhyC5I/YeJ7wF+RMzX8UE/11KU9IMazNA==", + "dependencies": [ + "@solana/codecs-core", + "@solana/codecs-data-structures", + "@solana/codecs-numbers", + "@solana/codecs-strings", + "@solana/errors" + ] + }, + "@solana/plugin-core@8.4.0": { + "integrity": "sha512-mRB5iQ+ZEISGyHnFvFDUJyDmK7YbPxmsJk38SKg3ncxqcSxMEhK4hZ7kJBo2UMsyDX1Sn2VSGJYPhZwdOa3s8w==" + }, + "@solana/plugin-interfaces@8.4.0": { + "integrity": "sha512-R1y8z9aBCHXnx7Aqax4ORBaC1wQaHS+KQjnbNEbVZijeJhfoKbSBA5vwlweEZPKT+l2iPL9jlxPrDlVDl4NyhQ==", + "dependencies": [ + "@solana/accounts", + "@solana/addresses", + "@solana/instruction-plans", + "@solana/keys", + "@solana/rpc-spec", + "@solana/rpc-subscriptions-spec", + "@solana/rpc-types", + "@solana/signers", + "@solana/transactions" + ] + }, + "@solana/program-client-core@8.4.0": { + "integrity": "sha512-GBgz9wHMp2BOKRTp/IAATooTLPIe+6Y0jCTYOSkXME9F7xyh1o7mGu0lEbotnB6C3fubaXzU6Swk9SYskl7Sig==", + "dependencies": [ + "@solana/accounts", + "@solana/addresses", + "@solana/codecs-core", + "@solana/errors", + "@solana/instruction-plans", + "@solana/instructions", + "@solana/plugin-interfaces", + "@solana/rpc-api", + "@solana/signers" + ] + }, + "@solana/programs@8.4.0": { + "integrity": "sha512-KZvtGP7spytak0igTSb1tulNc5fhCEyjYNlMBObveohVhrzT7/t7M6ioqcJpAvv1bWm+E7E4FI5B+fjMKMpAxQ==", + "dependencies": [ + "@solana/addresses", + "@solana/errors" + ] + }, + "@solana/promises@8.4.0": { + "integrity": "sha512-keb+TXJZHRT605HLakRanfjnSVUFYG6za+P7W8UDKA2ZUp+LTi1As5fQTkhRyFO/GOrbmP9a7lYC5eNGAekg6w==" + }, + "@solana/rpc-api@8.4.0": { + "integrity": "sha512-tD26U9U7pOQoLiTp7MoyWYPSmnvLAa9OrpQPGQ8NVUU7xXOeVKSKRe3rI4EL/zzcPNXeCAKtLJ449u8ejLT7LA==", + "dependencies": [ + "@solana/addresses", + "@solana/codecs-core", + "@solana/codecs-strings", + "@solana/errors", + "@solana/keys", + "@solana/rpc-parsed-types", + "@solana/rpc-spec", + "@solana/rpc-transformers", + "@solana/rpc-types", + "@solana/transaction-messages", + "@solana/transactions" + ] + }, + "@solana/rpc-parsed-types@8.4.0": { + "integrity": "sha512-/vBcGcLy/W1r8t0ST+gc3EqVPFx7dRFxkt5RoYE9tepEiroOwLbVg7rKtgtKifkFBODSVDcupEkTBBhRbWpB9A==" + }, + "@solana/rpc-spec-types@8.4.0": { + "integrity": "sha512-YnxoUzWy/bwdclB3ipu7+4/mnnb4Jqmgq1O20zhQ81cUGZseEWy++Y4GJA0OBZvrcDHhoRntSd26ABg9q0XaVg==", + "dependencies": [ + "@solana/errors" + ] + }, + "@solana/rpc-spec@8.4.0": { + "integrity": "sha512-g5R8jJoYDjwb4sEUw8PxReAw5OETSjWSgMF+f/Q+0BGRiX+hNO//3qxWRL0rpWAnHi9R03W5Li/sPOYC8IGL1Q==", + "dependencies": [ + "@solana/errors", + "@solana/rpc-spec-types", + "@solana/subscribable" + ] + }, + "@solana/rpc-subscriptions-api@8.4.0": { + "integrity": "sha512-qsSYyfmYSB8/VE6yks4Ls4fQyyi2VhS09PZaENfTSFk6iKAYyEnhOkwCu//MdeWOrrHDmGmxC2UdzpB61f+Fcg==", + "dependencies": [ + "@solana/addresses", + "@solana/keys", + "@solana/rpc-subscriptions-spec", + "@solana/rpc-transformers", + "@solana/rpc-types", + "@solana/transaction-messages", + "@solana/transactions" + ] + }, + "@solana/rpc-subscriptions-channel-websocket@8.4.0": { + "integrity": "sha512-O0UAs9G/lgBRf4Aw7kvG5quHWDWdfuTn8BJUy3KOvCFADOOGrrH6leXLHJAMxN2T8KmyO28cs2+GGW/CD5kWNQ==", + "dependencies": [ + "@solana/errors", + "@solana/functional", + "@solana/rpc-subscriptions-spec", + "@solana/subscribable", + "ws" + ] + }, + "@solana/rpc-subscriptions-spec@8.4.0": { + "integrity": "sha512-H7Jqleo+WR1hUcPexQCn5rIgGsXa7Ip0Pnl3Vzvv/DIpYEN5lpMrWXf3v9fVyG3jRxom5WW32xmYhiHa2dORzw==", + "dependencies": [ + "@solana/errors", + "@solana/promises", + "@solana/rpc-spec-types", + "@solana/subscribable" + ] + }, + "@solana/rpc-subscriptions@8.4.0": { + "integrity": "sha512-XkWl2flaGKkHzw6+StjVsYtJoB5xoGpnsdanXa1h1KnwK4HFFy/wsJ0P+5TY1Z0DR1IDn6voNl3KSQrQuEQm9Q==", + "dependencies": [ + "@solana/errors", + "@solana/fast-stable-stringify", + "@solana/functional", + "@solana/promises", + "@solana/rpc-spec-types", + "@solana/rpc-subscriptions-api", + "@solana/rpc-subscriptions-channel-websocket", + "@solana/rpc-subscriptions-spec", + "@solana/rpc-transformers", + "@solana/rpc-types", + "@solana/subscribable" + ] + }, + "@solana/rpc-transformers@8.4.0": { + "integrity": "sha512-FTlLgsjN/1RKeBidS5Dfb81VpeqRYESiKg7jTkbY6MXVL96bOMUihQDXAjmgUMMp95nTykuQjKas7pkG2Zsz5w==", + "dependencies": [ + "@solana/errors", + "@solana/functional", + "@solana/nominal-types", + "@solana/rpc-spec-types", + "@solana/rpc-types" + ] + }, + "@solana/rpc-transport-http@8.4.0": { + "integrity": "sha512-MSlFqehp1CpADeSozzb/YnBEvkBlIrTcmLIVmeKbcTMOELV5yZKnp+bMQl05Q0swsyTr423kQ1XvV9Oqk3/KoA==", + "dependencies": [ + "@solana/errors", + "@solana/rpc-spec", + "@solana/rpc-spec-types", + "undici-types" + ] + }, + "@solana/rpc-types@8.4.0": { + "integrity": "sha512-orCi24z9u7AdaozJfgtXwdwHErQy5vO3h6/wCBd/W0bWsfRXiCCWqJcZJqyoZvl1y0oESGEkZR0CzrpedyaAqg==", + "dependencies": [ + "@solana/addresses", + "@solana/codecs-core", + "@solana/codecs-numbers", + "@solana/codecs-strings", + "@solana/errors", + "@solana/fixed-points", + "@solana/nominal-types" + ] + }, + "@solana/rpc@8.4.0": { + "integrity": "sha512-xrJa4Bapskl1aud+qirKFbDy1A22vWHGwW9YKav20Q1YjJRItE8MfJ9N4c3MAtaSkC59QhBeHOsuf3F0gm+Hxw==", + "dependencies": [ + "@solana/errors", + "@solana/fast-stable-stringify", + "@solana/functional", + "@solana/rpc-api", + "@solana/rpc-spec", + "@solana/rpc-spec-types", + "@solana/rpc-transformers", + "@solana/rpc-transport-http", + "@solana/rpc-types" + ] + }, + "@solana/signers@8.4.0": { + "integrity": "sha512-hqBzc1M/+y+6rUy7OVAisjoS0/pwhIB3B0VOoJfQ9yBjFmx8TguxcKevn4dP0DIeBK4HqQgiqJyJN0f5hbHfxQ==", + "dependencies": [ + "@solana/addresses", + "@solana/codecs-core", + "@solana/errors", + "@solana/instructions", + "@solana/keys", + "@solana/nominal-types", + "@solana/offchain-messages", + "@solana/transaction-messages", + "@solana/transactions" + ] + }, + "@solana/subscribable@8.4.0": { + "integrity": "sha512-EgRMZWnxo1GYan014TscE5i9iDl/dgazwRAgyQ/QRUtB5FVcedRHr0Wh6dW6MJno4htKN4rZsMN+jAuaxLNfmw==", + "dependencies": [ + "@solana/errors", + "@solana/promises" + ] + }, + "@solana/sysvars@8.4.0": { + "integrity": "sha512-M2Wk70cji0n0muwHuZiPpDLeRy3Iq19FSOCNQPC/VL5Bg4Ltm7G9PXPvX4/TEODfFGgOLGja4rZmFlECl7tlXg==", + "dependencies": [ + "@solana/accounts", + "@solana/codecs-core", + "@solana/codecs-data-structures", + "@solana/codecs-numbers", + "@solana/errors", + "@solana/rpc-types" + ] + }, + "@solana/transaction-confirmation@8.4.0": { + "integrity": "sha512-tTKRbzqUzpQGh4ZmL8MTyvZBWHzvcuvDrGROFk8vw2b1FINsv6BAKbxXKWUTWp2RO0ABcznMt+sFHAyPwQ/2/w==", + "dependencies": [ + "@solana/addresses", + "@solana/codecs-strings", + "@solana/errors", + "@solana/keys", + "@solana/promises", + "@solana/rpc", + "@solana/rpc-subscriptions", + "@solana/rpc-types", + "@solana/transaction-messages", + "@solana/transactions" + ] + }, + "@solana/transaction-introspection@8.4.0": { + "integrity": "sha512-qVvPIRh7Q76k1UNcy2wZIKpA6emmfhMVNUFNheD+eCzOycGDcCT3Y/Mt7H5qU+dDq4NKLNR/20h4aRu1Qendbg==", + "dependencies": [ + "@solana/addresses", + "@solana/codecs-core", + "@solana/codecs-strings", + "@solana/errors", + "@solana/instructions", + "@solana/rpc-types", + "@solana/transaction-messages", + "@solana/transactions" + ] + }, + "@solana/transaction-messages@8.4.0": { + "integrity": "sha512-LdihUr4z6bAIv44z13uaShCXgb9C8DY0gZ+RcW9U+CcaDJwWhgZuy5IG2TBAAGa5lbEyRcYPQxD+/aE6b1F/WA==", + "dependencies": [ + "@solana/addresses", + "@solana/codecs-core", + "@solana/codecs-data-structures", + "@solana/codecs-numbers", + "@solana/errors", + "@solana/functional", + "@solana/instructions", + "@solana/nominal-types", + "@solana/rpc-types" + ] + }, + "@solana/transactions@8.4.0": { + "integrity": "sha512-+FFNSlr5vVTcGS9c7seH7mNnjZY21uZ3pHxiN9jeduODD7z+caKnGgjmzokZSDYapFUcupniIr736CrJNmbMFw==", + "dependencies": [ + "@solana/addresses", + "@solana/codecs-core", + "@solana/codecs-data-structures", + "@solana/codecs-numbers", + "@solana/codecs-strings", + "@solana/errors", + "@solana/functional", + "@solana/instructions", + "@solana/keys", + "@solana/nominal-types", + "@solana/rpc-types", + "@solana/transaction-messages" + ] + }, + "chalk@5.6.2": { + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==" + }, + "commander@15.0.0": { + "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==" + }, + "undici-types@8.11.2": { + "integrity": "sha512-iMVNmWZ0leK/goS6eXMizSzmm9CDWtyphwbaCms3DNLqRxDL+mMoNVcZMTyyVgXP0N+Z8neAMzDoUOUJL8veKg==" + }, + "ws@8.22.0": { + "integrity": "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==" + } + } +} diff --git a/packages/receipts-ts/mod.ts b/packages/receipts-ts/mod.ts new file mode 100644 index 0000000..095b866 --- /dev/null +++ b/packages/receipts-ts/mod.ts @@ -0,0 +1,35 @@ +/** + * NO SUS Canary receipts: encode, parse, send and fetch the SPL Memo that + * records each seal and each open on Solana. Spec: docs/RECEIPTS_SPEC.md. + * + * ```ts + * import { explorerTxUrl, fetchReceipt } from "@nosus/receipts"; + * + * const r = await fetchReceipt("2BHqnu…"); + * console.log(r.receipt, explorerTxUrl(r.signature)); + * ``` + * + * @module + */ + +export { + DEFAULT_MEMO_PROGRAM, + encodeOpenMemo, + encodeSealMemo, + MAX_MEMO_BYTES, + MEMO_PROGRAM_IDS, + type OpenInput, + type OpenReceipt, + parseReceiptMemo, + PROTOCOL, + type Receipt, + ReceiptFormatError, + type SealInput, + type SealReceipt, + VERSION, +} from "./src/memo.ts"; +export { chainNoteId, copiesHash, copyDigest, deviceHash, readerTag } from "./src/ids.ts"; +export { parseRelayerKeys } from "./src/keys.ts"; +export { type SendConfig, sendMemo } from "./src/send.ts"; +export { type FetchedReceipt, fetchReceipt } from "./src/fetch.ts"; +export { type Cluster, DEFAULT_RPC_URLS, explorerTxUrl } from "./src/explorer.ts"; diff --git a/packages/receipts-ts/src/base58.ts b/packages/receipts-ts/src/base58.ts new file mode 100644 index 0000000..4c2722c --- /dev/null +++ b/packages/receipts-ts/src/base58.ts @@ -0,0 +1,21 @@ +// Base58 (Bitcoin alphabet) to bytes. Kept local so parsing keys and reading +// receipts never load @solana/kit; only send.ts does. + +const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +export function base58Decode(text: string): Uint8Array { + let n = 0n; + for (const c of text) { + const digit = ALPHABET.indexOf(c); + if (digit < 0) throw new Error("not base58"); + n = n * 58n + BigInt(digit); + } + const bytes: number[] = []; + for (; n > 0n; n >>= 8n) bytes.unshift(Number(n & 0xffn)); + // Each leading "1" is a leading zero byte. + for (const c of text) { + if (c !== "1") break; + bytes.unshift(0); + } + return Uint8Array.from(bytes); +} diff --git a/packages/receipts-ts/src/explorer.ts b/packages/receipts-ts/src/explorer.ts new file mode 100644 index 0000000..a7f0d9e --- /dev/null +++ b/packages/receipts-ts/src/explorer.ts @@ -0,0 +1,13 @@ +export type Cluster = "devnet" | "mainnet-beta"; + +/** Default public RPC endpoint for each cluster. */ +export const DEFAULT_RPC_URLS: Readonly> = Object.freeze({ + "devnet": "https://api.devnet.solana.com", + "mainnet-beta": "https://api.mainnet-beta.solana.com", +}); + +/** Solana Explorer page for a transaction. Mainnet takes no cluster param. */ +export function explorerTxUrl(signature: string, cluster: Cluster = "devnet"): string { + const base = `https://explorer.solana.com/tx/${signature}`; + return cluster === "mainnet-beta" ? base : `${base}?cluster=${cluster}`; +} diff --git a/packages/receipts-ts/src/fetch.ts b/packages/receipts-ts/src/fetch.ts new file mode 100644 index 0000000..271596a --- /dev/null +++ b/packages/receipts-ts/src/fetch.ts @@ -0,0 +1,94 @@ +// Reads one receipt back from the chain with a plain JSON-RPC getTransaction +// call. No npm packages, so verifying needs nothing but fetch. + +import { MEMO_PROGRAM_IDS, parseReceiptMemo, PROTOCOL, type Receipt } from "./memo.ts"; +import { base58Decode } from "./base58.ts"; +import { DEFAULT_RPC_URLS } from "./explorer.ts"; + +export type FetchedReceipt = { + signature: string; + slot: number; + /** Unix seconds; null when the node does not know it. */ + blockTime: number | null; + /** First account key: the relayer that paid for and signed the memo. */ + feePayer: string; + memoProgram: string; + receipt: Receipt; +}; + +type Instruction = { programId: string; parsed?: unknown; data?: string }; +type Transaction = { + slot: number; + blockTime: number | null; + meta: { err: unknown } | null; + transaction: { message: { accountKeys: { pubkey: string }[]; instructions: Instruction[] } }; +}; + +const SIGNATURE_RE = /^[1-9A-HJ-NP-Za-km-z]{64,88}$/; + +/** + * Fetches a transaction and decodes its NO SUS Canary memo. Throws when the + * transaction is missing or failed, has no memo, has a foreign memo, or the + * memo is not exactly format v1 (ReceiptFormatError). + */ +export async function fetchReceipt( + signature: string, + opts: { rpcUrl?: string; fetch?: typeof fetch } = {}, +): Promise { + if (!SIGNATURE_RE.test(signature)) { + throw new Error("signature must be a base58 transaction signature"); + } + const res = await (opts.fetch ?? fetch)(opts.rpcUrl ?? DEFAULT_RPC_URLS.devnet, { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: 1, + method: "getTransaction", + params: [signature, { + encoding: "jsonParsed", + maxSupportedTransactionVersion: 0, + commitment: "confirmed", + }], + }), + }); + if (!res.ok) throw new Error(`getTransaction failed: HTTP ${res.status}`); + const body = await res.json() as { + result?: Transaction | null; + error?: { message?: string }; + }; + if (body.error) throw new Error(`getTransaction failed: ${body.error.message ?? "RPC error"}`); + + const tx = body.result; + if (!tx) throw new Error(`transaction ${signature} not found on this cluster`); + if (tx.meta?.err) throw new Error(`transaction ${signature} failed on chain`); + + const memos = tx.transaction.message.instructions + .filter((ix) => MEMO_PROGRAM_IDS.includes(ix.programId)) + .map((ix) => ({ program: ix.programId, text: memoText(ix) })); + if (memos.length === 0) throw new Error(`transaction ${signature} has no memo instruction`); + const ours = memos.filter((m) => m.text.startsWith(`{"p":"${PROTOCOL}",`)); + if (ours.length === 0) { + throw new Error(`transaction ${signature} memo is not a NO SUS Canary receipt`); + } + if (ours.length > 1) { + throw new Error(`transaction ${signature} has more than one NO SUS Canary memo`); + } + + return { + signature, + slot: tx.slot, + blockTime: tx.blockTime ?? null, + feePayer: tx.transaction.message.accountKeys[0]?.pubkey ?? "", + memoProgram: ours[0].program, + receipt: parseReceiptMemo(ours[0].text), + }; +} + +// RPC nodes decode SPL Memo v1/v3 into `parsed`; other memo programs (p-memo) +// come back as base58 `data`. +function memoText(ix: Instruction): string { + if (typeof ix.parsed === "string") return ix.parsed; + if (typeof ix.data === "string") return new TextDecoder().decode(base58Decode(ix.data)); + return ""; +} diff --git a/packages/receipts-ts/src/ids.ts b/packages/receipts-ts/src/ids.ts new file mode 100644 index 0000000..4398c85 --- /dev/null +++ b/packages/receipts-ts/src/ids.ts @@ -0,0 +1,38 @@ +// The sha256-based ids and hashes a receipt carries. Inputs are hashed as +// UTF-8 text; outputs are lowercase hex. Same formulas as the Canary app and +// the edge function, so anyone can recompute them. + +async function sha256Hex(text: string): Promise { + const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(text)); + return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, "0")).join(""); +} + +/** The memo `note`: "0x" + sha256("nosus-canary:" + noteId). noteId is a lowercase UUID. */ +export async function chainNoteId(noteId: string): Promise { + return `0x${await sha256Hex(`nosus-canary:${noteId}`)}`; +} + +/** sha256("device:" + deviceId), no 0x. Only ever stored or hashed again, never on chain. */ +export function deviceHash(deviceId: string): Promise { + return sha256Hex(`device:${deviceId}`); +} + +/** + * The open memo `tag`: "0x" + sha256(":::"). + * tagSalt is the relayer's secret, so only the relayer can recompute it. + */ +export async function readerTag( + p: { tagSalt: string; noteId: string; copyIndex: number; deviceHash: string }, +): Promise { + return `0x${await sha256Hex(`${p.tagSalt}:${p.noteId}:${p.copyIndex}:${p.deviceHash}`)}`; +} + +/** Commitment to one copy: sha256("::"), no 0x. */ +export function copyDigest(saltHex: string, index: number, copyText: string): Promise { + return sha256Hex(`${saltHex}:${index}:${copyText}`); +} + +/** The seal memo `hash`: "0x" + sha256 of the copy digests joined in copy order. */ +export async function copiesHash(copyDigests: string[]): Promise { + return `0x${await sha256Hex(copyDigests.join(""))}`; +} diff --git a/packages/receipts-ts/src/keys.ts b/packages/receipts-ts/src/keys.ts new file mode 100644 index 0000000..0cb0341 --- /dev/null +++ b/packages/receipts-ts/src/keys.ts @@ -0,0 +1,44 @@ +// Relayer key parsing, in the SOLANA_RELAYER_KEYS format: comma-separated +// keypairs, each either a base58 64-byte secret key or a solana-keygen JSON +// array. Errors never include key material. + +import { base58Decode } from "./base58.ts"; + +const BASE58_RE = /^[1-9A-HJ-NP-Za-km-z]+$/; + +/** 64-byte secret keys (private key || public key), as solana-keygen writes them. */ +export function parseRelayerKeys(raw: string): Uint8Array[] { + // Items are comma-separated, but a JSON array item contains commas itself. + const items = raw.match(/\[[^\]]*\]|[^,\[\]\s]+/g) ?? []; + const keys = items.map(parseSecretKey); + if (keys.length === 0 || keys.length > 32) { + throw new Error("SOLANA_RELAYER_KEYS must hold 1 to 32 keys"); + } + return keys; +} + +function parseSecretKey(item: string): Uint8Array { + let bytes: Uint8Array; + if (item.startsWith("[")) { + let parsed: unknown; + try { + parsed = JSON.parse(item); + } catch { + throw new Error("SOLANA_RELAYER_KEYS: a JSON key is not valid JSON"); + } + if ( + !Array.isArray(parsed) || + !parsed.every((n) => Number.isInteger(n) && n >= 0 && n <= 255) + ) { + throw new Error("SOLANA_RELAYER_KEYS: a JSON key must be an array of bytes"); + } + bytes = Uint8Array.from(parsed as number[]); + } else { + if (!BASE58_RE.test(item)) { + throw new Error("SOLANA_RELAYER_KEYS: a key must be base58 or a JSON array"); + } + bytes = base58Decode(item); + } + if (bytes.length !== 64) throw new Error("SOLANA_RELAYER_KEYS: a key must be 64 bytes"); + return bytes; +} diff --git a/packages/receipts-ts/src/memo.ts b/packages/receipts-ts/src/memo.ts new file mode 100644 index 0000000..b552e1b --- /dev/null +++ b/packages/receipts-ts/src/memo.ts @@ -0,0 +1,136 @@ +// NO SUS Canary receipt memo, format v1 (spec: docs/RECEIPTS_SPEC.md). +// +// One SPL Memo per seal and per open. The memo is compact JSON with a fixed +// key order, so the same receipt is always the same bytes: +// {"p":"nosus-canary","v":1,"t":"seal","note":"0x…","copies":N,"hash":"0x…","exp":E} +// {"p":"nosus-canary","v":1,"t":"open","note":"0x…","copy":N,"tag":"0x…"} + +export const PROTOCOL = "nosus-canary"; +export const VERSION = 1; + +/** Longest memo a single-signer transaction can carry. */ +export const MAX_MEMO_BYTES = 566; + +/** SPL Memo v3 (Solana Explorer shows the memo text). */ +export const DEFAULT_MEMO_PROGRAM = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"; + +/** Memo programs a receipt may be written with: SPL Memo v1, v3 and p-memo. */ +export const MEMO_PROGRAM_IDS: readonly string[] = Object.freeze([ + "Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo", + DEFAULT_MEMO_PROGRAM, + "Memo4c2pN8afCj432Lb7RMVKi9PbQnnW7ewFFaV3oAH", +]); + +export type SealInput = { note: string; copies: number; hash: string; exp: number }; +export type OpenInput = { note: string; copy: number; tag: string }; +export type SealReceipt = { v: 1; t: "seal" } & SealInput; +export type OpenReceipt = { v: 1; t: "open" } & OpenInput; +export type Receipt = SealReceipt | OpenReceipt; + +/** A memo or memo field that is not exactly format v1. */ +export class ReceiptFormatError extends Error { + constructor(message: string) { + super(message); + this.name = "ReceiptFormatError"; + } +} + +const BYTES32_RE = /^0x[0-9a-f]{64}$/; +const SEAL_KEYS = "p,v,t,note,copies,hash,exp"; +const OPEN_KEYS = "p,v,t,note,copy,tag"; + +function bytes32(name: string, value: unknown): string { + if (typeof value !== "string" || !BYTES32_RE.test(value)) { + throw new ReceiptFormatError(`memo ${name} must be 0x + 64 hex chars`); + } + return value; +} + +// Safe integers only, so every encoded memo parses back to the same bytes. +function uint(name: string, value: unknown): number { + if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) { + throw new ReceiptFormatError(`memo ${name} must be a non-negative integer`); + } + return value; +} + +// exp is unix seconds, 0 when the note never expires. +export function encodeSealMemo(p: SealInput): string { + return JSON.stringify({ + p: PROTOCOL, + v: VERSION, + t: "seal", + note: bytes32("note", p.note), + copies: uint("copies", p.copies), + hash: bytes32("hash", p.hash), + exp: uint("exp", p.exp), + }); +} + +export function encodeOpenMemo(p: OpenInput): string { + return JSON.stringify({ + p: PROTOCOL, + v: VERSION, + t: "open", + note: bytes32("note", p.note), + copy: uint("copy", p.copy), + tag: bytes32("tag", p.tag), + }); +} + +/** + * Strict parse: accepts only the exact bytes encodeSealMemo/encodeOpenMemo + * would write. Throws ReceiptFormatError otherwise. + */ +export function parseReceiptMemo(memo: string): Receipt { + if (new TextEncoder().encode(memo).length > MAX_MEMO_BYTES) { + throw new ReceiptFormatError(`memo is longer than ${MAX_MEMO_BYTES} bytes`); + } + let m: unknown; + try { + m = JSON.parse(memo); + } catch { + throw new ReceiptFormatError("memo is not JSON"); + } + if (typeof m !== "object" || m === null || Array.isArray(m)) { + throw new ReceiptFormatError("memo is not a JSON object"); + } + const o = m as Record; + if (o.p !== PROTOCOL) throw new ReceiptFormatError(`memo p must be "${PROTOCOL}"`); + if (o.v !== VERSION) throw new ReceiptFormatError(`memo v must be ${VERSION}`); + if (o.t !== "seal" && o.t !== "open") { + throw new ReceiptFormatError('memo t must be "seal" or "open"'); + } + + const keys = o.t === "seal" ? SEAL_KEYS : OPEN_KEYS; + if (Object.keys(o).join(",") !== keys) { + throw new ReceiptFormatError(`memo keys must be ${keys} in this order`); + } + + let receipt: Receipt; + let canonical: string; + if (o.t === "seal") { + receipt = { + v: 1, + t: "seal", + note: bytes32("note", o.note), + copies: uint("copies", o.copies), + hash: bytes32("hash", o.hash), + exp: uint("exp", o.exp), + }; + canonical = encodeSealMemo(receipt); + } else { + receipt = { + v: 1, + t: "open", + note: bytes32("note", o.note), + copy: uint("copy", o.copy), + tag: bytes32("tag", o.tag), + }; + canonical = encodeOpenMemo(receipt); + } + // Catches whitespace, 3.0 / 3e0, duplicate keys and anything else that + // JSON.parse forgives. + if (canonical !== memo) throw new ReceiptFormatError("memo is not in canonical form"); + return receipt; +} diff --git a/packages/receipts-ts/src/send.ts b/packages/receipts-ts/src/send.ts new file mode 100644 index 0000000..393fb3f --- /dev/null +++ b/packages/receipts-ts/src/send.ts @@ -0,0 +1,86 @@ +// Sends one memo as a Solana transaction from a relayer key. A Solana +// transaction is scoped by a recent blockhash, not an account nonce, so one +// relayer key can send concurrently and no lease is needed. + +import { + address, + appendTransactionMessageInstruction, + createKeyPairSignerFromBytes, + createSolanaRpc, + createTransactionMessage, + getBase64EncodedWireTransaction, + getSignatureFromTransaction, + pipe, + setTransactionMessageFeePayerSigner, + setTransactionMessageLifetimeUsingBlockhash, + signTransactionMessageWithSigners, +} from "npm:@solana/kit@8.4.0"; +import { Buffer } from "node:buffer"; +import { getAddMemoInstruction } from "npm:@solana-program/memo@0.15.0"; + +// The Supabase edge runtime resolves @solana/kit's Node build, whose base64 +// codec reads the global Buffer that Deno does not define. +(globalThis as { Buffer?: typeof Buffer }).Buffer ??= Buffer; + +export type SendConfig = { + rpcUrl: string; + /** 64-byte secret keys (private key || public key); see parseRelayerKeys. */ + keys: Uint8Array[]; + /** One of MEMO_PROGRAM_IDS. */ + memoProgram: string; +}; + +const CONFIRM_TIMEOUT_MS = 20_000; +const CONFIRM_POLL_MS = 400; + +/** + * Sends one memo instruction from a random relayer key and waits until the + * transaction is confirmed. Returns the base58 signature. Polls over HTTP; no + * WebSocket subscriptions. + */ +export async function sendMemo(cfg: SendConfig, p: { memo: string }): Promise { + const rpc = createSolanaRpc(cfg.rpcUrl); + const signer = await createKeyPairSignerFromBytes( + cfg.keys[Math.floor(Math.random() * cfg.keys.length)], + ); + const { value: latest } = await rpc.getLatestBlockhash({ commitment: "confirmed" }).send(); + + const message = pipe( + createTransactionMessage({ version: 0 }), + (m) => setTransactionMessageFeePayerSigner(signer, m), + (m) => setTransactionMessageLifetimeUsingBlockhash(latest, m), + (m) => + appendTransactionMessageInstruction( + getAddMemoInstruction( + { memo: p.memo, signers: [signer] }, + { programAddress: address(cfg.memoProgram) }, + ), + m, + ), + ); + const transaction = await signTransactionMessageWithSigners(message); + const signature = getSignatureFromTransaction(transaction); + + await rpc + .sendTransaction(getBase64EncodedWireTransaction(transaction), { + encoding: "base64", + preflightCommitment: "confirmed", + }) + .send(); + + const deadline = Date.now() + CONFIRM_TIMEOUT_MS; + for (;;) { + const { value: [status] } = await rpc.getSignatureStatuses([signature]).send(); + if (status?.err) { + const err = JSON.stringify(status.err, (_, v) => (typeof v === "bigint" ? v.toString() : v)); + throw new Error(`solana memo ${signature} failed: ${err}`); + } + if (status?.confirmationStatus === "confirmed" || status?.confirmationStatus === "finalized") { + return signature; + } + if (Date.now() >= deadline) { + throw new Error(`solana memo ${signature} not confirmed within ${CONFIRM_TIMEOUT_MS} ms`); + } + await new Promise((resolve) => setTimeout(resolve, CONFIRM_POLL_MS)); + } +} diff --git a/packages/receipts-ts/test/fetch_test.ts b/packages/receipts-ts/test/fetch_test.ts new file mode 100644 index 0000000..d083103 --- /dev/null +++ b/packages/receipts-ts/test/fetch_test.ts @@ -0,0 +1,138 @@ +// fetchReceipt against saved devnet getTransaction responses. Offline: fetch +// is injected and never reaches the network. +import { assertEquals, assertRejects } from "jsr:@std/assert@1.0.19"; +import vectors from "../../test-vectors/receipts.json" with { type: "json" }; +import tx2BHqnu from "../../test-vectors/devnet/2BHqnu.json" with { type: "json" }; +import txNwoJau from "../../test-vectors/devnet/NwoJau.json" with { type: "json" }; +import tx62Frr2 from "../../test-vectors/devnet/62Frr2.json" with { type: "json" }; +import tx2b9SS9 from "../../test-vectors/devnet/2b9SS9.json" with { type: "json" }; +import tx4NXs89 from "../../test-vectors/devnet/4NXs89.json" with { type: "json" }; +import { fetchReceipt } from "../src/fetch.ts"; +import { parseReceiptMemo, ReceiptFormatError } from "../src/memo.ts"; + +const FIXTURES: Record = { + "devnet/2BHqnu.json": tx2BHqnu, + "devnet/NwoJau.json": txNwoJau, + "devnet/62Frr2.json": tx62Frr2, + "devnet/2b9SS9.json": tx2b9SS9, + "devnet/4NXs89.json": tx4NXs89, +}; +const SEAL = vectors.devnet[0]; +const RPC = "http://rpc.test"; + +// Returns `body` as the JSON-RPC response and records each request. +function rpc(body: unknown, status = 200) { + const requests: { url: string; body: unknown }[] = []; + const fetch = (url: string | URL | Request, init?: RequestInit) => { + requests.push({ url: String(url), body: JSON.parse(String(init?.body)) }); + return Promise.resolve(new Response(JSON.stringify(body), { status })); + }; + return { fetch: fetch as typeof globalThis.fetch, requests }; +} + +// A copy of the seal fixture with its single instruction replaced. +function withInstruction(ix: unknown) { + const copy = structuredClone(tx2BHqnu); + (copy.result.transaction.message.instructions as unknown[]) = [ix]; + return copy; +} + +Deno.test("fetchReceipt decodes every real devnet receipt", async () => { + for (const v of vectors.devnet) { + const { fetch } = rpc(FIXTURES[v.fixture]); + const r = await fetchReceipt(v.signature, { rpcUrl: RPC, fetch }); + assertEquals(r, { + signature: v.signature, + slot: v.slot, + blockTime: v.blockTime, + feePayer: v.feePayer, + memoProgram: v.memoProgram, + receipt: parseReceiptMemo(v.memo), + }); + } +}); + +Deno.test("fetchReceipt sends one jsonParsed getTransaction at confirmed", async () => { + const { fetch, requests } = rpc(tx2BHqnu); + await fetchReceipt(SEAL.signature, { rpcUrl: RPC, fetch }); + assertEquals(requests, [{ + url: RPC, + body: { + jsonrpc: "2.0", + id: 1, + method: "getTransaction", + params: [SEAL.signature, { + encoding: "jsonParsed", + maxSupportedTransactionVersion: 0, + commitment: "confirmed", + }], + }, + }]); +}); + +Deno.test("fetchReceipt reads base58 data from memo programs the node does not parse", async () => { + const raw = vectors.rawMemoInstruction; + const { fetch } = rpc(withInstruction({ + accounts: [SEAL.feePayer], + data: raw.data, + programId: raw.programId, + stackHeight: 1, + })); + const r = await fetchReceipt(SEAL.signature, { rpcUrl: RPC, fetch }); + assertEquals(r.memoProgram, raw.programId); + assertEquals(r.receipt, parseReceiptMemo(raw.memo)); +}); + +Deno.test("fetchReceipt errors", async () => { + const sig = SEAL.signature; + const memoIx = tx2BHqnu.result.transaction.message.instructions[0]; + const failed = structuredClone(tx2BHqnu); + (failed.result.meta.err as unknown) = { InstructionError: [0, "Custom"] }; + const cases: [unknown, string, number?][] = [ + [{ jsonrpc: "2.0", result: null, id: 1 }, `transaction ${sig} not found on this cluster`], + [{ jsonrpc: "2.0", error: { code: -32602, message: "Invalid param" }, id: 1 }, "Invalid param"], + [{}, "HTTP 503", 503], + [failed, `transaction ${sig} failed on chain`], + [ + withInstruction({ + parsed: { type: "transfer", info: {} }, + program: "system", + programId: "11111111111111111111111111111111", + }), + `transaction ${sig} has no memo instruction`, + ], + [ + withInstruction({ ...memoIx, parsed: "gm" }), + `transaction ${sig} memo is not a NO SUS Canary receipt`, + ], + ]; + for (const [body, message, status] of cases) { + const { fetch } = rpc(body, status); + await assertRejects(() => fetchReceipt(sig, { rpcUrl: RPC, fetch }), Error, message); + } + + const twice = structuredClone(tx2BHqnu); + twice.result.transaction.message.instructions.push(memoIx); + await assertRejects( + () => fetchReceipt(sig, { rpcUrl: RPC, fetch: rpc(twice).fetch }), + Error, + "more than one NO SUS Canary memo", + ); + + const v2 = vectors.invalidMemos.find((v) => v.name === "v=2")!; + await assertRejects( + () => + fetchReceipt(sig, { + rpcUrl: RPC, + fetch: rpc(withInstruction({ ...memoIx, parsed: v2.memo })).fetch, + }), + ReceiptFormatError, + v2.error, + ); + + await assertRejects( + () => fetchReceipt("not a signature!", { rpcUrl: RPC, fetch: rpc({}).fetch }), + Error, + "signature must be a base58 transaction signature", + ); +}); diff --git a/packages/receipts-ts/test/ids_test.ts b/packages/receipts-ts/test/ids_test.ts new file mode 100644 index 0000000..f2d15b7 --- /dev/null +++ b/packages/receipts-ts/test/ids_test.ts @@ -0,0 +1,33 @@ +import { assertEquals } from "jsr:@std/assert@1.0.19"; +import vectors from "../../test-vectors/receipts.json" with { type: "json" }; +import { chainNoteId, copiesHash, copyDigest, deviceHash, readerTag } from "../src/ids.ts"; +import { explorerTxUrl } from "../src/explorer.ts"; + +Deno.test("chainNoteId", async () => { + for (const v of vectors.chainNoteId) assertEquals(await chainNoteId(v.noteId), v.expected); +}); + +Deno.test("deviceHash", async () => { + for (const v of vectors.deviceHash) assertEquals(await deviceHash(v.deviceId), v.expected); +}); + +Deno.test("copyDigest hashes the copy text as UTF-8", async () => { + for (const v of vectors.copyDigest) { + assertEquals(await copyDigest(v.saltHex, v.index, v.copyText), v.expected); + } +}); + +Deno.test("copiesHash", async () => { + for (const v of vectors.copiesHash) assertEquals(await copiesHash(v.digests), v.expected); +}); + +Deno.test("readerTag", async () => { + for (const v of vectors.readerTag) assertEquals(await readerTag(v), v.expected); +}); + +Deno.test("explorerTxUrl: devnet has a cluster param, mainnet has none", () => { + for (const v of vectors.explorerTxUrl) { + assertEquals(explorerTxUrl(v.signature, v.cluster as "devnet" | "mainnet-beta"), v.expected); + } + assertEquals(explorerTxUrl("abc"), "https://explorer.solana.com/tx/abc?cluster=devnet"); +}); diff --git a/packages/receipts-ts/test/keys_test.ts b/packages/receipts-ts/test/keys_test.ts new file mode 100644 index 0000000..255c246 --- /dev/null +++ b/packages/receipts-ts/test/keys_test.ts @@ -0,0 +1,43 @@ +import { assertEquals, assertFalse, assertThrows } from "jsr:@std/assert@1.0.19"; +import { parseRelayerKeys } from "../src/keys.ts"; +import { base58Decode } from "../src/base58.ts"; + +// Test bytes 1..64 only; not a funded key. +const KEY = Uint8Array.from({ length: 64 }, (_, i) => i + 1); +const JSON_KEY = JSON.stringify([...KEY]); +const BASE58_KEY = + "2Ana1pUpv2ZbMVkwF5FXapYeBEjdxDatLn7nvJkhgTSXbs59SyZSx866bXirPgj8QQVB57uxHJBG1YFvkRbFj4T"; + +Deno.test("base58Decode keeps leading zero bytes", () => { + assertEquals(base58Decode(""), new Uint8Array()); + assertEquals(base58Decode("111"), new Uint8Array(3)); + assertEquals(base58Decode("11z"), Uint8Array.from([0, 0, 57])); + assertEquals(base58Decode("5Q"), Uint8Array.from([255])); + assertEquals(base58Decode("5R"), Uint8Array.from([1, 0])); + assertThrows(() => base58Decode("0"), Error, "not base58"); +}); + +Deno.test("parseRelayerKeys: base58 and solana-keygen JSON, comma-separated", () => { + assertEquals(parseRelayerKeys(BASE58_KEY), [KEY]); + assertEquals(parseRelayerKeys(JSON_KEY), [KEY]); + assertEquals(parseRelayerKeys(`${JSON_KEY}, ${BASE58_KEY},${JSON_KEY}`), [KEY, KEY, KEY]); +}); + +Deno.test("parseRelayerKeys: errors name the problem, never the key", () => { + const cases: [string, string][] = [ + ["", "SOLANA_RELAYER_KEYS must hold 1 to 32 keys"], + [" , ", "SOLANA_RELAYER_KEYS must hold 1 to 32 keys"], + [Array(33).fill(BASE58_KEY).join(","), "SOLANA_RELAYER_KEYS must hold 1 to 32 keys"], + ["[1,2,]", "SOLANA_RELAYER_KEYS: a JSON key is not valid JSON"], + ["[1,256]", "SOLANA_RELAYER_KEYS: a JSON key must be an array of bytes"], + ["[1.5]", "SOLANA_RELAYER_KEYS: a JSON key must be an array of bytes"], + [`0${BASE58_KEY}`, "SOLANA_RELAYER_KEYS: a key must be base58 or a JSON array"], + [BASE58_KEY.slice(0, 40), "SOLANA_RELAYER_KEYS: a key must be 64 bytes"], + [JSON.stringify([...KEY, 7]), "SOLANA_RELAYER_KEYS: a key must be 64 bytes"], + ]; + for (const [raw, message] of cases) { + const err = assertThrows(() => parseRelayerKeys(raw), Error); + assertEquals(err.message, message, raw); + assertFalse(err.message.includes(BASE58_KEY.slice(0, 8))); + } +}); diff --git a/packages/receipts-ts/test/memo_test.ts b/packages/receipts-ts/test/memo_test.ts new file mode 100644 index 0000000..01e98bb --- /dev/null +++ b/packages/receipts-ts/test/memo_test.ts @@ -0,0 +1,50 @@ +import { assertEquals, assertThrows } from "jsr:@std/assert@1.0.19"; +import vectors from "../../test-vectors/receipts.json" with { type: "json" }; +import { + encodeOpenMemo, + encodeSealMemo, + MAX_MEMO_BYTES, + parseReceiptMemo, + ReceiptFormatError, +} from "../src/memo.ts"; + +Deno.test("seal memos encode to the exact vector bytes and parse back", () => { + for (const v of vectors.sealMemo) { + assertEquals(encodeSealMemo(v.input), v.memo, v.name); + assertEquals(parseReceiptMemo(v.memo), { v: 1, t: "seal", ...v.input }, v.name); + } +}); + +Deno.test("open memos encode to the exact vector bytes and parse back", () => { + for (const v of vectors.openMemo) { + assertEquals(encodeOpenMemo(v.input), v.memo, v.name); + assertEquals(parseReceiptMemo(v.memo), { v: 1, t: "open", ...v.input }, v.name); + } +}); + +Deno.test("the largest memo today is 219 bytes", () => { + const sizes = [...vectors.sealMemo, ...vectors.openMemo].map((v) => + new TextEncoder().encode(v.memo).length + ); + assertEquals(Math.max(...sizes), 219); +}); + +Deno.test("encoders reject bad fields with the shared messages", () => { + for (const v of vectors.encodeErrors) { + const encode = v.kind === "seal" + ? () => encodeSealMemo(v.input as Parameters[0]) + : () => encodeOpenMemo(v.input as Parameters[0]); + assertThrows(encode, ReceiptFormatError, v.error, v.name); + } +}); + +Deno.test("parseReceiptMemo rejects every invalid vector with the shared message", () => { + for (const v of vectors.invalidMemos) { + const err = assertThrows(() => parseReceiptMemo(v.memo), ReceiptFormatError); + assertEquals(err.message, v.error, v.name); + } +}); + +Deno.test("MAX_MEMO_BYTES matches the vectors", () => { + assertEquals(MAX_MEMO_BYTES, vectors.maxMemoBytes); +}); diff --git a/packages/test-vectors/devnet/2BHqnu.json b/packages/test-vectors/devnet/2BHqnu.json new file mode 100644 index 0000000..87f02d9 --- /dev/null +++ b/packages/test-vectors/devnet/2BHqnu.json @@ -0,0 +1,69 @@ +{ + "jsonrpc": "2.0", + "result": { + "blockTime": 1791631256, + "meta": { + "computeUnitsConsumed": 91585, + "costUnits": 92683, + "err": null, + "fee": 5000, + "innerInstructions": [], + "logMessages": [ + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr invoke [1]", + "Program log: Signed by CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "Program log: Memo (len 217): \"{\\\"p\\\":\\\"nosus-canary\\\",\\\"v\\\":1,\\\"t\\\":\\\"seal\\\",\\\"note\\\":\\\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\\\",\\\"copies\\\":3,\\\"hash\\\":\\\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\\\",\\\"exp\\\":1791634855}\"", + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr consumed 91585 of 200000 compute units", + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr success" + ], + "postBalances": [ + 4999995000, + 41509609334 + ], + "postTokenBalances": [], + "preBalances": [ + 5000000000, + 41509609334 + ], + "preTokenBalances": [], + "rewards": [], + "status": { + "Ok": null + } + }, + "slot": 509523773, + "transaction": { + "message": { + "accountKeys": [ + { + "pubkey": "CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "signer": true, + "source": "transaction", + "writable": true + }, + { + "pubkey": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "signer": false, + "source": "transaction", + "writable": false + } + ], + "addressTableLookups": [], + "instructions": [ + { + "parsed": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "program": "spl-memo", + "programId": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "stackHeight": 1 + } + ], + "recentBlockhash": "5RQyZ259mmkoeNFD4pfU7zzDwHc9zW1LijXT4GQxaQmB" + }, + "signatures": [ + "2BHqnuCxYyemfegHkncgTsQyMPjpyB9boD1XqYfD1Wtbcf51Fpy3y264UwGhnvRKtcxFKCaSAzHxLrDwFRk512bQ" + ] + }, + "transactionIndex": 3, + "version": 0 + }, + "id": 1 +} diff --git a/packages/test-vectors/devnet/2b9SS9.json b/packages/test-vectors/devnet/2b9SS9.json new file mode 100644 index 0000000..637df3d --- /dev/null +++ b/packages/test-vectors/devnet/2b9SS9.json @@ -0,0 +1,69 @@ +{ + "jsonrpc": "2.0", + "result": { + "blockTime": 1791632860, + "meta": { + "computeUnitsConsumed": 84546, + "costUnits": 85639, + "err": null, + "fee": 5000, + "innerInstructions": [], + "logMessages": [ + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr invoke [1]", + "Program log: Signed by CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "Program log: Memo (len 197): \"{\\\"p\\\":\\\"nosus-canary\\\",\\\"v\\\":1,\\\"t\\\":\\\"open\\\",\\\"note\\\":\\\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\\\",\\\"copy\\\":0,\\\"tag\\\":\\\"0xe52417df0e5f0b104525ec1a583ec0bb64a71c2358a3e93d855b121172a4d10e\\\"}\"", + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr consumed 84546 of 200000 compute units", + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr success" + ], + "postBalances": [ + 4999900000, + 41509609334 + ], + "postTokenBalances": [], + "preBalances": [ + 4999905000, + 41509609334 + ], + "preTokenBalances": [], + "rewards": [], + "status": { + "Ok": null + } + }, + "slot": 509530464, + "transaction": { + "message": { + "accountKeys": [ + { + "pubkey": "CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "signer": true, + "source": "transaction", + "writable": true + }, + { + "pubkey": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "signer": false, + "source": "transaction", + "writable": false + } + ], + "addressTableLookups": [], + "instructions": [ + { + "parsed": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\",\"copy\":0,\"tag\":\"0xe52417df0e5f0b104525ec1a583ec0bb64a71c2358a3e93d855b121172a4d10e\"}", + "program": "spl-memo", + "programId": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "stackHeight": 1 + } + ], + "recentBlockhash": "EvrmQvr4RvAejEGnpTdvyc6QXNgJGKx9Uc5AF1Qz7Xw8" + }, + "signatures": [ + "2b9SS9RhwPvMrsDR5upY5a9w3gk7E2zgV4jmC69QTtZseBMmguXxNdBDqSFTZXW23cgLgAs8L9kFV39LyiU4bnTn" + ] + }, + "transactionIndex": 3, + "version": 0 + }, + "id": 1 +} diff --git a/packages/test-vectors/devnet/4NXs89.json b/packages/test-vectors/devnet/4NXs89.json new file mode 100644 index 0000000..05fabb3 --- /dev/null +++ b/packages/test-vectors/devnet/4NXs89.json @@ -0,0 +1,69 @@ +{ + "jsonrpc": "2.0", + "result": { + "blockTime": 1791632882, + "meta": { + "computeUnitsConsumed": 84546, + "costUnits": 85639, + "err": null, + "fee": 5000, + "innerInstructions": [], + "logMessages": [ + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr invoke [1]", + "Program log: Signed by CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "Program log: Memo (len 197): \"{\\\"p\\\":\\\"nosus-canary\\\",\\\"v\\\":1,\\\"t\\\":\\\"open\\\",\\\"note\\\":\\\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\\\",\\\"copy\\\":1,\\\"tag\\\":\\\"0x6ec7e19683ff70ce1d03ebf3df42242872f98407b47baada27b8cb50d934306e\\\"}\"", + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr consumed 84546 of 200000 compute units", + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr success" + ], + "postBalances": [ + 4999895000, + 41509609334 + ], + "postTokenBalances": [], + "preBalances": [ + 4999900000, + 41509609334 + ], + "preTokenBalances": [], + "rewards": [], + "status": { + "Ok": null + } + }, + "slot": 509530556, + "transaction": { + "message": { + "accountKeys": [ + { + "pubkey": "CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "signer": true, + "source": "transaction", + "writable": true + }, + { + "pubkey": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "signer": false, + "source": "transaction", + "writable": false + } + ], + "addressTableLookups": [], + "instructions": [ + { + "parsed": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\",\"copy\":1,\"tag\":\"0x6ec7e19683ff70ce1d03ebf3df42242872f98407b47baada27b8cb50d934306e\"}", + "program": "spl-memo", + "programId": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "stackHeight": 1 + } + ], + "recentBlockhash": "2D2Goyob1SvB8PEYNqjwGfs8FdJ4mHEMYs4mxzMSQy8f" + }, + "signatures": [ + "4NXs89eDP5hm2GyAkuA5rRDBQUNB5e6ssAChQJRCFGTYimyMDa3LmQRbcEVmaezQSXCx8kgt5GRkpUje59WqH2rc" + ] + }, + "transactionIndex": 5, + "version": 0 + }, + "id": 1 +} diff --git a/packages/test-vectors/devnet/62Frr2.json b/packages/test-vectors/devnet/62Frr2.json new file mode 100644 index 0000000..5634b2c --- /dev/null +++ b/packages/test-vectors/devnet/62Frr2.json @@ -0,0 +1,69 @@ +{ + "jsonrpc": "2.0", + "result": { + "blockTime": 1791632837, + "meta": { + "computeUnitsConsumed": 91949, + "costUnits": 93047, + "err": null, + "fee": 5000, + "innerInstructions": [], + "logMessages": [ + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr invoke [1]", + "Program log: Signed by CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "Program log: Memo (len 218): \"{\\\"p\\\":\\\"nosus-canary\\\",\\\"v\\\":1,\\\"t\\\":\\\"seal\\\",\\\"note\\\":\\\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\\\",\\\"copies\\\":10,\\\"hash\\\":\\\"0x40846d626dd4beb151497162ca5c1de105281a20d076223b76a44ab1d47962df\\\",\\\"exp\\\":1791719237}\"", + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr consumed 91949 of 200000 compute units", + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr success" + ], + "postBalances": [ + 4999905000, + 41509609334 + ], + "postTokenBalances": [], + "preBalances": [ + 4999910000, + 41509609334 + ], + "preTokenBalances": [], + "rewards": [], + "status": { + "Ok": null + } + }, + "slot": 509530368, + "transaction": { + "message": { + "accountKeys": [ + { + "pubkey": "CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "signer": true, + "source": "transaction", + "writable": true + }, + { + "pubkey": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "signer": false, + "source": "transaction", + "writable": false + } + ], + "addressTableLookups": [], + "instructions": [ + { + "parsed": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\",\"copies\":10,\"hash\":\"0x40846d626dd4beb151497162ca5c1de105281a20d076223b76a44ab1d47962df\",\"exp\":1791719237}", + "program": "spl-memo", + "programId": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "stackHeight": 1 + } + ], + "recentBlockhash": "DMmmhJAc7wUo9iozeGYotjnentLqav6HjB5copymG2hJ" + }, + "signatures": [ + "62Frr29RyPXhhUkAaxDLQHDKinMztPhrsYeokzvoiAAUjp9JBXbNUn3S6D4gX7QEqt2yfurqG54PAERb7fLKCskF" + ] + }, + "transactionIndex": 2, + "version": 0 + }, + "id": 1 +} diff --git a/packages/test-vectors/devnet/NwoJau.json b/packages/test-vectors/devnet/NwoJau.json new file mode 100644 index 0000000..29d93d7 --- /dev/null +++ b/packages/test-vectors/devnet/NwoJau.json @@ -0,0 +1,69 @@ +{ + "jsonrpc": "2.0", + "result": { + "blockTime": 1791631257, + "meta": { + "computeUnitsConsumed": 84546, + "costUnits": 85639, + "err": null, + "fee": 5000, + "innerInstructions": [], + "logMessages": [ + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr invoke [1]", + "Program log: Signed by CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "Program log: Memo (len 197): \"{\\\"p\\\":\\\"nosus-canary\\\",\\\"v\\\":1,\\\"t\\\":\\\"open\\\",\\\"note\\\":\\\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\\\",\\\"copy\\\":0,\\\"tag\\\":\\\"0x10947d1df8aaba2c25d2088b054593cfdafd46f959c89007447309960b4845e6\\\"}\"", + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr consumed 84546 of 200000 compute units", + "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr success" + ], + "postBalances": [ + 4999990000, + 41509609334 + ], + "postTokenBalances": [], + "preBalances": [ + 4999995000, + 41509609334 + ], + "preTokenBalances": [], + "rewards": [], + "status": { + "Ok": null + } + }, + "slot": 509523778, + "transaction": { + "message": { + "accountKeys": [ + { + "pubkey": "CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "signer": true, + "source": "transaction", + "writable": true + }, + { + "pubkey": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "signer": false, + "source": "transaction", + "writable": false + } + ], + "addressTableLookups": [], + "instructions": [ + { + "parsed": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copy\":0,\"tag\":\"0x10947d1df8aaba2c25d2088b054593cfdafd46f959c89007447309960b4845e6\"}", + "program": "spl-memo", + "programId": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "stackHeight": 1 + } + ], + "recentBlockhash": "81rte1Ja2nCdibyXqeEzJZFsAp7RP1t2wgBjjdygowLd" + }, + "signatures": [ + "NwoJauec9otkicaGf8yD6UechYgUnXRdYPqnuc5Kpn6uMYym6XVJcMmWdbVnwnRVncKKVgEyuZB2mR3T5REvdSr" + ] + }, + "transactionIndex": 10, + "version": 0 + }, + "id": 1 +} diff --git a/packages/test-vectors/receipts.json b/packages/test-vectors/receipts.json new file mode 100644 index 0000000..53c3613 --- /dev/null +++ b/packages/test-vectors/receipts.json @@ -0,0 +1,453 @@ +{ + "about": "NO SUS Canary receipt vectors, memo format v1. Both packages test against this file.", + "maxMemoBytes": 566, + "chainNoteId": [ + { + "noteId": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed", + "expected": "0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e" + }, + { + "noteId": "00000000-0000-4000-8000-000000000000", + "expected": "0x88538326b97d656f5d8f8cd20a2673e4621c615292f8ef03207faef39f93d7f7" + }, + { + "noteId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", + "expected": "0xbf3c93bbf98524532e883d50f2790461d21e2664f1d8b1448aeba7ab9c80d812" + } + ], + "deviceHash": [ + { + "deviceId": "7c9e6679-7425-40de-944b-e07fc1f90ae7", + "expected": "9738e16064bc6e9a5ac8505293475b0717e349efc66d42a058608d402a0b3372" + }, + { + "deviceId": "device-on-a-test-phone", + "expected": "db5d5e52631e9e113a27dbbf52d93cc2c4273e3f136bc44aa1968bea99c81924" + } + ], + "copyDigest": [ + { + "saltHex": "5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e", + "index": 0, + "copyText": "Lunch is at noon on Friday.", + "expected": "19c74fd9f2a8a2264ea8a8af015977085578380cd7272522b785e1fd15f42dab" + }, + { + "saltHex": "5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e", + "index": 1, + "copyText": "Lunch is at noon on Friday.​", + "expected": "5b183e08c2cf4d6dc49bfb52732e0fdb7b95ec80e22a03cebf72037e2ac79827" + }, + { + "saltHex": "5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e", + "index": 2, + "copyText": "Café ☕ at noon.", + "expected": "a1981e202f5edc1f9ee01fba89418946fbab343c1c60707e89a1e91e9e056867" + } + ], + "copiesHash": [ + { + "digests": [ + "19c74fd9f2a8a2264ea8a8af015977085578380cd7272522b785e1fd15f42dab", + "5b183e08c2cf4d6dc49bfb52732e0fdb7b95ec80e22a03cebf72037e2ac79827", + "a1981e202f5edc1f9ee01fba89418946fbab343c1c60707e89a1e91e9e056867" + ], + "expected": "0x7103d90f50d512f9f9ec27663bb1a9e15f5598d7f9e71395ed4197758a0754f4" + }, + { + "digests": [ + "19c74fd9f2a8a2264ea8a8af015977085578380cd7272522b785e1fd15f42dab", + "5b183e08c2cf4d6dc49bfb52732e0fdb7b95ec80e22a03cebf72037e2ac79827" + ], + "expected": "0x1c15eeda35f08e6c3f71856d299e32a91d33e5c6397078dbc14362a99d1e0735" + } + ], + "readerTag": [ + { + "tagSalt": "a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1", + "noteId": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed", + "copyIndex": 0, + "deviceHash": "9738e16064bc6e9a5ac8505293475b0717e349efc66d42a058608d402a0b3372", + "expected": "0x3d7f04addc9492ec9b75534e7174b076a746f33235bef0ee31e944b0894d4fab" + }, + { + "tagSalt": "a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1", + "noteId": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed", + "copyIndex": 2, + "deviceHash": "9738e16064bc6e9a5ac8505293475b0717e349efc66d42a058608d402a0b3372", + "expected": "0x5b95884239658bc8d460e497449fa024c892cabf1c90f2eaf4174917ce3b0c81" + } + ], + "sealMemo": [ + { + "name": "devnet 2BHqnu", + "input": { + "note": "0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40", + "copies": 3, + "hash": "0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8", + "exp": 1791634855 + }, + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}" + }, + { + "name": "devnet 62Frr2", + "input": { + "note": "0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d", + "copies": 10, + "hash": "0x40846d626dd4beb151497162ca5c1de105281a20d076223b76a44ab1d47962df", + "exp": 1791719237 + }, + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\",\"copies\":10,\"hash\":\"0x40846d626dd4beb151497162ca5c1de105281a20d076223b76a44ab1d47962df\",\"exp\":1791719237}" + }, + { + "name": "never expires", + "input": { + "note": "0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e", + "copies": 3, + "hash": "0x7103d90f50d512f9f9ec27663bb1a9e15f5598d7f9e71395ed4197758a0754f4", + "exp": 0 + }, + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e\",\"copies\":3,\"hash\":\"0x7103d90f50d512f9f9ec27663bb1a9e15f5598d7f9e71395ed4197758a0754f4\",\"exp\":0}" + }, + { + "name": "largest seal today (100 copies)", + "input": { + "note": "0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e", + "copies": 100, + "hash": "0x7103d90f50d512f9f9ec27663bb1a9e15f5598d7f9e71395ed4197758a0754f4", + "exp": 1791634855 + }, + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e\",\"copies\":100,\"hash\":\"0x7103d90f50d512f9f9ec27663bb1a9e15f5598d7f9e71395ed4197758a0754f4\",\"exp\":1791634855}" + } + ], + "openMemo": [ + { + "name": "devnet NwoJau", + "input": { + "note": "0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40", + "copy": 0, + "tag": "0x10947d1df8aaba2c25d2088b054593cfdafd46f959c89007447309960b4845e6" + }, + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copy\":0,\"tag\":\"0x10947d1df8aaba2c25d2088b054593cfdafd46f959c89007447309960b4845e6\"}" + }, + { + "name": "devnet 2b9SS9", + "input": { + "note": "0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d", + "copy": 0, + "tag": "0xe52417df0e5f0b104525ec1a583ec0bb64a71c2358a3e93d855b121172a4d10e" + }, + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\",\"copy\":0,\"tag\":\"0xe52417df0e5f0b104525ec1a583ec0bb64a71c2358a3e93d855b121172a4d10e\"}" + }, + { + "name": "devnet 4NXs89", + "input": { + "note": "0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d", + "copy": 1, + "tag": "0x6ec7e19683ff70ce1d03ebf3df42242872f98407b47baada27b8cb50d934306e" + }, + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\",\"copy\":1,\"tag\":\"0x6ec7e19683ff70ce1d03ebf3df42242872f98407b47baada27b8cb50d934306e\"}" + }, + { + "name": "copy 99", + "input": { + "note": "0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e", + "copy": 99, + "tag": "0x5b95884239658bc8d460e497449fa024c892cabf1c90f2eaf4174917ce3b0c81" + }, + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e\",\"copy\":99,\"tag\":\"0x5b95884239658bc8d460e497449fa024c892cabf1c90f2eaf4174917ce3b0c81\"}" + } + ], + "encodeErrors": [ + { + "name": "seal: uppercase note", + "kind": "seal", + "input": { + "note": "0xB8168EFCC5C17AFC454283C0E2237B39F5DC917D39AB0EB0F540F544B9878F2E", + "copies": 3, + "hash": "0x7103d90f50d512f9f9ec27663bb1a9e15f5598d7f9e71395ed4197758a0754f4", + "exp": 0 + }, + "error": "memo note must be 0x + 64 hex chars" + }, + { + "name": "seal: hash without 0x", + "kind": "seal", + "input": { + "note": "0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e", + "copies": 3, + "hash": "7103d90f50d512f9f9ec27663bb1a9e15f5598d7f9e71395ed4197758a0754f4", + "exp": 0 + }, + "error": "memo hash must be 0x + 64 hex chars" + }, + { + "name": "seal: negative copies", + "kind": "seal", + "input": { + "note": "0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e", + "copies": -1, + "hash": "0x7103d90f50d512f9f9ec27663bb1a9e15f5598d7f9e71395ed4197758a0754f4", + "exp": 0 + }, + "error": "memo copies must be a non-negative integer" + }, + { + "name": "seal: negative exp", + "kind": "seal", + "input": { + "note": "0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e", + "copies": 3, + "hash": "0x7103d90f50d512f9f9ec27663bb1a9e15f5598d7f9e71395ed4197758a0754f4", + "exp": -5 + }, + "error": "memo exp must be a non-negative integer" + }, + { + "name": "open: short tag", + "kind": "open", + "input": { + "note": "0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e", + "copy": 0, + "tag": "0xababababababababababababababababababababababababababababababab" + }, + "error": "memo tag must be 0x + 64 hex chars" + }, + { + "name": "open: negative copy", + "kind": "open", + "input": { + "note": "0xb8168efcc5c17afc454283c0e2237b39f5dc917d39ab0eb0f540f544b9878f2e", + "copy": -1, + "tag": "0x3d7f04addc9492ec9b75534e7174b076a746f33235bef0ee31e944b0894d4fab" + }, + "error": "memo copy must be a non-negative integer" + } + ], + "invalidMemos": [ + { + "name": "empty string", + "memo": "", + "error": "memo is not JSON" + }, + { + "name": "not JSON", + "memo": "hello", + "error": "memo is not JSON" + }, + { + "name": "truncated JSON", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855", + "error": "memo is not JSON" + }, + { + "name": "JSON array", + "memo": "[1,2]", + "error": "memo is not a JSON object" + }, + { + "name": "JSON null", + "memo": "null", + "error": "memo is not a JSON object" + }, + { + "name": "longer than 566 bytes", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"pad\":\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}", + "error": "memo is longer than 566 bytes" + }, + { + "name": "wrong p", + "memo": "{\"p\":\"nosus\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo p must be \"nosus-canary\"" + }, + { + "name": "missing p", + "memo": "{\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo p must be \"nosus-canary\"" + }, + { + "name": "v=2", + "memo": "{\"p\":\"nosus-canary\",\"v\":2,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo v must be 1" + }, + { + "name": "v as string", + "memo": "{\"p\":\"nosus-canary\",\"v\":\"1\",\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo v must be 1" + }, + { + "name": "unknown t", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"burn\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo t must be \"seal\" or \"open\"" + }, + { + "name": "extra key", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855,\"x\":1}", + "error": "memo keys must be p,v,t,note,copies,hash,exp in this order" + }, + { + "name": "missing key (seal exp)", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\"}", + "error": "memo keys must be p,v,t,note,copies,hash,exp in this order" + }, + { + "name": "missing key (open tag)", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copy\":0}", + "error": "memo keys must be p,v,t,note,copy,tag in this order" + }, + { + "name": "keys out of order", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"copies\":3,\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo keys must be p,v,t,note,copies,hash,exp in this order" + }, + { + "name": "open with seal keys", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo keys must be p,v,t,note,copy,tag in this order" + }, + { + "name": "uppercase hex note", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xE5BBE8D0602B1DFDA55EA516343E6A5064D021C37E6B7BA648BC5719AEA1FC40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo note must be 0x + 64 hex chars" + }, + { + "name": "uppercase 0X prefix", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copy\":0,\"tag\":\"0X10947d1df8aaba2c25d2088b054593cfdafd46f959c89007447309960b4845e6\"}", + "error": "memo tag must be 0x + 64 hex chars" + }, + { + "name": "short hex hash", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271\",\"exp\":1791634855}", + "error": "memo hash must be 0x + 64 hex chars" + }, + { + "name": "note as number", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":12,\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo note must be 0x + 64 hex chars" + }, + { + "name": "negative copies", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":-3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo copies must be a non-negative integer" + }, + { + "name": "float copies", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":1.5,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo copies must be a non-negative integer" + }, + { + "name": "negative copy", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copy\":-1,\"tag\":\"0x10947d1df8aaba2c25d2088b054593cfdafd46f959c89007447309960b4845e6\"}", + "error": "memo copy must be a non-negative integer" + }, + { + "name": "float exp", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855.5}", + "error": "memo exp must be a non-negative integer" + }, + { + "name": "copies as string", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":\"3\",\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo copies must be a non-negative integer" + }, + { + "name": "exp above 2^53", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":9007199254740993}", + "error": "memo exp must be a non-negative integer" + }, + { + "name": "integer written as 3.0", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3.0,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo is not in canonical form" + }, + { + "name": "integer written as 3e0", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3e0,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo is not in canonical form" + }, + { + "name": "v written as 1.0", + "memo": "{\"p\":\"nosus-canary\",\"v\":1.0,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo is not in canonical form" + }, + { + "name": "whitespace", + "memo": "{\"p\":\"nosus-canary\",\"v\": 1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}", + "error": "memo is not in canonical form" + }, + { + "name": "trailing newline", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}\n", + "error": "memo is not in canonical form" + }, + { + "name": "duplicate key", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855,\"p\":\"nosus-canary\"}", + "error": "memo is not in canonical form" + } + ], + "rawMemoInstruction": { + "programId": "Memo4c2pN8afCj432Lb7RMVKi9PbQnnW7ewFFaV3oAH", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copy\":0,\"tag\":\"0x10947d1df8aaba2c25d2088b054593cfdafd46f959c89007447309960b4845e6\"}", + "data": "Z7gZmhkMcFnC3TVXoi3681EbSqDfPuwjedJgqq7RUjdYgAz8VbnbKPJ1zFaos13xmGoS1Srt5vFCBRvx1qHiLLN4Ph2oW7Rvxs1nNANHUPiADwEYgbyQBjpG2ZBuSFgyDG57qPSDKvaUhjpGkDjJDFaUDJQmjVkiTz9Bn9q8WbMuUgD9oacePZsftzD4QsoEeiUXVTA5bE19kkTT4T3ye8gRwxP9m6EsxgrTrvmJ9j7mxvhNkFeNcs2JjEkYUv7JNJ9e3tXeJVVgg" + }, + "explorerTxUrl": [ + { + "signature": "2BHqnuCxYyemfegHkncgTsQyMPjpyB9boD1XqYfD1Wtbcf51Fpy3y264UwGhnvRKtcxFKCaSAzHxLrDwFRk512bQ", + "cluster": "devnet", + "expected": "https://explorer.solana.com/tx/2BHqnuCxYyemfegHkncgTsQyMPjpyB9boD1XqYfD1Wtbcf51Fpy3y264UwGhnvRKtcxFKCaSAzHxLrDwFRk512bQ?cluster=devnet" + }, + { + "signature": "2BHqnuCxYyemfegHkncgTsQyMPjpyB9boD1XqYfD1Wtbcf51Fpy3y264UwGhnvRKtcxFKCaSAzHxLrDwFRk512bQ", + "cluster": "mainnet-beta", + "expected": "https://explorer.solana.com/tx/2BHqnuCxYyemfegHkncgTsQyMPjpyB9boD1XqYfD1Wtbcf51Fpy3y264UwGhnvRKtcxFKCaSAzHxLrDwFRk512bQ" + } + ], + "devnet": [ + { + "signature": "2BHqnuCxYyemfegHkncgTsQyMPjpyB9boD1XqYfD1Wtbcf51Fpy3y264UwGhnvRKtcxFKCaSAzHxLrDwFRk512bQ", + "fixture": "devnet/2BHqnu.json", + "slot": 509523773, + "blockTime": 1791631256, + "feePayer": "CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "memoProgram": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copies\":3,\"hash\":\"0x2a1ab6e3b5fae89ea53b689e88c9f6560d2b33711e36cc1d4524df6c680271e8\",\"exp\":1791634855}" + }, + { + "signature": "NwoJauec9otkicaGf8yD6UechYgUnXRdYPqnuc5Kpn6uMYym6XVJcMmWdbVnwnRVncKKVgEyuZB2mR3T5REvdSr", + "fixture": "devnet/NwoJau.json", + "slot": 509523778, + "blockTime": 1791631257, + "feePayer": "CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "memoProgram": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0xe5bbe8d0602b1dfda55ea516343e6a5064d021c37e6b7ba648bc5719aea1fc40\",\"copy\":0,\"tag\":\"0x10947d1df8aaba2c25d2088b054593cfdafd46f959c89007447309960b4845e6\"}" + }, + { + "signature": "62Frr29RyPXhhUkAaxDLQHDKinMztPhrsYeokzvoiAAUjp9JBXbNUn3S6D4gX7QEqt2yfurqG54PAERb7fLKCskF", + "fixture": "devnet/62Frr2.json", + "slot": 509530368, + "blockTime": 1791632837, + "feePayer": "CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "memoProgram": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"seal\",\"note\":\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\",\"copies\":10,\"hash\":\"0x40846d626dd4beb151497162ca5c1de105281a20d076223b76a44ab1d47962df\",\"exp\":1791719237}" + }, + { + "signature": "2b9SS9RhwPvMrsDR5upY5a9w3gk7E2zgV4jmC69QTtZseBMmguXxNdBDqSFTZXW23cgLgAs8L9kFV39LyiU4bnTn", + "fixture": "devnet/2b9SS9.json", + "slot": 509530464, + "blockTime": 1791632860, + "feePayer": "CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "memoProgram": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\",\"copy\":0,\"tag\":\"0xe52417df0e5f0b104525ec1a583ec0bb64a71c2358a3e93d855b121172a4d10e\"}" + }, + { + "signature": "4NXs89eDP5hm2GyAkuA5rRDBQUNB5e6ssAChQJRCFGTYimyMDa3LmQRbcEVmaezQSXCx8kgt5GRkpUje59WqH2rc", + "fixture": "devnet/4NXs89.json", + "slot": 509530556, + "blockTime": 1791632882, + "feePayer": "CCD4SUQt4No2QNidpCuNAxJZXsqY1KhxkpfkuphueQJx", + "memoProgram": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", + "memo": "{\"p\":\"nosus-canary\",\"v\":1,\"t\":\"open\",\"note\":\"0x56f7956802f494824332309f033188a8850e78b4aed1eca6b1d923534315831d\",\"copy\":1,\"tag\":\"0x6ec7e19683ff70ce1d03ebf3df42242872f98407b47baada27b8cb50d934306e\"}" + } + ] +} diff --git a/readme.config.json b/readme.config.json deleted file mode 100644 index 7eacca6..0000000 --- a/readme.config.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "liveUrl": "http://shubham-sahu.me/nosus-canary/", - "repoUrl": "https://github.com/https-shubhamsahu/nosus-canary", - "contractTestnet": "0xb1a1858866122c84cf97861ca815fb070e010e68", - "contractMainnet": "", - "explorerTestnet": "https://testnet.monadscan.com", - "explorerMainnet": "https://monadscan.com", - "verified": true, - "customDomain": true, - "demoVideoUrl": "", - "adVideoUrl": "", - "xPostUrl": "", - "team": [ - "Shubham Sahu" - ], - "event": "MONAD BLITZ MUMBAI V4", - "eventName": "Monad Blitz Mumbai V4", - "verifiedUrl": "https://sourcify.dev/server/repo-ui/10143/0xb1a1858866122c84cf97861ca815fb070e010e68" -} \ No newline at end of file diff --git a/supabase/.gitignore b/supabase/.gitignore deleted file mode 100644 index ad9264f..0000000 --- a/supabase/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Supabase -.branches -.temp - -# dotenvx -.env.keys -.env.local -.env.*.local diff --git a/supabase/AGENTS.md b/supabase/AGENTS.md deleted file mode 100644 index 2948056..0000000 --- a/supabase/AGENTS.md +++ /dev/null @@ -1,15 +0,0 @@ -# Supabase scope - -Read root `AGENTS.md` and `README.md` first. - -- This is a separate experiment backend; production NO SUS project IDs, URLs, - keys, migrations, and buckets are forbidden here. -- Create new migrations with the Supabase CLI. Applied migrations are - append-only. -- Enable RLS on every table and deny browser-table access by default. Use - narrow server routes and the server-only service role only when necessary. -- Never place plaintext, decryption keys, Lit session signatures, or secrets in - Postgres, Storage metadata, logs, or database functions. - -Would you like to finalize today's work? If yes, say whether to verify only, -build a target, or deploy a named target. diff --git a/supabase/README.md b/supabase/README.md deleted file mode 100644 index 6af18d4..0000000 --- a/supabase/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Supabase backend - -This directory is for a **new, isolated** Supabase project for the Monad -experiment. It must never be linked to production NO SUS. - -## Purpose - -The backend stores encrypted payloads, Lit metadata, public receipt metadata, -and event-indexing records. It does not accept, derive, log, or return -plaintext or decryption keys. - -## Entry points - -- `migrations/20260916082811_experiment_drops.sql` — initial RLS-protected - schema and private encrypted-drop storage bucket -- `../web/src/app/api/` — server-only, allow-listed read API for the live wall - and receipt verifier - -## Rules - -- Migrations are append-only. Make a new migration with `supabase migration new - `; never rewrite one that has been applied. -- RLS stays enabled. Browser clients receive only the publishable key; the - service-role key is server-only. -- Do not apply this migration, link a project, create a bucket remotely, or - store real notes until the root finalization gate is explicitly approved. diff --git a/supabase/config.toml b/supabase/config.toml deleted file mode 100644 index b3ce41b..0000000 --- a/supabase/config.toml +++ /dev/null @@ -1,413 +0,0 @@ -# For detailed configuration reference documentation, visit: -# https://supabase.com/docs/guides/local-development/cli/config -# A string used to distinguish different Supabase projects on the same host. Defaults to the -# working directory name when running `supabase init`. -project_id = "nosus-monad" - -[api] -enabled = true -# Port to use for the API URL. -port = 54321 -# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API -# endpoints. `public` and `graphql_public` schemas are included by default. -schemas = ["public", "graphql_public"] -# Extra schemas to add to the search_path of every request. -extra_search_path = ["public", "extensions"] -# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size -# for accidental or malicious requests. -max_rows = 1000 -# Controls whether new tables, views, sequences and functions created in the `public` schema by -# `postgres` are reachable through the Data API roles (`anon`, `authenticated`, `service_role`) -# without explicit GRANTs. Leave unset today to preserve local behaviour. The implicit default -# flips to `false` on 2026-05-30 to match the new cloud default, and the field is removed in -# 2026-10-30 once the always-revoked behaviour is permanent. Set to `false` to opt in early. -# auto_expose_new_tables = false - -[api.tls] -# Enable HTTPS endpoints locally using a self-signed certificate. -enabled = false -# Paths to self-signed certificate pair. -# cert_path = "../certs/my-cert.pem" -# key_path = "../certs/my-key.pem" - -[db] -# Port to use for the local database URL. -port = 54322 -# Port used by db diff command to initialize the shadow database. -shadow_port = 54320 -# Maximum amount of time to wait for health check when starting the local database. -health_timeout = "2m" -# The database major version to use. This has to be the same as your remote database's. Run `SHOW -# server_version;` on the remote database to check. -major_version = 17 - -[db.pooler] -enabled = false -# Port to use for the local connection pooler. -port = 54329 -# Specifies when a server connection can be reused by other clients. -# Configure one of the supported pooler modes: `transaction`, `session`. -pool_mode = "transaction" -# How many server connections to allow per user/database pair. -default_pool_size = 20 -# Maximum number of client connections allowed. -max_client_conn = 100 - -# [db.vault] -# secret_key = "env(SECRET_VALUE)" - -[db.migrations] -# If disabled, migrations will be skipped during a db push or reset. -enabled = true -# Specifies an ordered list of schema files that describe your database. -# Supports glob patterns relative to supabase directory: "./schemas/*.sql" -schema_paths = [] - -[db.seed] -# If enabled, seeds the database after migrations during a db reset. -enabled = true -# Specifies an ordered list of seed files to load during db reset. -# Supports glob patterns relative to supabase directory: "./seeds/*.sql" -sql_paths = ["./seed.sql"] - -[db.network_restrictions] -# Enable management of network restrictions. -enabled = false -# List of IPv4 CIDR blocks allowed to connect to the database. -# Defaults to allow all IPv4 connections. Set empty array to block all IPs. -allowed_cidrs = ["0.0.0.0/0"] -# List of IPv6 CIDR blocks allowed to connect to the database. -# Defaults to allow all IPv6 connections. Set empty array to block all IPs. -allowed_cidrs_v6 = ["::/0"] - -# Uncomment to reject non-secure connections to the database. -# [db.ssl_enforcement] -# enabled = true - -[realtime] -enabled = true -# Bind realtime via either IPv4 or IPv6. (default: IPv4) -# ip_version = "IPv6" -# The maximum length in bytes of HTTP request headers. (default: 4096) -# max_header_length = 4096 - -[studio] -enabled = true -# Port to use for Supabase Studio. -port = 54323 -# External URL of the API server that frontend connects to. -api_url = "http://127.0.0.1" -# OpenAI API Key to use for Supabase AI in the Supabase Studio. -openai_api_key = "env(OPENAI_API_KEY)" - -# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they -# are monitored, and you can view the emails that would have been sent from the web interface. -[inbucket] -enabled = true -# Port to use for the email testing server web interface. -port = 54324 -# Uncomment to expose additional ports for testing user applications that send emails. -# smtp_port = 54325 -# pop3_port = 54326 -# admin_email = "admin@email.com" -# sender_name = "Admin" - -[storage] -enabled = true -# The maximum file size allowed (e.g. "5MB", "500KB"). -file_size_limit = "50MiB" - -# Uncomment to configure local storage buckets -# [storage.buckets.images] -# public = false -# file_size_limit = "50MiB" -# allowed_mime_types = ["image/png", "image/jpeg"] -# objects_path = "./images" - -# Allow connections via S3 compatible clients -[storage.s3_protocol] -enabled = true - -# Image transformation API is available to Supabase Pro plan. -# [storage.image_transformation] -# enabled = true - -# Store analytical data in S3 for running ETL jobs over Iceberg Catalog -# This feature is only available on the hosted platform. -[storage.analytics] -enabled = false -max_namespaces = 5 -max_tables = 10 -max_catalogs = 2 - -# Analytics Buckets is available to Supabase Pro plan. -# [storage.analytics.buckets.my-warehouse] - -# Store vector embeddings in S3 for large and durable datasets -[storage.vector] -enabled = true -max_buckets = 10 -max_indexes = 5 - -# Vector Buckets is available to Supabase Pro plan. -# [storage.vector.buckets.documents-openai] - -[auth] -enabled = true -# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used -# in emails. -site_url = "http://127.0.0.1:3000" -# The public URL that Auth serves on. Defaults to the API external URL with `/auth/v1` appended. -# external_url = "" -# A list of *exact* URLs that auth providers are permitted to redirect to post authentication. -additional_redirect_urls = ["https://127.0.0.1:3000"] -# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week). -jwt_expiry = 3600 -# JWT issuer URL. If not set, defaults to auth.external_url. -# jwt_issuer = "" -# Path to JWT signing key. DO NOT commit your signing keys file to git. -# signing_keys_path = "./signing_keys.json" -# If disabled, the refresh token will never expire. -enable_refresh_token_rotation = true -# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds. -# Requires enable_refresh_token_rotation = true. -refresh_token_reuse_interval = 10 -# Allow/disallow new user signups to your project. -enable_signup = true -# Allow/disallow anonymous sign-ins to your project. -enable_anonymous_sign_ins = false -# Allow/disallow testing manual linking of accounts -enable_manual_linking = false -# Passwords shorter than this value will be rejected as weak. Minimum 6, recommended 8 or more. -minimum_password_length = 6 -# Passwords that do not meet the following requirements will be rejected as weak. Supported values -# are: `letters_digits`, `lower_upper_letters_digits`, `lower_upper_letters_digits_symbols` -password_requirements = "" - -# Configure passkey sign-ins. -# [auth.passkey] -# enabled = false - -# Configure WebAuthn relying party settings (required when passkey is enabled). -# [auth.webauthn] -# rp_display_name = "Supabase" -# rp_id = "localhost" -# rp_origins = ["http://127.0.0.1:3000"] - -[auth.rate_limit] -# Number of emails that can be sent per hour. Requires auth.email.smtp to be enabled. -email_sent = 2 -# Number of SMS messages that can be sent per hour. Requires auth.sms to be enabled. -sms_sent = 30 -# Number of anonymous sign-ins that can be made per hour per IP address. Requires enable_anonymous_sign_ins = true. -anonymous_users = 30 -# Number of sessions that can be refreshed in a 5 minute interval per IP address. -token_refresh = 150 -# Number of sign up and sign-in requests that can be made in a 5 minute interval per IP address (excludes anonymous users). -sign_in_sign_ups = 30 -# Number of OTP / Magic link verifications that can be made in a 5 minute interval per IP address. -token_verifications = 30 -# Number of Web3 logins that can be made in a 5 minute interval per IP address. -web3 = 30 - -# Configure one of the supported captcha providers: `hcaptcha`, `turnstile`. -# [auth.captcha] -# enabled = true -# provider = "hcaptcha" -# secret = "" - -[auth.email] -# Allow/disallow new user signups via email to your project. -enable_signup = true -# If enabled, a user will be required to confirm any email change on both the old, and new email -# addresses. If disabled, only the new email is required to confirm. -double_confirm_changes = true -# If enabled, users need to confirm their email address before signing in. -enable_confirmations = false -# If enabled, users will need to reauthenticate or have logged in recently to change their password. -secure_password_change = false -# Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email. -max_frequency = "1s" -# Number of characters used in the email OTP. -otp_length = 6 -# Number of seconds before the email OTP expires (defaults to 1 hour). -otp_expiry = 3600 - -# Use a production-ready SMTP server -# [auth.email.smtp] -# enabled = true -# host = "smtp.sendgrid.net" -# port = 587 -# user = "apikey" -# pass = "env(SENDGRID_API_KEY)" -# admin_email = "admin@email.com" -# sender_name = "Admin" - -# Uncomment to customize email template -# [auth.email.template.invite] -# subject = "You have been invited" -# content_path = "./supabase/templates/invite.html" - -# Uncomment to customize notification email template -# [auth.email.notification.password_changed] -# enabled = true -# subject = "Your password has been changed" -# content_path = "./templates/password_changed_notification.html" - -[auth.sms] -# Allow/disallow new user signups via SMS to your project. -enable_signup = false -# If enabled, users need to confirm their phone number before signing in. -enable_confirmations = false -# Template for sending OTP to users -template = "Your code is {{ `{{ .Code }}` }}" -# Controls the minimum amount of time that must pass before sending another sms otp. -max_frequency = "5s" - -# Use pre-defined map of phone number to OTP for testing. -# [auth.sms.test_otp] -# 4152127777 = "123456" - -# Configure logged in session timeouts. -# [auth.sessions] -# Force log out after the specified duration. -# timebox = "24h" -# Force log out if the user has been inactive longer than the specified duration. -# inactivity_timeout = "8h" - -# This hook runs before a new user is created and allows developers to reject the request based on the incoming user object. -# [auth.hook.before_user_created] -# enabled = true -# uri = "pg-functions://postgres/auth/before-user-created-hook" - -# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used. -# [auth.hook.custom_access_token] -# enabled = true -# uri = "pg-functions:////" - -# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`. -[auth.sms.twilio] -enabled = false -account_sid = "" -message_service_sid = "" -# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead: -auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)" - -# Multi-factor-authentication is available to Supabase Pro plan. -[auth.mfa] -# Control how many MFA factors can be enrolled at once per user. -max_enrolled_factors = 10 - -# Control MFA via App Authenticator (TOTP) -[auth.mfa.totp] -enroll_enabled = false -verify_enabled = false - -# Configure MFA via Phone Messaging -[auth.mfa.phone] -enroll_enabled = false -verify_enabled = false -otp_length = 6 -template = "Your code is {{ `{{ .Code }}` }}" -max_frequency = "5s" - -# Configure MFA via WebAuthn -# [auth.mfa.web_authn] -# enroll_enabled = true -# verify_enabled = true - -# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`, -# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`, -# `twitter`, `x`, `slack`, `spotify`, `workos`, `zoom`. -[auth.external.apple] -enabled = false -client_id = "" -# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead: -secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)" -# Overrides the default auth callback URL derived from auth.external_url. -redirect_uri = "" -# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure, -# or any other third-party OIDC providers. -url = "" -# If enabled, the nonce check will be skipped. Required for local sign in with Google auth. -skip_nonce_check = false -# If enabled, it will allow the user to successfully authenticate when the provider does not return an email address. -email_optional = false - -# Allow Solana wallet holders to sign in to your project via the Sign in with Solana (SIWS, EIP-4361) standard. -# You can configure "web3" rate limit in the [auth.rate_limit] section and set up [auth.captcha] if self-hosting. -[auth.web3.solana] -enabled = false - -# Use Firebase Auth as a third-party provider alongside Supabase Auth. -[auth.third_party.firebase] -enabled = false -# project_id = "my-firebase-project" - -# Use Auth0 as a third-party provider alongside Supabase Auth. -[auth.third_party.auth0] -enabled = false -# tenant = "my-auth0-tenant" -# tenant_region = "us" - -# Use AWS Cognito (Amplify) as a third-party provider alongside Supabase Auth. -[auth.third_party.aws_cognito] -enabled = false -# user_pool_id = "my-user-pool-id" -# user_pool_region = "us-east-1" - -# Use Clerk as a third-party provider alongside Supabase Auth. -[auth.third_party.clerk] -enabled = false -# Obtain from https://clerk.com/setup/supabase -# domain = "example.clerk.accounts.dev" - -# OAuth server configuration -[auth.oauth_server] -# Enable OAuth server functionality -enabled = false -# Path for OAuth consent flow UI -authorization_url_path = "/oauth/consent" -# Allow dynamic client registration -allow_dynamic_registration = false - -[edge_runtime] -enabled = true -# Supported request policies: `oneshot`, `per_worker`. -# `per_worker` (default) — enables hot reload during local development. -# `oneshot` — fallback mode if hot reload causes issues (e.g. in large repos or with symlinks). -policy = "per_worker" -# Port to attach the Chrome inspector for debugging edge functions. -inspector_port = 8083 -# The Deno major version to use. -deno_version = 2 - -# [edge_runtime.secrets] -# secret_key = "env(SECRET_VALUE)" - -[analytics] -enabled = true -port = 54327 -# Configure one of the supported backends: `postgres`, `bigquery`. -backend = "postgres" - -# Experimental features may be deprecated any time -[experimental] -# Configures Postgres storage engine to use OrioleDB (S3) -orioledb_version = "" -# Configures S3 bucket URL, eg. .s3-.amazonaws.com -s3_host = "env(S3_HOST)" -# Configures S3 bucket region, eg. us-east-1 -s3_region = "env(S3_REGION)" -# Configures AWS_ACCESS_KEY_ID for S3 bucket -s3_access_key = "env(S3_ACCESS_KEY)" -# Configures AWS_SECRET_ACCESS_KEY for S3 bucket -s3_secret_key = "env(S3_SECRET_KEY)" - -# [experimental.pgdelta] -# When enabled, pg-delta becomes the active engine for supported schema flows. -# enabled = false -# Directory under `supabase/` where declarative files are written. -# declarative_schema_path = "./database" -# JSON string passed through to pg-delta SQL formatting. -# format_options = "{\"keywordCase\":\"upper\",\"indent\":2,\"maxWidth\":80,\"commaStyle\":\"trailing\"}" diff --git a/supabase/migrations/20260916082811_experiment_drops.sql b/supabase/migrations/20260916082811_experiment_drops.sql deleted file mode 100644 index 175a2f7..0000000 --- a/supabase/migrations/20260916082811_experiment_drops.sql +++ /dev/null @@ -1,69 +0,0 @@ --- NO SUS — Monad Experiment. Separate project only; never apply to production NO SUS. --- The browser never writes these tables directly. Server-side event indexing and --- encrypted-payload persistence use the service role after on-chain validation. - -create table if not exists public.experiment_drops ( - id text primary key check (id ~ '^0x[0-9a-f]{64}$'), - sender_wallet text not null check (sender_wallet ~ '^0x[0-9a-f]{40}$'), - recipient_wallet text check (recipient_wallet is null or recipient_wallet ~ '^0x[0-9a-f]{40}$'), - opener_wallet text check (opener_wallet is null or opener_wallet ~ '^0x[0-9a-f]{40}$'), - ciphertext_digest text not null check (ciphertext_digest ~ '^0x[0-9a-f]{64}$'), - ciphertext_payload text not null, - lit_metadata jsonb not null check (jsonb_typeof(lit_metadata) = 'object'), - storage_path text unique, - expires_at timestamptz, - sealed_tx_hash text unique check (sealed_tx_hash is null or sealed_tx_hash ~ '^0x[0-9a-f]{64}$'), - opened_tx_hash text unique check (opened_tx_hash is null or opened_tx_hash ~ '^0x[0-9a-f]{64}$'), - created_at timestamptz not null default now(), - opened_at timestamptz, - constraint acknowledged_drop_has_opener check ( - (opened_at is null and opener_wallet is null and opened_tx_hash is null) - or (opened_at is not null and opener_wallet is not null and opened_tx_hash is not null) - ) -); - -create table if not exists public.experiment_drop_events ( - id bigint generated always as identity primary key, - drop_id text not null references public.experiment_drops(id) on delete cascade, - event_type text not null check (event_type in ('sealed', 'opened')), - actor_wallet text not null check (actor_wallet ~ '^0x[0-9a-f]{40}$'), - transaction_hash text not null check (transaction_hash ~ '^0x[0-9a-f]{64}$'), - block_number bigint not null check (block_number >= 0), - event_at timestamptz not null default now(), - unique (transaction_hash, event_type) -); - -create index if not exists experiment_drops_created_at_idx - on public.experiment_drops (created_at desc); -create index if not exists experiment_drops_opened_at_idx - on public.experiment_drops (opened_at desc nulls last); -create index if not exists experiment_drop_events_drop_id_idx - on public.experiment_drop_events (drop_id, event_at desc); - -alter table public.experiment_drops enable row level security; -alter table public.experiment_drop_events enable row level security; - --- No anon/authenticated policy is intentional. The only browser-safe reads are --- the explicit, allow-listed Next.js routes; service-role callers bypass RLS. -revoke all on table public.experiment_drops from anon, authenticated; -revoke all on table public.experiment_drop_events from anon, authenticated; - -insert into storage.buckets (id, name, public, file_size_limit, allowed_mime_types) -values ( - 'encrypted-drops', - 'encrypted-drops', - false, - 1048576, - array['application/octet-stream', 'application/json'] -) -on conflict (id) do update set - public = excluded.public, - file_size_limit = excluded.file_size_limit, - allowed_mime_types = excluded.allowed_mime_types; - --- Private by default: no storage.objects policies are created for anon or --- authenticated. The server validates then uses the service role for writes. -comment on table public.experiment_drops is - 'Encrypted-drop metadata for the Monad testnet experiment. Never stores plaintext or decryption keys.'; -comment on table public.experiment_drop_events is - 'Indexed Sealed and OpenAcknowledged events for the public Receipt Wall.'; diff --git a/tool/build-backend-bootstrap.mjs b/tool/build-backend-bootstrap.mjs index 73065f8..ee16177 100644 --- a/tool/build-backend-bootstrap.mjs +++ b/tool/build-backend-bootstrap.mjs @@ -12,7 +12,6 @@ sql = sql.replaceAll('rxfnazmusofikwaggntb.supabase.co', 'ffidvfguojalzpclipzi.s // drops it. Skip only its search_path adjustment when it does not exist. sql = sql.replace('ALTER FUNCTION public.revoke_device(uuid) SET search_path = public;', "DO $bootstrap$ BEGIN IF to_regprocedure('public.revoke_device(uuid)') IS NOT NULL THEN ALTER FUNCTION public.revoke_device(uuid) SET search_path = public; END IF; END $bootstrap$;"); -sql += '\n' + readFileSync(resolve(root, 'supabase/migrations/20260916082811_experiment_drops.sql'), 'utf8'); if (sql.includes('rxfnazmusofikwaggntb.supabase.co')) throw new Error('Production URL in bootstrap'); const output = resolve(root, 'app/supabase/.temp/experiment-bootstrap.sql'); mkdirSync(dirname(output), { recursive: true }); diff --git a/tool/build-readme.mjs b/tool/build-readme.mjs deleted file mode 100644 index 7844f16..0000000 --- a/tool/build-readme.mjs +++ /dev/null @@ -1,675 +0,0 @@ -#!/usr/bin/env node -// Builds the retro README (black, paper and orange only) for NO SUS Canary: README.md + animated SVGs. -// -// node tool/build-readme.mjs [config=readme.config.json] [outDir=.] -// -// Edit readme.config.json (live URL, repo URL, contract address, links) and re-run. -// Everything is drawn with shapes (a built-in 5x7 pixel font), because GitHub -// shows SVGs as images: no JavaScript and no external fonts, but CSS animation -// works. Every animation stops under prefers-reduced-motion, and the static -// frame always shows the finished state, so no text is ever hidden. - -import fs from 'node:fs'; -import path from 'node:path'; - -const cfgPath = process.argv[2] ?? 'readme.config.json'; -const outDir = process.argv[3] ?? '.'; -const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf8')); -const assetDir = path.join(outDir, 'assets', 'readme'); -fs.mkdirSync(assetDir, { recursive: true }); - -// ---------------------------------------------------------------- palette -// Three colours, nothing else: black ink, paper and NO SUS orange. -const INK = '#141414'; -const PAPER = '#FAF6EC'; -const ORANGE = '#F28C28'; - -// ---------------------------------------------------------------- pixel font (5x7, uppercase) -const FONT = { - 'A': ['.###.', '#...#', '#...#', '#####', '#...#', '#...#', '#...#'], - 'B': ['####.', '#...#', '#...#', '####.', '#...#', '#...#', '####.'], - 'C': ['.###.', '#...#', '#....', '#....', '#....', '#...#', '.###.'], - 'D': ['####.', '#...#', '#...#', '#...#', '#...#', '#...#', '####.'], - 'E': ['#####', '#....', '#....', '####.', '#....', '#....', '#####'], - 'F': ['#####', '#....', '#....', '####.', '#....', '#....', '#....'], - 'G': ['.###.', '#...#', '#....', '#.###', '#...#', '#...#', '.####'], - 'H': ['#...#', '#...#', '#...#', '#####', '#...#', '#...#', '#...#'], - 'I': ['.###.', '..#..', '..#..', '..#..', '..#..', '..#..', '.###.'], - 'J': ['..###', '...#.', '...#.', '...#.', '...#.', '#..#.', '.##..'], - 'K': ['#...#', '#..#.', '#.#..', '##...', '#.#..', '#..#.', '#...#'], - 'L': ['#....', '#....', '#....', '#....', '#....', '#....', '#####'], - 'M': ['#...#', '##.##', '#.#.#', '#.#.#', '#...#', '#...#', '#...#'], - 'N': ['#...#', '#...#', '##..#', '#.#.#', '#..##', '#...#', '#...#'], - 'O': ['.###.', '#...#', '#...#', '#...#', '#...#', '#...#', '.###.'], - 'P': ['####.', '#...#', '#...#', '####.', '#....', '#....', '#....'], - 'Q': ['.###.', '#...#', '#...#', '#...#', '#.#.#', '#..#.', '.##.#'], - 'R': ['####.', '#...#', '#...#', '####.', '#.#..', '#..#.', '#...#'], - 'S': ['.####', '#....', '#....', '.###.', '....#', '....#', '####.'], - 'T': ['#####', '..#..', '..#..', '..#..', '..#..', '..#..', '..#..'], - 'U': ['#...#', '#...#', '#...#', '#...#', '#...#', '#...#', '.###.'], - 'V': ['#...#', '#...#', '#...#', '#...#', '#...#', '.#.#.', '..#..'], - 'W': ['#...#', '#...#', '#...#', '#.#.#', '#.#.#', '#.#.#', '.#.#.'], - 'X': ['#...#', '#...#', '.#.#.', '..#..', '.#.#.', '#...#', '#...#'], - 'Y': ['#...#', '#...#', '.#.#.', '..#..', '..#..', '..#..', '..#..'], - 'Z': ['#####', '....#', '...#.', '..#..', '.#...', '#....', '#####'], - '0': ['.###.', '#...#', '#..##', '#.#.#', '##..#', '#...#', '.###.'], - '1': ['..#..', '.##..', '..#..', '..#..', '..#..', '..#..', '.###.'], - '2': ['.###.', '#...#', '....#', '...#.', '..#..', '.#...', '#####'], - '3': ['####.', '....#', '....#', '.###.', '....#', '....#', '####.'], - '4': ['...#.', '..##.', '.#.#.', '#..#.', '#####', '...#.', '...#.'], - '5': ['#####', '#....', '####.', '....#', '....#', '#...#', '.###.'], - '6': ['.###.', '#....', '#....', '####.', '#...#', '#...#', '.###.'], - '7': ['#####', '....#', '...#.', '..#..', '.#...', '.#...', '.#...'], - '8': ['.###.', '#...#', '#...#', '.###.', '#...#', '#...#', '.###.'], - '9': ['.###.', '#...#', '#...#', '.####', '....#', '....#', '.###.'], - ' ': ['.....', '.....', '.....', '.....', '.....', '.....', '.....'], - '.': ['.....', '.....', '.....', '.....', '.....', '.##..', '.##..'], - ',': ['.....', '.....', '.....', '.....', '.##..', '..#..', '.#...'], - ':': ['.....', '.##..', '.##..', '.....', '.##..', '.##..', '.....'], - '-': ['.....', '.....', '.....', '.###.', '.....', '.....', '.....'], - '!': ['..#..', '..#..', '..#..', '..#..', '..#..', '.....', '..#..'], - '?': ['.###.', '#...#', '....#', '...#.', '..#..', '.....', '..#..'], - '/': ['....#', '....#', '...#.', '..#..', '.#...', '#....', '#....'], - '#': ['.#.#.', '.#.#.', '#####', '.#.#.', '#####', '.#.#.', '.#.#.'], - '>': ['.#...', '..#..', '...#.', '....#', '...#.', '..#..', '.#...'], - '<': ['...#.', '..#..', '.#...', '#....', '.#...', '..#..', '...#.'], - '(': ['...#.', '..#..', '.#...', '.#...', '.#...', '..#..', '...#.'], - ')': ['.#...', '..#..', '...#.', '...#.', '...#.', '..#..', '.#...'], - '+': ['.....', '..#..', '..#..', '#####', '..#..', '..#..', '.....'], - '=': ['.....', '.....', '#####', '.....', '#####', '.....', '.....'], - '~': ['.....', '.....', '.#...', '#.#.#', '...#.', '.....', '.....'], - '*': ['.....', '#.#.#', '.###.', '#####', '.###.', '#.#.#', '.....'], - "'": ['..#..', '..#..', '.#...', '.....', '.....', '.....', '.....'], - '|': ['..#..', '..#..', '..#..', '..#..', '..#..', '..#..', '..#..'], - '^': ['#....', '##...', '###..', '####.', '###..', '##...', '#....'], // play triangle - '`': ['.....', '#####', '#####', '.###.', '.###.', '..#..', '.....'], // "next" triangle -}; - -const textW = (s, px) => s.length * 6 * px - px; - -function pixelText(str, x, y, px, fill, attrs = '') { - let rects = ''; - [...String(str).toUpperCase()].forEach((ch, i) => { - const glyph = FONT[ch] ?? FONT['?']; - const ox = x + i * 6 * px; - glyph.forEach((row, ry) => { - let start = -1; - for (let cx = 0; cx <= 5; cx++) { - const on = cx < 5 && row[cx] === '#'; - if (on && start < 0) start = cx; - if (!on && start >= 0) { - rects += ``; - start = -1; - } - } - }); - }); - return `${rects}`; -} - -function sprite(rows, pal, x, y, px, attrs = '') { - let out = ''; - rows.forEach((row, ry) => { - let cx = 0; - while (cx < row.length) { - const c = row[cx]; - if (c === '.') { cx++; continue; } - let end = cx; - while (end < row.length && row[end] === c) end++; - out += ``; - cx = end; - } - }); - return `${out}`; -} - -function wrap(text, max) { - const lines = []; - let cur = ''; - for (const word of text.split(' ')) { - const next = cur ? `${cur} ${word}` : word; - if (next.length > max && cur) { - lines.push(cur); - cur = word; - } else { - cur = next; - } - } - if (cur) lines.push(cur); - return lines; -} - -// ---------------------------------------------------------------- sprites -// Three colours only: INK, PAPER and ORANGE. -const CANARY_PAL = { K: INK, Y: ORANGE, y: PAPER, W: PAPER, O: INK }; -const CANARY_A = [ - '.....KKKKK......', - '...KKYYYYYKK....', - '..KYYYYYYYWWK...', - '..KYYYYYYYWKK...', - '.KYYYYYYYYYYKOO.', - '.KYYYYYYYYYYKOOO', - '.KYyyyyYYYYYK...', - 'KYYyyyyyYYYYK...', - 'KYYYyyyyYYYK....', - '.KYYYyyYYYYK....', - '..KYYYYYYYK.....', - '...KKKKKKK......', - '....K...K.......', - '...KK..KK.......', -]; -const CANARY_B = [ - '.....KKKKK......', - '...KKYYYYYKK....', - '..KYYYYYYYWWK...', - '..KYYYYYYYWKK...', - '.KYYyyYYYYYYKOO.', - '.KYyyyyYYYYYKOOO', - '.KYYyyyYYYYYK...', - 'KYYYYYYYYYYYK...', - 'KYYYYYYYYYYK....', - '.KYYYYYYYYYK....', - '..KYYYYYYYK.....', - '...KKKKKKK......', - '....K...K.......', - '...KK..KK.......', -]; -const PHONE_PAL = { K: INK, P: INK, W: PAPER, Y: ORANGE }; -const PHONE = [ - '.KKKKKKKK.', - 'KPPPPPPPPK', - 'KPWWWWWWPK', - 'KPWYYYYWPK', - 'KPWWWWWWPK', - 'KPWYYYWWPK', - 'KPWWWWWWPK', - 'KPWYYYYWPK', - 'KPWWWWWWPK', - 'KPWWWWWWPK', - 'KPPPPPPPPK', - 'KPPPWWPPPK', - '.KKKKKKKK.', -]; -const ENV_PAL = { K: INK, W: PAPER, Y: ORANGE }; -const ENVELOPE = [ - 'KKKKKKKKKKKKKK', - 'KYYWWWWWWWWYYK', - 'KWYYWWWWWWYYWK', - 'KWWYYWWWWYYWWK', - 'KWWWYYWWYYWWWK', - 'KWWWWYYYYWWWWK', - 'KWWWWWYYWWWWWK', - 'KWWWWWWWWWWWWK', - 'KWWWWWWWWWWWWK', - 'KKKKKKKKKKKKKK', -]; -const LENS_PAL = { K: INK, L: PAPER, H: ORANGE }; -const MAGNIFIER = [ - '..KKKK......', - '.KLLLLK.....', - 'KLLKLLLK....', - 'KLKLLLLK....', - 'KLLLLLLK....', - 'KLLLLLLK....', - '.KLLLLK.....', - '..KKKKHH....', - '......HHH...', - '.......HHH..', - '........HHH.', - '.........HH.', -]; -// A sneaky leaked page with eyes: the "wild LEAK". -const LEAK_PAL = { K: INK, W: PAPER, R: ORANGE, L: INK }; -const LEAK = [ - '..KKKKKKKKKK....', - '..KWWWWWWWWKK...', - '..KWWWWWWWWWKK..', - '..KWRRWWWRRWWK..', - '..KWRKWWWRKWWK..', - '..KWWWWWWWWWWK..', - '..KWLLLLLLLWWK..', - '..KWWWWWWWWWWK..', - '..KWLLLLLLWWWK..', - '..KWWWWKKWWWWK..', - '..KWWWKRRKWWWK..', - '..KWWWWWWWWWWK..', - '..KWLLLLLWWWWK..', - '..KWWWWWWWWWWK..', - '..KKWKKWKKWKKK..', - '...K..K..K..K...', -]; - -// ---------------------------------------------------------------- svg helpers -const esc = (s) => String(s).replace(/&/g, '&').replace(/ -${esc(title)} - -${defs} -${body} - -`; -} - -// A paper card with a thick ink border and a hard orange shadow (bottom-right). -const SH = 8; -const card = (w, h, r = 16) => - ` -`; - -const written = new Set(); -function write(name, content) { - fs.writeFileSync(path.join(assetDir, name), content); - written.add(name); - console.log(` wrote assets/readme/${name} (${(content.length / 1024).toFixed(1)} KB)`); -} - -const blinkCss = `.blink { animation: blink 1.1s linear infinite; } -@keyframes blink { 0%,55% { opacity: 1; } 56%,100% { opacity: 0; } }`; -const flapCss = (s) => `.fa { animation: flapA ${s}s linear infinite; } -.fb { opacity: 0; animation: flapB ${s}s linear infinite; } -@keyframes flapA { 0%,49.9% { opacity: 1; } 50%,100% { opacity: 0; } } -@keyframes flapB { 0%,49.9% { opacity: 0; } 50%,100% { opacity: 1; } }`; -const bird = (x, y, px) => - sprite(CANARY_A, CANARY_PAL, x, y, px, 'class="fa"') + sprite(CANARY_B, CANARY_PAL, x, y, px, 'class="fb"'); - -// One-shot typewriter: each line is revealed by a paper-coloured cover that -// steps to the right, one character per step. Static frame = fully revealed. -function typewriter(lines, x, y0, px, lineGap, colors, cover, clipId, startDelay, cps) { - let body = ''; - let css = ''; - let t = startDelay; - lines.forEach((line, i) => { - const y = y0 + i * lineGap; - const w = textW(line, px) + px * 2; - const n = Math.max(1, line.length); - const dur = n / cps; - body += pixelText(line, x, y, px, colors[Math.min(i, colors.length - 1)]); - body += ``; - css += ` -.cv${i} { transform: translateX(${w}px); animation: cv${i} ${dur.toFixed(2)}s steps(${n}, end) ${t.toFixed(2)}s backwards; } -@keyframes cv${i} { from { transform: translateX(0px); } to { transform: translateX(${w}px); } }`; - t += dur + 0.15; - }); - return { body, css, end: t }; -} - -// ---------------------------------------------------------------- banner -function banner() { - const W = 840, H = 250; - const sparks = [[574, 50, 0], [792, 70, 0.6], [586, 176, 1.2], [800, 168, 1.8]]; - let body = card(W, H); - body += ``; - sparks.forEach(([x, y, d]) => { - body += ``; - }); - body += pixelText('NO SUS', 52, 44, 9, ORANGE); - body += pixelText('NO SUS', 46, 38, 9, INK); - body += pixelText('CANARY', 50, 116, 5, ORANGE); - body += pixelText('EVERY READER GETS THEIR OWN COPY.', 50, 164, 2, INK); - body += `${pixelText('^ PRESS START', 50, 196, 2, ORANGE)}`; - body += pixelText(cfg.event, W - SH - 30 - textW(cfg.event, 2), 196, 2, INK); - body += `${bird(612, 40, 10)}`; - const css = `${blinkCss} -${flapCss(0.5)} -.bob { animation: bob 1.2s ease-in-out infinite alternate; } -@keyframes bob { from { transform: translateY(0); } to { transform: translateY(-8px); } } -.spark { animation: spark 2.4s steps(2, end) infinite; } -@keyframes spark { 0%,100% { opacity: 1; } 50% { opacity: 0; } }`; - write('banner.svg', svgDoc(W, H, 'NO SUS Canary: every reader gets their own copy.', css, body)); -} - -// ---------------------------------------------------------------- buttons -function button(file, label, alt, primary) { - const W = 260, H = 64; - const tw = textW(label, 2); - const body = [ - ``, - ``, - pixelText(label, Math.round((W - 6 - tw) / 2), Math.round((H - 6 - 14) / 2), 2, INK, primary ? 'class="nudge"' : ''), - ].join('\n'); - const css = primary - ? `.nudge { animation: nudge 1.4s ease-in-out infinite; } -@keyframes nudge { 0%,100% { transform: translateX(0); } 50% { transform: translateX(4px); } }` - : ''; - write(file, svgDoc(W, H, alt, css, body)); -} - -// ---------------------------------------------------------------- dialogue box (handheld RPG style) -function dialogue(file, speaker, text, alt) { - const W = 840, px = 3, gap = 34, x0 = 120; - const max = Math.floor((W - x0 - 60) / (6 * px)); - const lines = [speaker, ...wrap(text.toUpperCase(), max)]; - const H = 44 + lines.length * gap + 26; - const inner = { x: 18, y: 18, w: W - SH - 36, h: H - SH - 36 }; - const tw = typewriter(lines, x0, 42, px, gap, [ORANGE, INK], PAPER, 'box', 0.3, 42); - const body = [ - card(W, H), - ``, - `${bird(34, Math.round((H - SH) / 2 - 30), 4)}`, - tw.body, - `${pixelText('`', W - SH - 60, H - SH - 46, 3, INK)}`, - ].join('\n'); - const css = `${flapCss(0.6)} -.bob { animation: bob 1.4s ease-in-out infinite alternate; } -@keyframes bob { from { transform: translateY(0); } to { transform: translateY(-4px); } } -.next { animation: next 0.9s linear ${tw.end.toFixed(2)}s infinite; } -@keyframes next { 0%,55% { opacity: 1; transform: translateY(0); } 56%,100% { opacity: 0.2; transform: translateY(3px); } } -${tw.css}`; - const defs = ``; - write(file, svgDoc(W, H, alt, css, body, defs)); -} - -// ---------------------------------------------------------------- the story (how it works) -function story() { - const W = 840, H = 330, T = 10; - const readers = ['ASHA', 'BEN', 'PRIYA', 'RAJ', 'ZOE']; - const leaker = 2; - const rx = [496, 562, 628, 694, 760]; - const phoneY = 196, envStart = { x: 118, y: 166 }; - let css = ` -.bob { animation: bob 1s ease-in-out infinite alternate; } -@keyframes bob { from { transform: translateY(0); } to { transform: translateY(-5px); } } -${flapCss(0.5)} -.seal { animation: seal ${T}s linear infinite; } -@keyframes seal { 0% { opacity: 0; } 4%,92% { opacity: 1; } 96%,100% { opacity: 0; } } -.pulse { animation: pulse 1s steps(2, end) infinite; } -@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0; } } -.bubble { animation: bubble ${T}s linear infinite; } -@keyframes bubble { 0%,49% { opacity: 0; } 53%,92% { opacity: 1; } 96%,100% { opacity: 0; } } -.leak { opacity: 0; animation: leak ${T}s linear infinite; } -@keyframes leak { 0%,43% { opacity: 0; transform: translate(${rx[leaker] + 1 - 446}px, ${phoneY + 16 - 118}px); } - 44% { opacity: 1; transform: translate(${rx[leaker] + 1 - 446}px, ${phoneY + 16 - 118}px); } - 52% { opacity: 1; transform: translate(0px, 0px); } 55%,100% { opacity: 0; transform: translate(0px, 0px); } } -.mag { animation: mag ${T}s linear infinite; } -@keyframes mag { 0%,54% { opacity: 0; transform: translate(-150px, 0px); } 56% { opacity: 1; transform: translate(-150px, 0px); } - 68% { opacity: 1; transform: translate(0px, 0px); } 72%,100% { opacity: 0; transform: translate(0px, 0px); } } -.win { animation: win ${T}s linear infinite; } -@keyframes win { 0%,69% { opacity: 0; } 70%,73%,77%,81%,92% { opacity: 1; } 71.5%,75%,79% { opacity: 0.2; } 96%,100% { opacity: 0; } } -.who { animation: who ${T}s linear infinite; } -@keyframes who { 0%,73% { opacity: 0; } 76%,92% { opacity: 1; } 96%,100% { opacity: 0; } } -.hl { animation: hl ${T}s linear infinite; } -@keyframes hl { 0%,69% { opacity: 0; } 70%,74%,78%,82%,86%,92% { opacity: 1; } 72%,76%,80%,84% { opacity: 0; } 96%,100% { opacity: 0; } }`; - - let body = card(W, H); - body += ``; - body += ` - -${pixelText('SEALED ON MONAD', 208, 51, 2, INK)}`; - body += `${bird(40, 188, 5)}`; - body += pixelText('SENDER', 44, 286, 2, ORANGE); - readers.forEach((name, j) => { - body += pixelText(`0${j + 1}`, rx[j] + 4, phoneY - 22, 2, INK); - body += sprite(PHONE, PHONE_PAL, rx[j], phoneY, 3); - const nw = textW(name, 2); - body += pixelText(name, rx[j] + 15 - Math.round(nw / 2), 286, 2, j === leaker ? ORANGE : INK); - }); - readers.forEach((_, j) => { - const fx = rx[j] + 1, fy = phoneY + 16; - const a = 10 + j * 4, b = 22 + j * 4; - css += ` -.env${j} { animation: env${j} ${T}s ease-out infinite; } -@keyframes env${j} { 0%,${a - 0.1}% { opacity: 0; transform: translate(${envStart.x - fx}px, ${envStart.y - fy}px); } - ${a}% { opacity: 1; transform: translate(${envStart.x - fx}px, ${envStart.y - fy}px); } - ${b}% { opacity: 1; transform: translate(0px, 0px); } 92% { opacity: 1; transform: translate(0px, 0px); } 96%,100% { opacity: 0; transform: translate(0px, 0px); } }`; - body += sprite(ENVELOPE, ENV_PAL, fx, fy, 2, `class="env${j}"`); - }); - body += ` -${pixelText('LEAKED!', 342, 106, 3, ORANGE)} - -`; - body += sprite(ENVELOPE, ENV_PAL, 446, 118, 2, 'class="leak"'); - body += sprite(MAGNIFIER, LENS_PAL, 470, 110, 3, 'class="mag"'); - body += ``; - body += `${pixelText('THE CANARY SANG!', 150, 212, 3, ORANGE)}`; - body += `${pixelText(`COPY 0${leaker + 1} = ${readers[leaker]}`, 150, 242, 2, INK)}`; - write('story.svg', svgDoc(W, H, - "Animation: the sender seals a note on Monad, five readers each receive a different copy, Priya's copy leaks, NO SUS scans it and the canary sings: copy 03 is Priya's.", - css, body)); -} - -// ---------------------------------------------------------------- the catch (battle text scene) -function battle() { - const W = 840, H = 390, T = 12, cps = 24, px = 3; - const lines = ['A WILD LEAK APPEARED!', 'CANARY USED FINGERPRINT!', "IT'S SUPER EFFECTIVE!", "IT WAS PRIYA'S COPY! #03"]; - const windows = [[0, 22], [25, 47], [50, 72], [75, 95]]; - const box = { x: 20, y: 290, w: W - SH - 40, h: 76 }; - let css = ` -${flapCss(0.6)} -.foe { animation: foe ${T}s linear infinite; } -@keyframes foe { - 0%,29% { transform: translate(0px, 0px); opacity: 1; } - 30%,32%,34%,36% { opacity: .15; } - 31%,33%,35%,37% { opacity: 1; } - 50% { transform: translate(0px, 0px); } - 51% { transform: translate(-8px, 0px); } - 52% { transform: translate(8px, 0px); } - 53% { transform: translate(-8px, 0px); } - 54%,76% { transform: translate(0px, 0px); opacity: 1; } - 82%,95% { transform: translate(0px, 40px); opacity: 0; } - 96%,100% { transform: translate(0px, 0px); opacity: 1; } } -.hp { transform-box: fill-box; transform-origin: 0% 50%; transform: scaleX(0.06); animation: hp ${T}s linear infinite; } -@keyframes hp { 0%,50% { transform: scaleX(1); } 58%,95% { transform: scaleX(0.06); } 100% { transform: scaleX(1); } } -.xpup { opacity: 0; animation: xpup ${T}s linear infinite; } -@keyframes xpup { 0%,78% { opacity: 0; transform: translate(0px, 0px); } 81% { opacity: 1; } 93% { opacity: 1; transform: translate(0px, -18px); } 96%,100% { opacity: 0; } } -.next { animation: next 0.9s linear infinite; } -@keyframes next { 0%,55% { opacity: 1; } 56%,100% { opacity: 0.2; } }`; - - const infoBox = (x, y, w, name, lv, bar) => ` -${pixelText(name, x + 18, y + 14, 3, INK)} -${pixelText(lv, x + w - 18 - textW(lv, 2), y + 18, 2, INK)} -${pixelText('HP', x + 18, y + 50, 2, ORANGE)} - -`; - - let body = card(W, H, 18); - body += ``; - body += ``; - body += infoBox(36, 30, 330, 'LEAK', 'LV3', 'hp'); - body += `${sprite(LEAK, LEAK_PAL, 560, 50, 8)}`; - body += bird(160, 156, 8); - body += infoBox(466, 200, 340, 'CANARY', 'LV99', ''); - body += `${pixelText('+500 XP', 560, 166, 3, ORANGE)}`; - body += ``; - body += ``; - lines.forEach((line, i) => { - const [a, b] = windows[i]; - const n = line.length; - const w = textW(line, px) + px * 2; - const d = ((n / cps) / T) * 100; - const last = i === lines.length - 1; - css += ` -.bl${i} { opacity: ${last ? 1 : 0}; animation: bl${i} ${T}s linear infinite; } -@keyframes bl${i} { 0%,${(a - 0.01).toFixed(2)}% { opacity: 0; } ${a}%,${b}% { opacity: 1; } ${(b + 0.01).toFixed(2)}%,100% { opacity: 0; } } -.bc${i} { transform: translateX(${w}px); animation: bc${i} ${T}s linear infinite; } -@keyframes bc${i} { 0%,${a}% { transform: translateX(0px); animation-timing-function: steps(${n}, end); } ${(a + d).toFixed(2)}%,100% { transform: translateX(${w}px); } }`; - body += `${pixelText(line, 50, 318, px, INK)}`; - }); - body += `${pixelText('`', box.x + box.w - 50, 334, 3, INK)}`; - const defs = ``; - write('battle.svg', svgDoc(W, H, - "Battle text: A wild LEAK appeared! Canary used FINGERPRINT! It's super effective! It was Priya's copy, number 03.", - css, body, defs)); -} - -// ---------------------------------------------------------------- footer -function gameOver() { - const W = 840, H = 100; - const a = 'GAME OVER?', b = '^ PLAY AGAIN AT THE LIVE APP'; - let body = card(W, H); - body += pixelText(a, Math.round((W - SH - textW(a, 3)) / 2), 22, 3, ORANGE); - body += `${pixelText(b, Math.round((W - SH - textW(b, 2)) / 2), 58, 2, INK)}`; - write('game-over.svg', svgDoc(W, H, 'Game over? Play again at the live app.', blinkCss, body)); -} - -// ---------------------------------------------------------------- README -const zeroAddr = /^0x0{40}$/i; -const has = (v) => typeof v === 'string' && v.trim() !== '' && !zeroAddr.test(v); - -function readme() { - const live = cfg.liveUrl; - const liveText = live.replace(/^https?:\/\//, '').replace(/#.*$/, ''); - const repo = cfg.repoUrl; - const repoName = repo.split('/').pop(); - const testnet = has(cfg.contractTestnet) ? cfg.contractTestnet : null; - const mainnet = has(cfg.contractMainnet) ? cfg.contractMainnet : null; - const testnetUrl = testnet ? `${cfg.explorerTestnet}/address/${testnet}` : null; - const mainnetUrl = mainnet ? `${cfg.explorerMainnet}/address/${mainnet}` : null; - const link = (url, text) => (url ? `[${text}](${url})` : '_soon_'); - const ok = (b) => (b ? '**Done**' : 'Soon'); - const team = (cfg.team ?? []).join(' · '); - const testnetMd = testnet ? `[\`${testnet}\`](${testnetUrl})` : '_deploying_'; - const buildInPublic = [cfg.xPostUrl, cfg.demoVideoUrl, cfg.adVideoUrl].some(Boolean); - - const checklist = [ - `| ${ok(!!live)} | Live app | [${liveText}](${live}) |`, - `| ${ok(!!testnet)} | Contract on Monad testnet | ${testnetMd} |`, - `| ${ok(!!cfg.verified && !!testnet)} | Verified source code | ${cfg.verified && testnetUrl ? `[View verified source](${cfg.verifiedUrl || testnetUrl})` : '_soon_'} |`, - `| ${ok(!!testnet)} | Live transaction in the demo | Every **Open my copy** tap |`, - `| **Done** | Public repo you can run | [Run it yourself](#more) |`, - `| ${ok(buildInPublic)} | Build in public | ${link(cfg.xPostUrl, 'X post')} · ${link(cfg.demoVideoUrl, 'demo')} · ${link(cfg.adVideoUrl, 'ad')} |`, - `| ${ok(!!mainnet)} | Bonus: Monad mainnet | ${mainnet ? `[\`${mainnet}\`](${mainnetUrl})` : '_soon_'} |`, - `| ${ok(!!cfg.customDomain)} | Bonus: custom domain | ${cfg.customDomain ? `[${liveText.split('/')[0]}](${live})` : '_soon_'} |`, - ].join('\n'); - - return ` - -

- NO SUS Canary: every reader gets their own copy. -

- -

- Play live -   - Judge checklist -

- -

Prof. Canary: Share one link. Every reader gets a secretly different copy. If it leaks, I tell you whose copy it was.

- -## Step 1: Watch - -

Animation: the sender seals a note on Monad, five readers each receive a different copy, Priya's copy leaks, NO SUS scans it and the canary sings: copy 03 is Priya's.

- -## Step 2: Try it - -**60 seconds. No wallet. No install.** - -1. **Make a note.** Open the [live app](${live}) → **PLAY CANARY** → **Create a Canary link** → **Use the demo note** → **Create Canary link**. -2. **Be a reader.** Open that link in a private window, type any name, tap **Open my copy**. -3. **Catch the leak.** Copy the reader's text → **Check a leak** → paste. It names the reader. - -

Battle text: A wild LEAK appeared! Canary used FINGERPRINT! It's super effective! It was Priya's copy, number 03.

- -## Step 3: Why Monad - -- **One transaction per reader.** Every **Open my copy** is recorded on-chain. -- **Final in under a second.** About **0.015 MON** each. -- **Parallel execution.** A whole room can open the link at once. - -## Judge checklist - -| | What | Where | -|---|---|---| -${checklist} - -> **Honest limits:** it names *whose copy* leaked, not *who shared it*. It doesn't stop screenshots. It makes them traceable. - -## More - -
-How the fingerprint works - -- **Write once.** NO SUS swaps safe word twins (\`don't\` / \`do not\`, \`five\` / \`5\`) to make up to **100 copies**. Each looks normal, each is unique. -- **Seal it.** Copies are encrypted in your browser. The key lives only in the link's \`#fragment\`. \`sealNote\` puts one hash of all copies on Monad before anyone reads. -- **Share it.** Each reader gets the next unused copy. \`openCopy\` records it on Monad with an anonymous tag, never the name. -- **Catch it.** Paste a leak into **Check a leak**. Matching runs on your device. If too little text survived, it names nobody. -
- -
-Run it yourself - -You need Flutter 3.44+ and Node 22+. - -\`\`\`bash -git clone ${repo}.git -cd ${repoName} - -# App (web) -cd app -flutter pub get -flutter run -d chrome - -# Contract -cd ../contracts -npm ci -npx hardhat test -\`\`\` - -Own backend and contract: see [\`docs/canary/NOSUS_CANARY_BUILD_PLAN.md\`](docs/canary/NOSUS_CANARY_BUILD_PLAN.md). -
- -
-Architecture - -\`\`\`mermaid -%%{init: {'theme':'base','themeVariables':{'primaryColor':'${PAPER}','primaryTextColor':'${INK}','primaryBorderColor':'${INK}','lineColor':'${ORANGE}','fontFamily':'monospace'}}}%% -flowchart LR - S["Sender app"] -- "encrypted copies" --> F["canary function"] - F -- "sealNote" --> M[("NoSusCanary on Monad")] - R["Reader"] -- "open + name" --> F - F -- "openCopy" --> M - F -- "their copy" --> R -\`\`\` - -- **Chain:** hashes and anonymous tags only. -- **Server:** encrypted copies it can't read. -- **Sender's device:** the key and every copy's fingerprint. -
- -
-Test results - -Fingerprint test harness, 15-slot demo note: - -| Leak type | Right copy | Wrong copy | -|---|---|---| -| Full copy, marker removed | 300 / 300 | 0 | -| OCR-style (caps, no punctuation) | 300 / 300 | 0 | -| 2% random typos | 300 / 300 | 0 | -| Partial excerpts (30–70%) | named only when sure | 0 / 600 | -
- -Full technical write-up (setup, deployment, contract and relayers): [\`docs/TECHNICAL_README.md\`](docs/TECHNICAL_README.md) - ---- - -${team ? `**Team:** ${team} · ` : ''}Built at **${cfg.eventName}** · part of **NO SUS** - -

Game over? Play again at the live app.

-`; -} - -// ---------------------------------------------------------------- run -console.log('Building NO SUS Canary README…'); -banner(); -button('btn-play.svg', '^ PLAY LIVE', 'Play live', true); -button('btn-judge.svg', 'JUDGE CHECKLIST', 'Judge checklist', false); -dialogue('say-hello.svg', 'PROF. CANARY:', 'Share one link. Every reader gets a secretly different copy. If it leaks, I tell you whose copy it was.', - 'Prof. Canary: Share one link. Every reader gets a secretly different copy. If it leaks, I tell you whose copy it was.'); -story(); -battle(); -gameOver(); -// Remove assets from older versions of this README. -for (const f of fs.readdirSync(assetDir)) { - if (f.endsWith('.svg') && !written.has(f)) { - fs.rmSync(path.join(assetDir, f)); - console.log(` removed stale assets/readme/${f}`); - } -} -fs.writeFileSync(path.join(outDir, 'README.md'), readme()); -console.log(' wrote README.md'); -console.log('Done.'); diff --git a/tool/check-repository.mjs b/tool/check-repository.mjs deleted file mode 100644 index 481817d..0000000 --- a/tool/check-repository.mjs +++ /dev/null @@ -1,55 +0,0 @@ -import { existsSync, readFileSync, readdirSync, statSync } from "node:fs"; -import { join, relative } from "node:path"; - -const root = process.cwd(); -const required = [ - "AGENTS.md", - "CLAUDE.md", - "README.md", - "docs/STATUS.md", - "docs/CURSOR_HANDOFF.md", - "docs/ARCHITECTURE.md", - "docs/LIT_MONAD_SPIKE.md", - "web/src/lib/lit-conditions.ts", - "tool/threshold-spike/conditions.mjs", - "contracts/README.md", - "contracts/AGENTS.md", - "web/README.md", - "web/AGENTS.md", - "supabase/README.md", - "supabase/AGENTS.md", - ".cursor/rules/00-project.mdc", - ".cursor/rules/10-contracts.mdc", - ".cursor/rules/20-web.mdc", -]; - -const failures = required.filter((file) => !existsSync(join(root, file))).map( - (file) => `Missing required navigation file: ${file}`, -); - -const rootRules = readFileSync(join(root, "AGENTS.md"), "utf8"); -if (!rootRules.includes("Would you like to finalize today's work?")) { - failures.push("AGENTS.md lacks the required finalization prompt."); -} - -function visit(directory) { - for (const item of readdirSync(directory)) { - if ([".git", "node_modules", ".next", "artifacts", "cache"].includes(item)) continue; - const fullPath = join(directory, item); - if (statSync(fullPath).isDirectory()) visit(fullPath); - else if (item.endsWith(".mdc")) { - const contents = readFileSync(fullPath, "utf8"); - if (!contents.startsWith("---\n")) { - failures.push(`Cursor rule lacks front matter: ${relative(root, fullPath)}`); - } - } - } -} -visit(join(root, ".cursor")); - -if (failures.length) { - console.error(failures.join("\n")); - process.exit(1); -} - -console.log("Repository navigation and Cursor handoff checks passed."); diff --git a/tool/solana-spike/.gitignore b/tool/solana-spike/.gitignore new file mode 100644 index 0000000..8535fbc --- /dev/null +++ b/tool/solana-spike/.gitignore @@ -0,0 +1,2 @@ +# Devnet relayer keypair written by send_memo.ts. Never commit. +.keys/ diff --git a/tool/solana-spike/README.md b/tool/solana-spike/README.md new file mode 100644 index 0000000..da6c07e --- /dev/null +++ b/tool/solana-spike/README.md @@ -0,0 +1,39 @@ +# Solana devnet memo spike + +Sends one NO SUS Canary "seal" memo and one "open" memo to Solana devnet through +the production module `app/supabase/functions/canary/solana.ts` (the exact code +path the `canary` edge function uses), then reads one transaction back and +checks that the decoded memo equals what was sent. Memos carry dummy +sha256-shaped ids only; no note text, names or keys. + +Deno is not installed in this repo; `npx` fetches the official npm build: + +```sh +npx -y deno run -A tool/solana-spike/send_memo.ts +``` + +## Keys + +On the first run the script generates a devnet keypair and writes it to +`tool/solana-spike/.keys/relayer.json` in `solana-keygen` format (a JSON array +of 64 bytes). The directory is git-ignored and the secret is never printed; +only the public key is. Later runs reuse the same file. + +The script feeds that file to `loadSolana()` through `SOLANA_RELAYER_KEYS`, so it +also proves the JSON-array form of the secret parses. `SOLANA_RPC_URL` is +honoured if set (default `https://api.devnet.solana.com`). + +## Funding + +Devnet SOL is free. The script asks the RPC faucet for 1 SOL when the balance is +below 0.01 SOL and retries a few times with backoff. The public faucet is +rate-limited; if it keeps refusing, fund the printed public key by hand at + and run the script again. One memo costs 5000 +lamports (0.000005 SOL), so 1 SOL covers about 200,000 memos. + +## Using the key as the edge function relayer + +Owner only, experiment project only, with explicit approval (see `AGENTS.md`): +set `SOLANA_RELAYER_KEYS` to the contents of `relayer.json` (or to a base58 +64-byte secret key; several keys may be comma-separated). Leaving it unset keeps +the Solana proof off and the function behaves exactly as before. diff --git a/tool/solana-spike/send_memo.ts b/tool/solana-spike/send_memo.ts new file mode 100644 index 0000000..13b1e57 --- /dev/null +++ b/tool/solana-spike/send_memo.ts @@ -0,0 +1,164 @@ +// NO SUS Canary: Solana devnet memo spike. +// +// Exercises the exact production code path (app/supabase/functions/canary/ +// solana.ts): loads or generates a devnet relayer key, funds it by airdrop, +// sends one seal memo and one open memo, then reads one back and checks the +// text. The secret key is written to .keys/relayer.json and never printed. +// +// npx -y deno run -A tool/solana-spike/send_memo.ts + +import { + createKeyPairSignerFromBytes, + createKeyPairSignerFromPrivateKeyBytes, + createSolanaRpc, + getBase58Encoder, + lamports, + type Signature, +} from "npm:@solana/kit@8.4.0"; +import { + loadSolana, + openMemo, + sealMemo, + sendSolanaMemo, +} from "../../app/supabase/functions/canary/solana.ts"; + +const KEYS_DIR = new URL(".keys/", import.meta.url); +const KEY_FILE = new URL("relayer.json", KEYS_DIR); +const MIN_BALANCE = 10_000_000n; // 0.01 SOL +const AIRDROP = lamports(1_000_000_000n); // 1 SOL + +function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +function hex64(): string { + return Array.from(crypto.getRandomValues(new Uint8Array(32)), (b) => b.toString(16).padStart(2, "0")) + .join(""); +} + +function explorer(sig: string, rpcUrl: string): string { + const cluster = rpcUrl.includes("testnet") ? "testnet" : "devnet"; + return `https://explorer.solana.com/tx/${sig}?cluster=${cluster}`; +} + +// Returns the solana-keygen style JSON array (64 bytes) for the relayer, +// generating and saving a new one when the file does not exist yet. +async function loadOrCreateKeyJson(): Promise { + try { + return (await Deno.readTextFile(KEY_FILE)).trim(); + } catch (e) { + if (!(e instanceof Deno.errors.NotFound)) throw e; + } + const seed = crypto.getRandomValues(new Uint8Array(32)); + const signer = await createKeyPairSignerFromPrivateKeyBytes(seed); + const secret = new Uint8Array(64); + secret.set(seed, 0); + secret.set(getBase58Encoder().encode(signer.address), 32); + const json = JSON.stringify(Array.from(secret)); + await Deno.mkdir(KEYS_DIR, { recursive: true }); + await Deno.writeTextFile(KEY_FILE, json + "\n"); + console.log("Generated a new devnet keypair in tool/solana-spike/.keys/relayer.json"); + return json; +} + +type Rpc = ReturnType; + +async function waitConfirmed(rpc: Rpc, sig: Signature, timeoutMs: number): Promise { + const deadline = Date.now() + timeoutMs; + while (Date.now() < deadline) { + const { value: [status] } = await rpc.getSignatureStatuses([sig]).send(); + if (status?.err) return false; + if (status?.confirmationStatus === "confirmed" || status?.confirmationStatus === "finalized") { + return true; + } + await sleep(500); + } + return false; +} + +async function main() { + Deno.env.set("SOLANA_RELAYER_KEYS", await loadOrCreateKeyJson()); + const cfg = loadSolana(); + if (!cfg) throw new Error("loadSolana() returned null although SOLANA_RELAYER_KEYS is set"); + const signer = await createKeyPairSignerFromBytes(cfg.keys[0]); + console.log(`Relayer public key: ${signer.address}`); + console.log(`RPC: ${cfg.rpcUrl}`); + console.log(`Memo program: ${cfg.memoProgram}`); + + const rpc = createSolanaRpc(cfg.rpcUrl); + const balance = async () => + (await rpc.getBalance(signer.address, { commitment: "confirmed" }).send()).value; + console.log(`Balance: ${Number(await balance()) / 1e9} SOL`); + + if ((await balance()) < MIN_BALANCE) { + let funded = false; + for (let attempt = 1; attempt <= 4 && !funded; attempt++) { + try { + const sig = await rpc.requestAirdrop(signer.address, AIRDROP, { commitment: "confirmed" }) + .send(); + console.log(`Airdrop requested (${attempt}/4): ${sig}`); + funded = await waitConfirmed(rpc, sig, 30_000); + } catch (e) { + console.log(`Airdrop attempt ${attempt}/4 failed: ${e instanceof Error ? e.message : String(e)}`); + } + if (!funded && attempt < 4) await sleep(2_000 * 2 ** (attempt - 1)); + } + if (!funded) { + console.error( + `Devnet airdrop is rate-limited. Fund ${signer.address} at https://faucet.solana.com and run again.`, + ); + Deno.exit(1); + } + console.log(`Balance after airdrop: ${Number(await balance()) / 1e9} SOL`); + } + + const note = `0x${hex64()}`; + const seal = sealMemo({ + note, + copies: 3, + hash: `0x${hex64()}`, + exp: Math.floor(Date.now() / 1000) + 3600, + }); + console.log(`\nSeal memo (${new TextEncoder().encode(seal).length} bytes): ${seal}`); + let t0 = Date.now(); + const sealSig = await sendSolanaMemo(cfg, seal); + console.log(` confirmed in ${Date.now() - t0} ms: ${sealSig}`); + console.log(` ${explorer(sealSig, cfg.rpcUrl)}`); + + const open = openMemo({ note, copy: 0, tag: `0x${hex64()}` }); + console.log(`\nOpen memo (${new TextEncoder().encode(open).length} bytes): ${open}`); + t0 = Date.now(); + const openSig = await sendSolanaMemo(cfg, open); + console.log(` confirmed in ${Date.now() - t0} ms: ${openSig}`); + console.log(` ${explorer(openSig, cfg.rpcUrl)}`); + + // Round trip: read the seal transaction back and compare the memo text. + const tx = await rpc + .getTransaction(sealSig as Signature, { + encoding: "jsonParsed", + maxSupportedTransactionVersion: 0, + commitment: "confirmed", + }) + .send(); + if (!tx) throw new Error("getTransaction returned null"); + const ix = tx.transaction.message.instructions[0] as unknown as { + program?: string; + parsed?: unknown; + data?: unknown; + }; + // SPL Memo (MemoSq4…) is parsed by the RPC into a plain string; p-memo is not, + // so fall back to decoding the raw base58 instruction data. + const decoded = typeof ix.parsed === "string" + ? ix.parsed + : new TextDecoder().decode(getBase58Encoder().encode(String(ix.data ?? ""))); + console.log(`\nRead back (${ix.program ?? "raw"}): ${decoded}`); + console.log(`Compute units: ${tx.meta?.computeUnitsConsumed ?? "?"}, fee: ${tx.meta?.fee ?? "?"} lamports`); + if (decoded !== seal) { + console.error("MISMATCH: decoded memo differs from the sent memo"); + Deno.exit(1); + } + console.log("Round trip OK: decoded memo equals the sent memo."); + console.log(`Balance: ${Number(await balance()) / 1e9} SOL`); +} + +await main(); diff --git a/tool/threshold-spike/README.md b/tool/threshold-spike/README.md deleted file mode 100644 index c08a1a5..0000000 --- a/tool/threshold-spike/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Gate T1 runner - -This runner is the first proof for the product promise. It uses three controlled -test wallets: a sender seals a harmless probe for the recipient, the recipient -is denied before acknowledgement, decrypts after acknowledgement, and a stranger -is denied. It never prints the plaintext probe. - -Dry-run the Lit `canDecrypt` condition without enabling the product. - -```sh -npm install -npm run check -npm run dry-run -``` - -`npm run connect` handshakes Lit naga-dev and attempts a client-side encrypt. That still -does not prove decryption, does not deploy the contract, and does not flip the product -gate. `npm run live` additionally requires `THRESHOLD_SPIKE_RUN=1`, a deployed -`NoSusMonadDrops` address, and three controlled test wallets. Set -`THRESHOLD_SPIKE_CHECK_EXPIRY=1` to wait for and verify expiry in the same run. - -A successful live run still does not flip `web/src/lib/threshold.ts` until every case in -`docs/LIT_MONAD_SPIKE.md` is recorded in `docs/STATUS.md`. diff --git a/tool/threshold-spike/conditions.mjs b/tool/threshold-spike/conditions.mjs deleted file mode 100644 index 61c8117..0000000 --- a/tool/threshold-spike/conditions.mjs +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Canonical Lit access-control condition for Gate T1. - * Keep this aligned with web/src/lib/lit-conditions.ts. - */ - -export const LIT_ACC_CHAIN = "monadTestnet"; -export const CAN_DECRYPT_ABI = { - name: "canDecrypt", - type: "function", - stateMutability: "view", - inputs: [ - { name: "id", type: "bytes32" }, - { name: "account", type: "address" }, - ], - outputs: [{ name: "", type: "bool", internalType: "bool" }], -}; - -export function buildCanDecryptConditions(contractAddress, dropId) { - return [ - { - contractAddress, - chain: LIT_ACC_CHAIN, - functionName: "canDecrypt", - functionParams: [dropId, ":userAddress"], - functionAbi: CAN_DECRYPT_ABI, - returnValueTest: { - key: "", - comparator: "=", - value: "true", - }, - }, - ]; -} diff --git a/tool/threshold-spike/conditions.test.mjs b/tool/threshold-spike/conditions.test.mjs deleted file mode 100644 index 846f05f..0000000 --- a/tool/threshold-spike/conditions.test.mjs +++ /dev/null @@ -1,32 +0,0 @@ -import assert from "node:assert/strict"; -import { readFileSync } from "node:fs"; -import { dirname, join } from "node:path"; -import { fileURLToPath } from "node:url"; -import test from "node:test"; - -import { buildCanDecryptConditions, LIT_ACC_CHAIN } from "./conditions.mjs"; - -const root = join(dirname(fileURLToPath(import.meta.url)), "..", ".."); -const webSource = readFileSync(join(root, "web/src/lib/lit-conditions.ts"), "utf8"); - -test("the condition binds canDecrypt to the authenticated wallet on monadTestnet", () => { - const dropId = `0x${"11".repeat(32)}`; - const contract = "0x0000000000000000000000000000000000000001"; - const [condition] = buildCanDecryptConditions(contract, dropId); - - assert.equal(LIT_ACC_CHAIN, "monadTestnet"); - assert.equal(condition.chain, "monadTestnet"); - assert.equal(condition.functionName, "canDecrypt"); - assert.deepEqual(condition.functionParams, [dropId, ":userAddress"]); - assert.equal(condition.returnValueTest.value, "true"); - const serialized = JSON.stringify(condition); - assert.doesNotMatch(serialized, /plaintext|privateKey|salt/i); - assert.equal(condition.functionParams.includes(":userAddress"), true); -}); - -test("the web module uses the same chain, predicate, and user-address binding", () => { - assert.match(webSource, /export const LIT_ACC_CHAIN = "monadTestnet"/); - assert.match(webSource, /functionName: "canDecrypt"/); - assert.match(webSource, /:userAddress/); - assert.match(webSource, /value: "true"/); -}); diff --git a/tool/threshold-spike/package-lock.json b/tool/threshold-spike/package-lock.json deleted file mode 100644 index c796958..0000000 --- a/tool/threshold-spike/package-lock.json +++ /dev/null @@ -1,13776 +0,0 @@ -{ - "name": "@nosus-monad/threshold-spike", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@nosus-monad/threshold-spike", - "version": "0.1.0", - "dependencies": { - "@lit-protocol/auth": "8.2.3", - "@lit-protocol/lit-client": "8.3.1", - "@lit-protocol/networks": "8.4.1", - "viem": "2.38.3" - } - }, - "node_modules/@adraffy/ens-normalize": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", - "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", - "license": "MIT" - }, - "node_modules/@assemblyscript/loader": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.9.4.tgz", - "integrity": "sha512-HazVq9zwTVwGmqdwYzu7WyQ6FQVZ7SwET0KKQuKm55jD0IfUpZgN0OPIiZG3zV1iSrVYcN0bdwLRXI/VNCYsUA==", - "license": "Apache-2.0" - }, - "node_modules/@babel/code-frame": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", - "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.29.7", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", - "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", - "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.7", - "@babel/generator": "^7.29.7", - "@babel/helper-compilation-targets": "^7.29.7", - "@babel/helper-module-transforms": "^7.29.7", - "@babel/helpers": "^7.29.7", - "@babel/parser": "^7.29.7", - "@babel/template": "^7.29.7", - "@babel/traverse": "^7.29.7", - "@babel/types": "^7.29.7", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", - "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.8", - "@babel/types": "^7.29.8", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", - "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.29.7", - "@babel/helper-validator-option": "^7.29.7", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", - "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", - "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.29.7", - "@babel/types": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", - "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.29.7", - "@babel/helper-validator-identifier": "^7.29.7", - "@babel/traverse": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", - "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", - "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", - "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", - "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", - "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.29.7", - "@babel/types": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", - "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.8" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", - "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", - "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", - "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", - "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.7", - "@babel/parser": "^7.29.7", - "@babel/types": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", - "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.7", - "@babel/generator": "^7.29.8", - "@babel/helper-globals": "^7.29.7", - "@babel/parser": "^7.29.8", - "@babel/template": "^7.29.7", - "@babel/types": "^7.29.8", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", - "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.29.7", - "@babel/helper-validator-identifier": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@ethersproject/abi": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", - "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", - "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0" - } - }, - "node_modules/@ethersproject/abstract-provider/node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", - "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0" - } - }, - "node_modules/@ethersproject/address": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", - "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/rlp": "^5.8.0" - } - }, - "node_modules/@ethersproject/base64": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", - "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0" - } - }, - "node_modules/@ethersproject/basex": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.8.0.tgz", - "integrity": "sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/properties": "^5.8.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", - "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@ethersproject/bytes": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", - "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", - "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0" - } - }, - "node_modules/@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", - "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/base64": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@ethersproject/hdnode": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.8.0.tgz", - "integrity": "sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/basex": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/pbkdf2": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/sha2": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0", - "@ethersproject/strings": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/wordlists": "^5.8.0" - } - }, - "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.8.0.tgz", - "integrity": "sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/hdnode": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/pbkdf2": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/random": "^5.8.0", - "@ethersproject/strings": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" - } - }, - "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "license": "MIT" - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", - "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", - "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT" - }, - "node_modules/@ethersproject/networks": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", - "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz", - "integrity": "sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/sha2": "^5.8.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", - "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/providers": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.0.tgz", - "integrity": "sha512-+TTrrINMzZ0aXtlwO/95uhAggKm4USLm1PbeCBR/3XZ7+Oey+3pMyddzZEyRhizHpy1HXV0FRWRMI1O3EGYibA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@ethersproject/random": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.8.0.tgz", - "integrity": "sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", - "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/sha2": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.8.0.tgz", - "integrity": "sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", - "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "bn.js": "^5.2.1", - "elliptic": "6.6.1", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/solidity": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.8.0.tgz", - "integrity": "sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/sha2": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", - "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" - } - }, - "node_modules/@ethersproject/units": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.8.0.tgz", - "integrity": "sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.8.0.tgz", - "integrity": "sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/hdnode": "^5.8.0", - "@ethersproject/json-wallets": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/random": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/wordlists": "^5.8.0" - } - }, - "node_modules/@ethersproject/wallet/node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", - "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/base64": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@ethersproject/wordlists": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.8.0.tgz", - "integrity": "sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", - "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/environment": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", - "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", - "@types/node": "*", - "jest-mock": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", - "license": "MIT", - "dependencies": { - "expect": "30.2.0", - "jest-snapshot": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", - "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", - "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@sinonjs/fake-timers": "^13.0.0", - "@types/node": "*", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/get-type": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", - "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", - "license": "MIT", - "dependencies": { - "@jest/environment": "30.2.0", - "@jest/expect": "30.2.0", - "@jest/types": "30.2.0", - "jest-mock": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/snapshot-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", - "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "natural-compare": "^1.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", - "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@jest/types": "30.2.0", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", - "chalk": "^4.1.2", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "micromatch": "^4.0.8", - "pirates": "^4.0.7", - "slash": "^3.0.0", - "write-file-atomic": "^5.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", - "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@lit-protocol/access-control-conditions": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/access-control-conditions/-/access-control-conditions-8.0.2.tgz", - "integrity": "sha512-5F5fA6QZL4+hYmF0knePoPzyfZLvEudKdf/4Sn3ioHn5jivgnr9QoYL//eHwry7G9kdgeFSJz8rbxdj/d6WjeQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@ethersproject/contracts": "5.8.0", - "@ethersproject/providers": "5.7.0", - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/constants": "8.0.2", - "@lit-protocol/contracts": "0.5.3", - "@lit-protocol/logger": "8.0.2", - "@lit-protocol/schemas": "8.0.2", - "@lit-protocol/types": "8.0.2", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "pino": "^9.6.0", - "siwe": "^2.3.2", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/access-control-conditions-schemas/-/access-control-conditions-schemas-8.0.2.tgz", - "integrity": "sha512-aMElsRHLfjOM/S5cEwta6G2+OblSnIve51lv9HGjpb5Lamru4qqVTA8yQwlh7Wh5Sk4/1vZyZc1Mwp3fLxK+Aw==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/constants": "8.0.2", - "@lit-protocol/contracts": "0.5.3", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/@ethersproject/contracts": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.8.0.tgz", - "integrity": "sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "^5.8.0", - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/transactions": "^5.8.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/@ethersproject/providers": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz", - "integrity": "sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/base64": "^5.8.0", - "@ethersproject/basex": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/random": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/sha2": "^5.8.0", - "@ethersproject/strings": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0", - "bech32": "1.1.4", - "ws": "8.18.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/@lit-protocol/constants": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/constants/-/constants-8.0.2.tgz", - "integrity": "sha512-2jw9PNmU2w/DVRn86+hQmoiW5uCl9bNCPZv/4eS13fiPhi4VERys5lC9zxn4uUyLeCUivDlPnuP1LO0ElyfXxA==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/contracts": "0.5.3", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/@lit-protocol/contracts": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@lit-protocol/contracts/-/contracts-0.5.3.tgz", - "integrity": "sha512-s5q/X0iGLdJYY8dGUJi8EmVkfVJRxMfsVXAb4t/8YEWvOC1oQHuO069nqTPmCqkJO8OcDUknaSSkuxuDIvp2oQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "peerDependencies": { - "typescript": "^5.0.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/@noble/curves": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", - "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.7.2" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/@noble/hashes": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", - "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/@scure/bip32": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.2.tgz", - "integrity": "sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==", - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.8.1", - "@noble/hashes": "~1.7.1", - "@scure/base": "~1.2.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/@scure/bip39": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.4.tgz", - "integrity": "sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.7.1", - "@scure/base": "~1.2.4" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/ethers": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", - "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.8.0", - "@ethersproject/abstract-provider": "5.8.0", - "@ethersproject/abstract-signer": "5.8.0", - "@ethersproject/address": "5.8.0", - "@ethersproject/base64": "5.8.0", - "@ethersproject/basex": "5.8.0", - "@ethersproject/bignumber": "5.8.0", - "@ethersproject/bytes": "5.8.0", - "@ethersproject/constants": "5.8.0", - "@ethersproject/contracts": "5.8.0", - "@ethersproject/hash": "5.8.0", - "@ethersproject/hdnode": "5.8.0", - "@ethersproject/json-wallets": "5.8.0", - "@ethersproject/keccak256": "5.8.0", - "@ethersproject/logger": "5.8.0", - "@ethersproject/networks": "5.8.0", - "@ethersproject/pbkdf2": "5.8.0", - "@ethersproject/properties": "5.8.0", - "@ethersproject/providers": "5.8.0", - "@ethersproject/random": "5.8.0", - "@ethersproject/rlp": "5.8.0", - "@ethersproject/sha2": "5.8.0", - "@ethersproject/signing-key": "5.8.0", - "@ethersproject/solidity": "5.8.0", - "@ethersproject/strings": "5.8.0", - "@ethersproject/transactions": "5.8.0", - "@ethersproject/units": "5.8.0", - "@ethersproject/wallet": "5.8.0", - "@ethersproject/web": "5.8.0", - "@ethersproject/wordlists": "5.8.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/viem": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.29.4.tgz", - "integrity": "sha512-Dhyae+w1LKKpYVXypGjBnZ3WU5EHl/Uip5RtVwVRYSVxD5VvHzqKzIfbFU1KP4vnnh3++ZNgLjBY/kVT/tPrrg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@noble/curves": "1.8.2", - "@noble/hashes": "1.7.2", - "@scure/bip32": "1.6.2", - "@scure/bip39": "1.5.4", - "abitype": "1.0.8", - "isows": "1.0.7", - "ox": "0.6.9", - "ws": "8.18.1" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/viem/node_modules/abitype": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.8.tgz", - "integrity": "sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3 >=3.22.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/viem/node_modules/ox": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.9.tgz", - "integrity": "sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.10.1", - "@noble/curves": "^1.6.0", - "@noble/hashes": "^1.5.0", - "@scure/bip32": "^1.5.0", - "@scure/bip39": "^1.4.0", - "abitype": "^1.0.6", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/viem/node_modules/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/access-control-conditions-schemas/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/@ethersproject/contracts": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.8.0.tgz", - "integrity": "sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "^5.8.0", - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/transactions": "^5.8.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/@lit-protocol/constants": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/constants/-/constants-8.0.2.tgz", - "integrity": "sha512-2jw9PNmU2w/DVRn86+hQmoiW5uCl9bNCPZv/4eS13fiPhi4VERys5lC9zxn4uUyLeCUivDlPnuP1LO0ElyfXxA==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/contracts": "0.5.3", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/@lit-protocol/contracts": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@lit-protocol/contracts/-/contracts-0.5.3.tgz", - "integrity": "sha512-s5q/X0iGLdJYY8dGUJi8EmVkfVJRxMfsVXAb4t/8YEWvOC1oQHuO069nqTPmCqkJO8OcDUknaSSkuxuDIvp2oQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "peerDependencies": { - "typescript": "^5.0.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/@lit-protocol/schemas": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/schemas/-/schemas-8.0.2.tgz", - "integrity": "sha512-SdbYcm8nGg7HDyIgp/LK3d9wDZ9jpzZdPiRJeBHfoKfVq5qf44hugy/BO3IJXROVb+6TqrsEbsUS1rlqbqi/0A==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/constants": "8.0.2", - "@lit-protocol/contracts": "0.5.3", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "siwe": "^2.3.2", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/@lit-protocol/types": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/types/-/types-8.0.2.tgz", - "integrity": "sha512-IDppgwcAPiIBmzVhfgK5h/5WLhJPFnlEhKqq/6X24M+sD8JL/rfac9P99+lHYMienki8rj4L9+zIUDIotFZCLw==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/constants": "8.0.2", - "@lit-protocol/contracts": "0.5.3", - "@lit-protocol/schemas": "8.0.2", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "siwe": "^2.3.2", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/@noble/curves": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", - "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.7.2" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/@noble/hashes": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", - "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/@scure/bip32": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.2.tgz", - "integrity": "sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==", - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.8.1", - "@noble/hashes": "~1.7.1", - "@scure/base": "~1.2.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/@scure/bip39": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.4.tgz", - "integrity": "sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.7.1", - "@scure/base": "~1.2.4" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/ethers": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", - "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.8.0", - "@ethersproject/abstract-provider": "5.8.0", - "@ethersproject/abstract-signer": "5.8.0", - "@ethersproject/address": "5.8.0", - "@ethersproject/base64": "5.8.0", - "@ethersproject/basex": "5.8.0", - "@ethersproject/bignumber": "5.8.0", - "@ethersproject/bytes": "5.8.0", - "@ethersproject/constants": "5.8.0", - "@ethersproject/contracts": "5.8.0", - "@ethersproject/hash": "5.8.0", - "@ethersproject/hdnode": "5.8.0", - "@ethersproject/json-wallets": "5.8.0", - "@ethersproject/keccak256": "5.8.0", - "@ethersproject/logger": "5.8.0", - "@ethersproject/networks": "5.8.0", - "@ethersproject/pbkdf2": "5.8.0", - "@ethersproject/properties": "5.8.0", - "@ethersproject/providers": "5.8.0", - "@ethersproject/random": "5.8.0", - "@ethersproject/rlp": "5.8.0", - "@ethersproject/sha2": "5.8.0", - "@ethersproject/signing-key": "5.8.0", - "@ethersproject/solidity": "5.8.0", - "@ethersproject/strings": "5.8.0", - "@ethersproject/transactions": "5.8.0", - "@ethersproject/units": "5.8.0", - "@ethersproject/wallet": "5.8.0", - "@ethersproject/web": "5.8.0", - "@ethersproject/wordlists": "5.8.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/ethers/node_modules/@ethersproject/providers": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz", - "integrity": "sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/base64": "^5.8.0", - "@ethersproject/basex": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/random": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/sha2": "^5.8.0", - "@ethersproject/strings": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0", - "bech32": "1.1.4", - "ws": "8.18.0" - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/ethers/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/viem": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.29.4.tgz", - "integrity": "sha512-Dhyae+w1LKKpYVXypGjBnZ3WU5EHl/Uip5RtVwVRYSVxD5VvHzqKzIfbFU1KP4vnnh3++ZNgLjBY/kVT/tPrrg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@noble/curves": "1.8.2", - "@noble/hashes": "1.7.2", - "@scure/bip32": "1.6.2", - "@scure/bip39": "1.5.4", - "abitype": "1.0.8", - "isows": "1.0.7", - "ox": "0.6.9", - "ws": "8.18.1" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/viem/node_modules/abitype": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.8.tgz", - "integrity": "sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3 >=3.22.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/viem/node_modules/ox": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.9.tgz", - "integrity": "sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.10.1", - "@noble/curves": "^1.6.0", - "@noble/hashes": "^1.5.0", - "@scure/bip32": "^1.5.0", - "@scure/bip39": "^1.4.0", - "abitype": "^1.0.6", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/access-control-conditions/node_modules/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/accs-schemas": { - "version": "0.0.24", - "resolved": "https://registry.npmjs.org/@lit-protocol/accs-schemas/-/accs-schemas-0.0.24.tgz", - "integrity": "sha512-sjUfMAc8kj/Tj/GAFnlrbvs9PzoSK5wR3L1hK4kFI6lifq31LsDGqNLWmIEDXRubE/YusK5QaY30h+WPgk8RFQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "ajv": "^8.12.0" - } - }, - "node_modules/@lit-protocol/auth": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/@lit-protocol/auth/-/auth-8.2.3.tgz", - "integrity": "sha512-T7RaUhw0VbKyHivcUhTsaAGpPJSjWe0tSsu3ZluRNIPcerpNzX/jdVp4lVoozEKx491Ah2+lwAtWjYW6MiTXYQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@ethersproject/contracts": "5.7.0", - "@ethersproject/providers": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@jest/globals": "30.2.0", - "@lit-protocol/access-control-conditions": "8.0.2", - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/auth-helpers": "8.2.0", - "@lit-protocol/constants": "9.0.1", - "@lit-protocol/contracts": "0.9.1", - "@lit-protocol/crypto": "8.1.0", - "@lit-protocol/lit-client": "8.3.1", - "@lit-protocol/logger": "8.0.2", - "@lit-protocol/nacl": "7.1.1", - "@lit-protocol/networks": "8.4.1", - "@lit-protocol/schemas": "8.0.3", - "@lit-protocol/types": "8.0.3", - "@lit-protocol/uint8arrays": "7.1.1", - "@lit-protocol/wasm": "8.1.0", - "@noble/curves": "1.8.1", - "@noble/hashes": "1.8.0", - "@openagenda/verror": "3.1.4", - "@simplewebauthn/browser": "7.2.0", - "@simplewebauthn/typescript-types": "7.0.0", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "@wagmi/core": "2.22.1", - "ajv": "8.12.0", - "base64url": "3.0.1", - "bs58": "6.0.0", - "cbor-web": "9.0.2", - "depd": "2.0.0", - "elysia": "1.2.25", - "ethers": "5.7.2", - "jose": "4.14.4", - "pako": "2.1.0", - "pino": "9.6.0", - "pino-caller": "4.0.0", - "siwe": "2.3.2", - "siwe-recap": "0.0.2-alpha.0", - "stytch": "12.4.0", - "typechain": "8.3.2", - "typestub-ipfs-only-hash": "4.0.0", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - }, - "peerDependencies": { - "tslib": "2.8.1", - "viem": "2.38.3" - } - }, - "node_modules/@lit-protocol/auth-helpers": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@lit-protocol/auth-helpers/-/auth-helpers-8.2.0.tgz", - "integrity": "sha512-gIT123rGzP52iQ68WSAn/Ewq33bFy9VI10xhjLqa9kndYG7uuXoQTh95R5ORsQIvpZP+zVAVcEukMPAFq7G5pg==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@ethersproject/contracts": "5.7.0", - "@ethersproject/providers": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@lit-protocol/access-control-conditions": "8.0.2", - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/constants": "9.0.0", - "@lit-protocol/contracts": "0.9.0", - "@lit-protocol/logger": "8.0.2", - "@lit-protocol/schemas": "8.0.2", - "@lit-protocol/types": "8.0.2", - "@openagenda/verror": "3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "@wagmi/core": "2.22.1", - "ethers": "5.7.2", - "pino": "9.6.0", - "siwe": "2.3.2", - "siwe-recap": "0.0.2-alpha.0", - "tslib": "2.8.1", - "typechain": "8.3.2", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - }, - "peerDependencies": { - "viem": "2.38.3" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT" - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/constants": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@lit-protocol/constants/-/constants-9.0.0.tgz", - "integrity": "sha512-/BfZH2K351FQePsaUDPGtb6EDvi34Tkqg5wRZBrs9sh/WQB+1xXfbId3WHHSszV47adFS2n5Rk6dlEgUQSpWuA==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/contracts": "0.9.0", - "@openagenda/verror": "3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "5.7.2", - "tslib": "2.8.1", - "typechain": "8.3.2", - "viem": "2.38.3", - "zod": "3.24.3" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/contracts": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@lit-protocol/contracts/-/contracts-0.9.0.tgz", - "integrity": "sha512-roswC9kJaMvKWqRrw9/ROKWpG3S+vPtlWPqVDS6JOjcPmaEEitMtfsAmCM4i3LykGKkbrW4MCvIatglByRu/Xw==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "peerDependencies": { - "typescript": "5.8.3", - "viem": "2.38.3" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/schemas": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/schemas/-/schemas-8.0.2.tgz", - "integrity": "sha512-SdbYcm8nGg7HDyIgp/LK3d9wDZ9jpzZdPiRJeBHfoKfVq5qf44hugy/BO3IJXROVb+6TqrsEbsUS1rlqbqi/0A==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/constants": "8.0.2", - "@lit-protocol/contracts": "0.5.3", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "siwe": "^2.3.2", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/schemas/node_modules/@lit-protocol/constants": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/constants/-/constants-8.0.2.tgz", - "integrity": "sha512-2jw9PNmU2w/DVRn86+hQmoiW5uCl9bNCPZv/4eS13fiPhi4VERys5lC9zxn4uUyLeCUivDlPnuP1LO0ElyfXxA==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/contracts": "0.5.3", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/schemas/node_modules/@lit-protocol/contracts": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@lit-protocol/contracts/-/contracts-0.5.3.tgz", - "integrity": "sha512-s5q/X0iGLdJYY8dGUJi8EmVkfVJRxMfsVXAb4t/8YEWvOC1oQHuO069nqTPmCqkJO8OcDUknaSSkuxuDIvp2oQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "peerDependencies": { - "typescript": "^5.0.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/schemas/node_modules/viem": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.29.4.tgz", - "integrity": "sha512-Dhyae+w1LKKpYVXypGjBnZ3WU5EHl/Uip5RtVwVRYSVxD5VvHzqKzIfbFU1KP4vnnh3++ZNgLjBY/kVT/tPrrg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@noble/curves": "1.8.2", - "@noble/hashes": "1.7.2", - "@scure/bip32": "1.6.2", - "@scure/bip39": "1.5.4", - "abitype": "1.0.8", - "isows": "1.0.7", - "ox": "0.6.9", - "ws": "8.18.1" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/schemas/node_modules/viem/node_modules/abitype": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.8.tgz", - "integrity": "sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3 >=3.22.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/schemas/node_modules/viem/node_modules/ox": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.9.tgz", - "integrity": "sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.10.1", - "@noble/curves": "^1.6.0", - "@noble/hashes": "^1.5.0", - "@scure/bip32": "^1.5.0", - "@scure/bip39": "^1.4.0", - "abitype": "^1.0.6", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/schemas/node_modules/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/types": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/types/-/types-8.0.2.tgz", - "integrity": "sha512-IDppgwcAPiIBmzVhfgK5h/5WLhJPFnlEhKqq/6X24M+sD8JL/rfac9P99+lHYMienki8rj4L9+zIUDIotFZCLw==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/constants": "8.0.2", - "@lit-protocol/contracts": "0.5.3", - "@lit-protocol/schemas": "8.0.2", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "siwe": "^2.3.2", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/types/node_modules/@lit-protocol/constants": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/constants/-/constants-8.0.2.tgz", - "integrity": "sha512-2jw9PNmU2w/DVRn86+hQmoiW5uCl9bNCPZv/4eS13fiPhi4VERys5lC9zxn4uUyLeCUivDlPnuP1LO0ElyfXxA==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/contracts": "0.5.3", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/types/node_modules/@lit-protocol/contracts": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@lit-protocol/contracts/-/contracts-0.5.3.tgz", - "integrity": "sha512-s5q/X0iGLdJYY8dGUJi8EmVkfVJRxMfsVXAb4t/8YEWvOC1oQHuO069nqTPmCqkJO8OcDUknaSSkuxuDIvp2oQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "peerDependencies": { - "typescript": "^5.0.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/types/node_modules/viem": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.29.4.tgz", - "integrity": "sha512-Dhyae+w1LKKpYVXypGjBnZ3WU5EHl/Uip5RtVwVRYSVxD5VvHzqKzIfbFU1KP4vnnh3++ZNgLjBY/kVT/tPrrg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@noble/curves": "1.8.2", - "@noble/hashes": "1.7.2", - "@scure/bip32": "1.6.2", - "@scure/bip39": "1.5.4", - "abitype": "1.0.8", - "isows": "1.0.7", - "ox": "0.6.9", - "ws": "8.18.1" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/types/node_modules/viem/node_modules/abitype": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.8.tgz", - "integrity": "sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3 >=3.22.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/types/node_modules/viem/node_modules/ox": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.9.tgz", - "integrity": "sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.10.1", - "@noble/curves": "^1.6.0", - "@noble/hashes": "^1.5.0", - "@scure/bip32": "^1.5.0", - "@scure/bip39": "^1.4.0", - "abitype": "^1.0.6", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@lit-protocol/types/node_modules/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@noble/curves": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", - "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.7.2" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@noble/hashes": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", - "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@scure/bip32": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.2.tgz", - "integrity": "sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==", - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.8.1", - "@noble/hashes": "~1.7.1", - "@scure/base": "~1.2.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/@scure/bip39": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.4.tgz", - "integrity": "sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.7.1", - "@scure/base": "~1.2.4" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "license": "MIT" - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", - "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", - "license": "MIT" - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/ethers/node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/multiformats": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz", - "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==", - "license": "Apache-2.0 OR MIT", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@lit-protocol/auth-helpers/node_modules/siwe-recap": { - "version": "0.0.2-alpha.0", - "resolved": "https://registry.npmjs.org/siwe-recap/-/siwe-recap-0.0.2-alpha.0.tgz", - "integrity": "sha512-xqFUnvrACWW/Q4s5HQ02avg8IyH2RcgkUzfvN4scYaaHErotLVtTGDZkSS0sn/oNK4MXRt83lTqredsvXgt8iA==", - "license": "MIT", - "dependencies": { - "canonicalize": "^2.0.0", - "multiformats": "^11.0.2", - "siwe": "^2.1.4" - }, - "peerDependencies": { - "ethers": "^5.5.1" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT" - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "license": "MIT" - }, - "node_modules/@lit-protocol/auth/node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/@lit-protocol/auth/node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", - "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", - "license": "MIT" - }, - "node_modules/@lit-protocol/auth/node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/ethers/node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@lit-protocol/auth/node_modules/multiformats": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz", - "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==", - "license": "Apache-2.0 OR MIT", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@lit-protocol/auth/node_modules/siwe-recap": { - "version": "0.0.2-alpha.0", - "resolved": "https://registry.npmjs.org/siwe-recap/-/siwe-recap-0.0.2-alpha.0.tgz", - "integrity": "sha512-xqFUnvrACWW/Q4s5HQ02avg8IyH2RcgkUzfvN4scYaaHErotLVtTGDZkSS0sn/oNK4MXRt83lTqredsvXgt8iA==", - "license": "MIT", - "dependencies": { - "canonicalize": "^2.0.0", - "multiformats": "^11.0.2", - "siwe": "^2.1.4" - }, - "peerDependencies": { - "ethers": "^5.5.1" - } - }, - "node_modules/@lit-protocol/constants": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@lit-protocol/constants/-/constants-9.0.1.tgz", - "integrity": "sha512-gaCMUPvQw9a/Eb6kpTJOMpEYXU5jyca88yB35CFuJ+hUkcfO/QkzKVAMwP+tpgLV8NIvYhpRyxIhKdfLWXbmYw==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/contracts": "0.9.1", - "@openagenda/verror": "3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "5.7.2", - "tslib": "2.8.1", - "typechain": "8.3.2", - "viem": "2.38.3", - "zod": "3.24.3" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT" - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/constants/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "license": "MIT" - }, - "node_modules/@lit-protocol/constants/node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/@lit-protocol/constants/node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", - "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", - "license": "MIT" - }, - "node_modules/@lit-protocol/constants/node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/@lit-protocol/contracts": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@lit-protocol/contracts/-/contracts-0.9.1.tgz", - "integrity": "sha512-nbc46P++OBouzIxTT6O30byZmOvfi7ORpT/vZCdW7a39+tMDd2dWWaKfcFRMP/4oqGPppGnvFHLVKNuaPtriwA==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "peerDependencies": { - "typescript": "5.8.3", - "viem": "2.38.3" - } - }, - "node_modules/@lit-protocol/crypto": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@lit-protocol/crypto/-/crypto-8.1.0.tgz", - "integrity": "sha512-Ae2+sM6I6jB6r8VGKlnyU1+lhZ/rsJqassqWY3PRjOwgIVTZpu9AGFByQh5IqkLQ+s6BJXmksL64367cV5Zs3A==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@jest/globals": "30.2.0", - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/constants": "9.0.0", - "@lit-protocol/contracts": "0.9.0", - "@lit-protocol/nacl": "7.1.1", - "@lit-protocol/schemas": "8.0.2", - "@lit-protocol/types": "8.0.2", - "@lit-protocol/uint8arrays": "7.1.1", - "@lit-protocol/wasm": "8.1.0", - "@noble/curves": "1.8.1", - "@noble/hashes": "1.8.0", - "@openagenda/verror": "3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ajv": "8.12.0", - "ethers": "5.7.2", - "pako": "2.1.0", - "siwe": "2.3.2", - "tslib": "2.8.1", - "typechain": "8.3.2", - "viem": "2.38.3", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT" - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/constants": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@lit-protocol/constants/-/constants-9.0.0.tgz", - "integrity": "sha512-/BfZH2K351FQePsaUDPGtb6EDvi34Tkqg5wRZBrs9sh/WQB+1xXfbId3WHHSszV47adFS2n5Rk6dlEgUQSpWuA==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/contracts": "0.9.0", - "@openagenda/verror": "3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "5.7.2", - "tslib": "2.8.1", - "typechain": "8.3.2", - "viem": "2.38.3", - "zod": "3.24.3" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/contracts": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@lit-protocol/contracts/-/contracts-0.9.0.tgz", - "integrity": "sha512-roswC9kJaMvKWqRrw9/ROKWpG3S+vPtlWPqVDS6JOjcPmaEEitMtfsAmCM4i3LykGKkbrW4MCvIatglByRu/Xw==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "peerDependencies": { - "typescript": "5.8.3", - "viem": "2.38.3" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/schemas": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/schemas/-/schemas-8.0.2.tgz", - "integrity": "sha512-SdbYcm8nGg7HDyIgp/LK3d9wDZ9jpzZdPiRJeBHfoKfVq5qf44hugy/BO3IJXROVb+6TqrsEbsUS1rlqbqi/0A==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/constants": "8.0.2", - "@lit-protocol/contracts": "0.5.3", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "siwe": "^2.3.2", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/schemas/node_modules/@lit-protocol/constants": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/constants/-/constants-8.0.2.tgz", - "integrity": "sha512-2jw9PNmU2w/DVRn86+hQmoiW5uCl9bNCPZv/4eS13fiPhi4VERys5lC9zxn4uUyLeCUivDlPnuP1LO0ElyfXxA==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/contracts": "0.5.3", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/schemas/node_modules/@lit-protocol/contracts": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@lit-protocol/contracts/-/contracts-0.5.3.tgz", - "integrity": "sha512-s5q/X0iGLdJYY8dGUJi8EmVkfVJRxMfsVXAb4t/8YEWvOC1oQHuO069nqTPmCqkJO8OcDUknaSSkuxuDIvp2oQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "peerDependencies": { - "typescript": "^5.0.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/schemas/node_modules/@noble/curves": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", - "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.7.2" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/schemas/node_modules/@noble/hashes": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", - "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/schemas/node_modules/viem": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.29.4.tgz", - "integrity": "sha512-Dhyae+w1LKKpYVXypGjBnZ3WU5EHl/Uip5RtVwVRYSVxD5VvHzqKzIfbFU1KP4vnnh3++ZNgLjBY/kVT/tPrrg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@noble/curves": "1.8.2", - "@noble/hashes": "1.7.2", - "@scure/bip32": "1.6.2", - "@scure/bip39": "1.5.4", - "abitype": "1.0.8", - "isows": "1.0.7", - "ox": "0.6.9", - "ws": "8.18.1" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/schemas/node_modules/viem/node_modules/abitype": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.8.tgz", - "integrity": "sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3 >=3.22.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/schemas/node_modules/viem/node_modules/ox": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.9.tgz", - "integrity": "sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.10.1", - "@noble/curves": "^1.6.0", - "@noble/hashes": "^1.5.0", - "@scure/bip32": "^1.5.0", - "@scure/bip39": "^1.4.0", - "abitype": "^1.0.6", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/schemas/node_modules/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/types": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/types/-/types-8.0.2.tgz", - "integrity": "sha512-IDppgwcAPiIBmzVhfgK5h/5WLhJPFnlEhKqq/6X24M+sD8JL/rfac9P99+lHYMienki8rj4L9+zIUDIotFZCLw==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/constants": "8.0.2", - "@lit-protocol/contracts": "0.5.3", - "@lit-protocol/schemas": "8.0.2", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "siwe": "^2.3.2", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/types/node_modules/@lit-protocol/constants": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/constants/-/constants-8.0.2.tgz", - "integrity": "sha512-2jw9PNmU2w/DVRn86+hQmoiW5uCl9bNCPZv/4eS13fiPhi4VERys5lC9zxn4uUyLeCUivDlPnuP1LO0ElyfXxA==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/contracts": "0.5.3", - "@openagenda/verror": "^3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "^5.7.1", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "viem": "2.29.4", - "zod": "3.24.3" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/types/node_modules/@lit-protocol/contracts": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@lit-protocol/contracts/-/contracts-0.5.3.tgz", - "integrity": "sha512-s5q/X0iGLdJYY8dGUJi8EmVkfVJRxMfsVXAb4t/8YEWvOC1oQHuO069nqTPmCqkJO8OcDUknaSSkuxuDIvp2oQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "peerDependencies": { - "typescript": "^5.0.0" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/types/node_modules/@noble/curves": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", - "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.7.2" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/types/node_modules/@noble/hashes": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", - "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/types/node_modules/viem": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.29.4.tgz", - "integrity": "sha512-Dhyae+w1LKKpYVXypGjBnZ3WU5EHl/Uip5RtVwVRYSVxD5VvHzqKzIfbFU1KP4vnnh3++ZNgLjBY/kVT/tPrrg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@noble/curves": "1.8.2", - "@noble/hashes": "1.7.2", - "@scure/bip32": "1.6.2", - "@scure/bip39": "1.5.4", - "abitype": "1.0.8", - "isows": "1.0.7", - "ox": "0.6.9", - "ws": "8.18.1" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/types/node_modules/viem/node_modules/abitype": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.8.tgz", - "integrity": "sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3 >=3.22.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/types/node_modules/viem/node_modules/ox": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.9.tgz", - "integrity": "sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.10.1", - "@noble/curves": "^1.6.0", - "@noble/hashes": "^1.5.0", - "@scure/bip32": "^1.5.0", - "@scure/bip39": "^1.4.0", - "abitype": "^1.0.6", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@lit-protocol/types/node_modules/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@scure/bip32": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.2.tgz", - "integrity": "sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==", - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.8.1", - "@noble/hashes": "~1.7.1", - "@scure/base": "~1.2.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@scure/bip32/node_modules/@noble/hashes": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", - "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@scure/bip39": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.4.tgz", - "integrity": "sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.7.1", - "@scure/base": "~1.2.4" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/@scure/bip39/node_modules/@noble/hashes": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", - "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "license": "MIT" - }, - "node_modules/@lit-protocol/crypto/node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/@lit-protocol/crypto/node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", - "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", - "license": "MIT" - }, - "node_modules/@lit-protocol/crypto/node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/@lit-protocol/lit-client/-/lit-client-8.3.1.tgz", - "integrity": "sha512-3OyeB/j4iXhI47QCFtos8zyNCQWqpuEfv170PMs/chq+v1m+LT+ackm6MGv1XrAipGqAxcgCoDOLXkR9n0N6Ew==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@ethersproject/contracts": "5.7.0", - "@ethersproject/providers": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@jest/globals": "30.2.0", - "@lit-protocol/access-control-conditions": "8.0.2", - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/auth-helpers": "8.2.0", - "@lit-protocol/constants": "9.0.1", - "@lit-protocol/contracts": "0.9.1", - "@lit-protocol/crypto": "8.1.0", - "@lit-protocol/logger": "8.0.2", - "@lit-protocol/nacl": "7.1.1", - "@lit-protocol/networks": "8.4.1", - "@lit-protocol/schemas": "8.0.3", - "@lit-protocol/types": "8.0.3", - "@lit-protocol/uint8arrays": "7.1.1", - "@lit-protocol/wasm": "8.1.0", - "@noble/curves": "1.8.1", - "@noble/hashes": "1.8.0", - "@openagenda/verror": "3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "@wagmi/core": "2.22.1", - "ajv": "8.12.0", - "bs58": "6.0.0", - "elysia": "1.2.25", - "ethers": "5.7.2", - "pako": "2.1.0", - "pino": "9.6.0", - "pino-caller": "4.0.0", - "siwe": "2.3.2", - "siwe-recap": "0.0.2-alpha.0", - "tslib": "2.8.1", - "typechain": "8.3.2", - "typestub-ipfs-only-hash": "^4.0.0", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - }, - "peerDependencies": { - "viem": "2.38.3" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT" - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "license": "MIT" - }, - "node_modules/@lit-protocol/lit-client/node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", - "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", - "license": "MIT" - }, - "node_modules/@lit-protocol/lit-client/node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/ethers/node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/multiformats": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz", - "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==", - "license": "Apache-2.0 OR MIT", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@lit-protocol/lit-client/node_modules/siwe-recap": { - "version": "0.0.2-alpha.0", - "resolved": "https://registry.npmjs.org/siwe-recap/-/siwe-recap-0.0.2-alpha.0.tgz", - "integrity": "sha512-xqFUnvrACWW/Q4s5HQ02avg8IyH2RcgkUzfvN4scYaaHErotLVtTGDZkSS0sn/oNK4MXRt83lTqredsvXgt8iA==", - "license": "MIT", - "dependencies": { - "canonicalize": "^2.0.0", - "multiformats": "^11.0.2", - "siwe": "^2.1.4" - }, - "peerDependencies": { - "ethers": "^5.5.1" - } - }, - "node_modules/@lit-protocol/logger": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@lit-protocol/logger/-/logger-8.0.2.tgz", - "integrity": "sha512-261xUbpHs3UbCRnaardxn4IKe49fT5U1XeNkFWxyQqwF5XM6L/ldH+a3C3hM/Jr/Mm84vyqFsMqKFCQajjMEOQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "dependencies": { - "pino": "^9.6.0", - "tslib": "1.14.1" - } - }, - "node_modules/@lit-protocol/logger/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "license": "0BSD" - }, - "node_modules/@lit-protocol/nacl": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@lit-protocol/nacl/-/nacl-7.1.1.tgz", - "integrity": "sha512-uuaHcVFnf3G4zRGYN2CrhSVHWXNcCY+VGG2uGS+pSk4EtyRvf9aw8mctQinItua02mTTj6SfFs508VSJ1imWsw==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "tslib": "1.14.1" - } - }, - "node_modules/@lit-protocol/nacl/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "license": "0BSD" - }, - "node_modules/@lit-protocol/networks": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@lit-protocol/networks/-/networks-8.4.1.tgz", - "integrity": "sha512-36uuhCtAghXQAR/1oqlx/QK0nuYuMPMvpeQ4Yx9aoI3V7c3HAmtP1F+93Th7Y5twcI8nVIoB56XntKwXHNrv7g==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@ethersproject/contracts": "5.7.0", - "@ethersproject/providers": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@jest/globals": "30.2.0", - "@lit-protocol/access-control-conditions": "8.0.2", - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/auth-helpers": "8.2.0", - "@lit-protocol/constants": "9.0.1", - "@lit-protocol/contracts": "0.9.1", - "@lit-protocol/crypto": "8.1.0", - "@lit-protocol/logger": "8.0.2", - "@lit-protocol/nacl": "7.1.1", - "@lit-protocol/schemas": "8.0.3", - "@lit-protocol/types": "8.0.3", - "@lit-protocol/uint8arrays": "7.1.1", - "@lit-protocol/wasm": "8.1.0", - "@noble/curves": "1.8.1", - "@noble/hashes": "^1.8.0", - "@openagenda/verror": "3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "@wagmi/core": "2.22.1", - "ajv": "8.12.0", - "bs58": "6.0.0", - "elysia": "1.2.25", - "ethers": "5.7.2", - "node-localstorage": "3.0.5", - "pako": "2.1.0", - "pino": "9.6.0", - "pino-caller": "4.0.0", - "siwe": "2.3.2", - "siwe-recap": "0.0.2-alpha.0", - "tslib": "^2.8.1", - "typechain": "8.3.2", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - }, - "peerDependencies": { - "viem": "2.38.3" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT" - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "license": "MIT" - }, - "node_modules/@lit-protocol/networks/node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/@lit-protocol/networks/node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", - "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", - "license": "MIT" - }, - "node_modules/@lit-protocol/networks/node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/ethers/node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@lit-protocol/networks/node_modules/multiformats": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz", - "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==", - "license": "Apache-2.0 OR MIT", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@lit-protocol/networks/node_modules/siwe-recap": { - "version": "0.0.2-alpha.0", - "resolved": "https://registry.npmjs.org/siwe-recap/-/siwe-recap-0.0.2-alpha.0.tgz", - "integrity": "sha512-xqFUnvrACWW/Q4s5HQ02avg8IyH2RcgkUzfvN4scYaaHErotLVtTGDZkSS0sn/oNK4MXRt83lTqredsvXgt8iA==", - "license": "MIT", - "dependencies": { - "canonicalize": "^2.0.0", - "multiformats": "^11.0.2", - "siwe": "^2.1.4" - }, - "peerDependencies": { - "ethers": "^5.5.1" - } - }, - "node_modules/@lit-protocol/schemas": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@lit-protocol/schemas/-/schemas-8.0.3.tgz", - "integrity": "sha512-0ZB1JXaiWRNoTL+Dci5weiT3MEq4SFcq1g5tLIx7cWTjLY8KHypfVnd5hFs/KX7yUQl9DS0BLRlSUUGzS9l0eQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/constants": "9.0.1", - "@lit-protocol/contracts": "0.9.1", - "@openagenda/verror": "3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "5.7.2", - "siwe": "2.3.2", - "tslib": "2.8.1", - "typechain": "8.3.2", - "viem": "2.38.3", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT" - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "license": "MIT" - }, - "node_modules/@lit-protocol/schemas/node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/@lit-protocol/schemas/node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", - "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", - "license": "MIT" - }, - "node_modules/@lit-protocol/schemas/node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/@lit-protocol/types": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@lit-protocol/types/-/types-8.0.3.tgz", - "integrity": "sha512-6Y2RZrJ6n/s3FmhbtK2ccYrfGuapRajEklsVxj21sqHzOx0Q2/rIP4QiEw/k85YjTWLCCWAaiuR23ntdbtXDhg==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@lit-protocol/access-control-conditions-schemas": "8.0.2", - "@lit-protocol/constants": "9.0.1", - "@lit-protocol/contracts": "0.9.1", - "@lit-protocol/schemas": "8.0.3", - "@openagenda/verror": "3.1.4", - "@t3-oss/env-core": "0.13.8", - "@typechain/ethers-v6": "0.5.1", - "ethers": "5.7.2", - "siwe": "2.3.2", - "tslib": "2.8.1", - "typechain": "8.3.2", - "viem": "2.38.3", - "zod": "3.24.3", - "zod-validation-error": "3.4.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT" - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@lit-protocol/types/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "license": "MIT" - }, - "node_modules/@lit-protocol/types/node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/@lit-protocol/types/node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", - "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", - "license": "MIT" - }, - "node_modules/@lit-protocol/types/node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/@lit-protocol/uint8arrays": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@lit-protocol/uint8arrays/-/uint8arrays-7.1.1.tgz", - "integrity": "sha512-9EycDdx3WQSH97DwIXUVhJXblVR1iJZCSa7watNzt+j2Au7CikO/DiBpIHfBe7ULVLkCI7li5hAnVB9vDfDEtQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "5.7.0", - "@lit-protocol/accs-schemas": "^0.0.24", - "@lit-protocol/constants": "7.1.1", - "@lit-protocol/contracts": "^0.0.74", - "@lit-protocol/types": "7.1.1", - "@openagenda/verror": "^3.1.4", - "depd": "^2.0.0", - "ethers": "^5.7.1", - "siwe": "^2.3.2", - "tslib": "1.14.1" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/@ethersproject/contracts": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.8.0.tgz", - "integrity": "sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "^5.8.0", - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/transactions": "^5.8.0" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/@ethersproject/contracts/node_modules/@ethersproject/abstract-provider": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", - "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/@ethersproject/providers": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz", - "integrity": "sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/base64": "^5.8.0", - "@ethersproject/basex": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/random": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/sha2": "^5.8.0", - "@ethersproject/strings": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0", - "bech32": "1.1.4", - "ws": "8.18.0" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/@ethersproject/providers/node_modules/@ethersproject/abstract-provider": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", - "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/@lit-protocol/constants": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@lit-protocol/constants/-/constants-7.1.1.tgz", - "integrity": "sha512-wJY5r8D0FdvtkQtcjx5JfPC3Qeb5SZ1m72HTcvJdqaJaBgaPP4eg2JSUg9uNJ+knOCyfdiBPl47XlWTGqe1X4Q==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "5.7.0", - "@lit-protocol/accs-schemas": "^0.0.24", - "@lit-protocol/contracts": "^0.0.74", - "@lit-protocol/types": "7.1.1", - "@openagenda/verror": "^3.1.4", - "depd": "^2.0.0", - "ethers": "^5.7.1", - "siwe": "^2.3.2", - "tslib": "1.14.1" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/@lit-protocol/contracts": { - "version": "0.0.74", - "resolved": "https://registry.npmjs.org/@lit-protocol/contracts/-/contracts-0.0.74.tgz", - "integrity": "sha512-8uV038gzBp7ew7a4884SVt9Zhu8CtiTb+A8dKNnByxVoT1kFt4O4DmsaniV8p9AGjNR13IWfpU1NFChmPHVIpQ==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "peerDependencies": { - "typescript": "^5.0.0" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/@lit-protocol/types": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@lit-protocol/types/-/types-7.1.1.tgz", - "integrity": "sha512-oOtUOEA+5o6vb6xOx7x0vDG5IDsHANbWgB1nc23Ah7SctbITQM7F8VZNaCwRsSj8UxKjWD13eGsMHvMPxoFXdg==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "5.7.0", - "@lit-protocol/accs-schemas": "^0.0.24", - "depd": "^2.0.0", - "ethers": "^5.7.1", - "siwe": "^2.3.2", - "tslib": "1.14.1" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/ethers": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", - "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.8.0", - "@ethersproject/abstract-provider": "5.8.0", - "@ethersproject/abstract-signer": "5.8.0", - "@ethersproject/address": "5.8.0", - "@ethersproject/base64": "5.8.0", - "@ethersproject/basex": "5.8.0", - "@ethersproject/bignumber": "5.8.0", - "@ethersproject/bytes": "5.8.0", - "@ethersproject/constants": "5.8.0", - "@ethersproject/contracts": "5.8.0", - "@ethersproject/hash": "5.8.0", - "@ethersproject/hdnode": "5.8.0", - "@ethersproject/json-wallets": "5.8.0", - "@ethersproject/keccak256": "5.8.0", - "@ethersproject/logger": "5.8.0", - "@ethersproject/networks": "5.8.0", - "@ethersproject/pbkdf2": "5.8.0", - "@ethersproject/properties": "5.8.0", - "@ethersproject/providers": "5.8.0", - "@ethersproject/random": "5.8.0", - "@ethersproject/rlp": "5.8.0", - "@ethersproject/sha2": "5.8.0", - "@ethersproject/signing-key": "5.8.0", - "@ethersproject/solidity": "5.8.0", - "@ethersproject/strings": "5.8.0", - "@ethersproject/transactions": "5.8.0", - "@ethersproject/units": "5.8.0", - "@ethersproject/wallet": "5.8.0", - "@ethersproject/web": "5.8.0", - "@ethersproject/wordlists": "5.8.0" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/ethers/node_modules/@ethersproject/abstract-provider": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", - "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0" - } - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "license": "0BSD" - }, - "node_modules/@lit-protocol/uint8arrays/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@lit-protocol/wasm": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@lit-protocol/wasm/-/wasm-8.1.0.tgz", - "integrity": "sha512-V1EIJHdwoTdxdFoq6N9msatXBNBWZ8cIoa1RvnmerO2QcwAZmq+dYntVK9+F6lFN9p9YL6AI1PW5349WTxg1Zg==", - "deprecated": "This package targets a retired Lit Protocol network and is no longer maintained. See https://developer.litprotocol.com for the current SDK.", - "dependencies": { - "@jest/globals": "30.2.0", - "ethers": "^5.7.1", - "pako": "^2.1.0", - "tslib": "1.14.1" - } - }, - "node_modules/@lit-protocol/wasm/node_modules/@ethersproject/contracts": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.8.0.tgz", - "integrity": "sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "^5.8.0", - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/transactions": "^5.8.0" - } - }, - "node_modules/@lit-protocol/wasm/node_modules/@ethersproject/providers": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz", - "integrity": "sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/base64": "^5.8.0", - "@ethersproject/basex": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/random": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/sha2": "^5.8.0", - "@ethersproject/strings": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0", - "bech32": "1.1.4", - "ws": "8.18.0" - } - }, - "node_modules/@lit-protocol/wasm/node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" - } - }, - "node_modules/@lit-protocol/wasm/node_modules/ethers": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", - "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.8.0", - "@ethersproject/abstract-provider": "5.8.0", - "@ethersproject/abstract-signer": "5.8.0", - "@ethersproject/address": "5.8.0", - "@ethersproject/base64": "5.8.0", - "@ethersproject/basex": "5.8.0", - "@ethersproject/bignumber": "5.8.0", - "@ethersproject/bytes": "5.8.0", - "@ethersproject/constants": "5.8.0", - "@ethersproject/contracts": "5.8.0", - "@ethersproject/hash": "5.8.0", - "@ethersproject/hdnode": "5.8.0", - "@ethersproject/json-wallets": "5.8.0", - "@ethersproject/keccak256": "5.8.0", - "@ethersproject/logger": "5.8.0", - "@ethersproject/networks": "5.8.0", - "@ethersproject/pbkdf2": "5.8.0", - "@ethersproject/properties": "5.8.0", - "@ethersproject/providers": "5.8.0", - "@ethersproject/random": "5.8.0", - "@ethersproject/rlp": "5.8.0", - "@ethersproject/sha2": "5.8.0", - "@ethersproject/signing-key": "5.8.0", - "@ethersproject/solidity": "5.8.0", - "@ethersproject/strings": "5.8.0", - "@ethersproject/transactions": "5.8.0", - "@ethersproject/units": "5.8.0", - "@ethersproject/wallet": "5.8.0", - "@ethersproject/web": "5.8.0", - "@ethersproject/wordlists": "5.8.0" - } - }, - "node_modules/@lit-protocol/wasm/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "license": "0BSD" - }, - "node_modules/@lit-protocol/wasm/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@multiformats/base-x": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@multiformats/base-x/-/base-x-4.0.1.tgz", - "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==", - "license": "MIT" - }, - "node_modules/@noble/ciphers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", - "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/curves": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz", - "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.7.1" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", - "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@openagenda/verror": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@openagenda/verror/-/verror-3.1.4.tgz", - "integrity": "sha512-+V7QuD6v5sMWez7cu+5DXoXMim+iQssOcspoNgbWDW8sEyC54Mdo5VuIkcIjqhPmQYOzBWo5qlbzNGEpD6PzMA==", - "license": "MIT", - "dependencies": { - "assertion-error": "^1.1.0", - "depd": "^2.0.0", - "inherits": "^2.0.4", - "sprintf-js": "^1.1.2" - } - }, - "node_modules/@pkgr/core": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz", - "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==", - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", - "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", - "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", - "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.2.tgz", - "integrity": "sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", - "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", - "license": "BSD-3-Clause" - }, - "node_modules/@scure/base": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", - "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", - "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.9.0", - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32/node_modules/@noble/curves": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", - "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", - "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@simplewebauthn/browser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-7.2.0.tgz", - "integrity": "sha512-HHIvRPpqKy0UV/BsGAmx4rQRZuZTUFYLLH65FwpSOslqHruiHx3Ql/bq7A75bjWuJ296a+4BIAq3+SPaII01TQ==", - "license": "MIT", - "dependencies": { - "@simplewebauthn/typescript-types": "*" - } - }, - "node_modules/@simplewebauthn/typescript-types": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@simplewebauthn/typescript-types/-/typescript-types-7.0.0.tgz", - "integrity": "sha512-bV+xACCFTsrLR/23ozHO06ZllHZaxC8LlI5YCo79GvU2BrN+rePDU2yXwZIYndNWcMQwRdndRdAhpafOh9AC/g==", - "deprecated": "This package has been renamed to @simplewebauthn/types. Please install @simplewebauthn/types instead to ensure you receive future updates.", - "license": "MIT" - }, - "node_modules/@sinclair/typebox": { - "version": "0.34.52", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", - "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" - } - }, - "node_modules/@spruceid/siwe-parser": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@spruceid/siwe-parser/-/siwe-parser-2.1.2.tgz", - "integrity": "sha512-d/r3S1LwJyMaRAKQ0awmo9whfXeE88Qt00vRj91q5uv5ATtWIQEGJ67Yr5eSZw5zp1/fZCXZYuEckt8lSkereQ==", - "license": "Apache-2.0", - "dependencies": { - "@noble/hashes": "^1.1.2", - "apg-js": "^4.3.0", - "uri-js": "^4.4.1", - "valid-url": "^1.0.9" - } - }, - "node_modules/@stablelib/binary": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", - "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", - "license": "MIT", - "dependencies": { - "@stablelib/int": "^1.0.1" - } - }, - "node_modules/@stablelib/int": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", - "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==", - "license": "MIT" - }, - "node_modules/@stablelib/random": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.2.tgz", - "integrity": "sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==", - "license": "MIT", - "dependencies": { - "@stablelib/binary": "^1.0.1", - "@stablelib/wipe": "^1.0.1" - } - }, - "node_modules/@stablelib/wipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", - "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==", - "license": "MIT" - }, - "node_modules/@t3-oss/env-core": { - "version": "0.13.8", - "resolved": "https://registry.npmjs.org/@t3-oss/env-core/-/env-core-0.13.8.tgz", - "integrity": "sha512-L1inmpzLQyYu4+Q1DyrXsGJYCXbtXjC4cICw1uAKv0ppYPQv656lhZPU91Qd1VS6SO/bou1/q5ufVzBGbNsUpw==", - "license": "MIT", - "peerDependencies": { - "arktype": "^2.1.0", - "typescript": ">=5.0.0", - "valibot": "^1.0.0-beta.7 || ^1.0.0", - "zod": "^3.24.0 || ^4.0.0-beta.0" - }, - "peerDependenciesMeta": { - "arktype": { - "optional": true - }, - "typescript": { - "optional": true - }, - "valibot": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/@typechain/ethers-v6": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz", - "integrity": "sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==", - "license": "MIT", - "dependencies": { - "lodash": "^4.17.15", - "ts-essentials": "^7.0.1" - }, - "peerDependencies": { - "ethers": "6.x", - "typechain": "^8.3.2", - "typescript": ">=4.7.0" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", - "license": "MIT" - }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.20.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.3.tgz", - "integrity": "sha512-DZmzkmwHzXrLPAXPyKNDzlIwMMUZCVacoD25ywdy5YTKGbOx/2ld+Q38Im2zJ0vBuZP5Prd3VZutKZyXwkOS8A==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "license": "MIT" - }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "license": "MIT" - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "license": "MIT" - }, - "node_modules/@types/yargs": { - "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", - "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "license": "MIT" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz", - "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==", - "license": "ISC" - }, - "node_modules/@wagmi/core": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/@wagmi/core/-/core-2.22.1.tgz", - "integrity": "sha512-cG/xwQWsBEcKgRTkQVhH29cbpbs/TdcUJVFXCyri3ZknxhMyGv0YEjTcrNpRgt2SaswL1KrvslSNYKKo+5YEAg==", - "license": "MIT", - "dependencies": { - "eventemitter3": "5.0.1", - "mipd": "0.0.7", - "zustand": "5.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "@tanstack/query-core": ">=5.0.0", - "typescript": ">=5.0.4", - "viem": "2.x" - }, - "peerDependenciesMeta": { - "@tanstack/query-core": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/abitype": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.1.0.tgz", - "integrity": "sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3.22.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/aes-js": { - "version": "4.0.0-beta.5", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", - "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", - "license": "MIT", - "peer": true - }, - "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/apg-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/apg-js/-/apg-js-4.4.0.tgz", - "integrity": "sha512-fefmXFknJmtgtNEXfPwZKYkMFX4Fyeyz+fNF6JWp87biGOPslJbCBVU158zvKRZfHBKnJDy8CMM40oLFGkXT8Q==", - "license": "BSD-2-Clause" - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/argparse/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" - }, - "node_modules/array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/atomic-sleep": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", - "license": "BSD-3-Clause", - "workspaces": [ - "test/babel-8" - ], - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", - "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/base-x": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.1.tgz", - "integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==", - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/base64url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", - "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.11.24", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.24.tgz", - "integrity": "sha512-hYrgxie335U08WqICoGqKRzV1HFXv6zdxwJE4ekCb80CM9a0SVVsN4QPwT67RraRo+9h8IATk6uxHJw7QSkdOg==", - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "license": "MIT" - }, - "node_modules/bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", - "license": "MIT", - "dependencies": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "license": "MIT" - }, - "node_modules/bn.js": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.5.tgz", - "integrity": "sha512-Vq886eXykuP5E6HcKSSStP3bJgrE6In5WKxVUvJ8XGpWWYs2xZHWqUwzCtGgEtBcxyd57KBFDPFoUfNzdaHCNg==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "1.1.21", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", - "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "license": "MIT" - }, - "node_modules/browserslist": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.0.tgz", - "integrity": "sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.11.23", - "caniuse-lite": "^1.0.30001810", - "electron-to-chromium": "^1.5.427", - "node-releases": "^2.0.55", - "update-browserslist-db": "^1.3.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs58": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", - "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", - "license": "MIT", - "dependencies": { - "base-x": "^5.0.0" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "license": "MIT", - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001810", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", - "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/canonicalize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-2.1.0.tgz", - "integrity": "sha512-F705O3xrsUtgt98j7leetNhTWPe+5S72rlL5O4jA1pKqBVQ/dT1O1D6PFxmSXvc0SUOinWS57DKx0I3CHrXJHQ==", - "license": "Apache-2.0", - "bin": { - "canonicalize": "bin/canonicalize.js" - } - }, - "node_modules/cbor-web": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/cbor-web/-/cbor-web-9.0.2.tgz", - "integrity": "sha512-N6gU2GsJS8RR5gy1d9wQcSPgn9FGJFY7KNvdDRlwHfz6kCxrQr2TDnrjXHmr6TFSl6Fd0FC4zRnityEldjRGvQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cids": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/cids/-/cids-1.1.9.tgz", - "integrity": "sha512-l11hWRfugIcbGuTZwAM5PwpjPPjyb6UZOGwlHSnOBV5o07XhQ4gNpBN67FbODvpjyHtd+0Xs6KNvUcGBiDRsdg==", - "deprecated": "This module has been superseded by the multiformats module", - "license": "MIT", - "dependencies": { - "multibase": "^4.0.1", - "multicodec": "^3.0.1", - "multihashes": "^4.0.1", - "uint8arrays": "^3.0.0" - }, - "engines": { - "node": ">=4.0.0", - "npm": ">=3.0.0" - } - }, - "node_modules/cids/node_modules/uint8arrays": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", - "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", - "license": "MIT", - "dependencies": { - "multiformats": "^9.4.2" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/command-line-args": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", - "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", - "license": "MIT", - "dependencies": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", - "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/command-line-usage": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", - "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", - "license": "MIT", - "dependencies": { - "array-back": "^4.0.2", - "chalk": "^2.4.2", - "table-layout": "^1.0.2", - "typical": "^5.2.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/command-line-usage/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/command-line-usage/node_modules/array-back": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", - "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/command-line-usage/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/command-line-usage/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/command-line-usage/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, - "node_modules/command-line-usage/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/command-line-usage/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/command-line-usage/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/command-line-usage/node_modules/typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "license": "MIT" - }, - "node_modules/cookie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "license": "MIT", - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.430", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.430.tgz", - "integrity": "sha512-e1QEj72Y4zd8RlNZVmoTg+iCOSVwpk05IOiiQwdrkwCSVlZfPthevErhE+nckGd2YbsXfp1SkisznhGVIXP2NQ==", - "license": "ISC" - }, - "node_modules/elliptic": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", - "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", - "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", - "license": "MIT" - }, - "node_modules/elysia": { - "version": "1.2.25", - "resolved": "https://registry.npmjs.org/elysia/-/elysia-1.2.25.tgz", - "integrity": "sha512-WsdQpORJvb4uszzeqYT0lg97knw1iBW1NTzJ1Jm57tiHg+DfAotlWXYbjmvQ039ssV0fYELDHinLLoUazZkEHg==", - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.27", - "cookie": "^1.0.2", - "memoirist": "^0.3.0", - "openapi-types": "^12.1.3" - }, - "peerDependencies": { - "@sinclair/typebox": ">= 0.34.0", - "openapi-types": ">= 12.0.0", - "typescript": ">= 5.0.0" - }, - "peerDependenciesMeta": { - "openapi-types": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/err-code": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", - "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==", - "license": "MIT" - }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ethers": { - "version": "6.17.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.17.0.tgz", - "integrity": "sha512-BpyrpIPJ3ydEVow8zGaz1DuPS7YU8DcWxuBnY9a0UA/lvAPwrMr+EPXsfrul628SRaekPNeIM4UFh/91GWZang==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/ethers-io/" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@adraffy/ens-normalize": "1.11.1", - "@noble/curves": "1.2.0", - "@noble/hashes": "1.3.2", - "@types/node": "22.7.5", - "aes-js": "4.0.0-beta.5", - "tslib": "2.7.0", - "ws": "8.21.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/ethers/node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@noble/hashes": "1.3.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ethers/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ethers/node_modules/@types/node": { - "version": "22.7.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", - "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/ethers/node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "license": "0BSD", - "peer": true - }, - "node_modules/ethers/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT", - "peer": true - }, - "node_modules/ethers/node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" - }, - "node_modules/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "30.2.0", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-redact": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", - "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", - "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", - "license": "MIT", - "dependencies": { - "array-back": "^3.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/hamt-sharding": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-2.0.1.tgz", - "integrity": "sha512-vnjrmdXG9dDs1m/H4iJ6z0JFI2NtgsW5keRkTcM85NGak69Mkf5PHUqBz+Xs0T4sg0ppvj9O5EGAJo40FTxmmA==", - "license": "MIT", - "dependencies": { - "sparse-array": "^1.3.1", - "uint8arrays": "^3.0.0" - }, - "engines": { - "node": ">=10.0.0", - "npm": ">=6.0.0" - } - }, - "node_modules/hamt-sharding/node_modules/uint8arrays": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", - "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", - "license": "MIT", - "dependencies": { - "multiformats": "^9.4.2" - } - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hasown": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", - "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "license": "MIT", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/hosted-git-info/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/interface-ipld-format": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/interface-ipld-format/-/interface-ipld-format-1.0.1.tgz", - "integrity": "sha512-WV/ar+KQJVoQpqRDYdo7YPGYIUHJxCuOEhdvsRpzLqoOIVCqPKdMMYmsLL1nCRsF3yYNio+PAJbCKiv6drrEAg==", - "deprecated": "This module has been superseded by the multiformats module", - "license": "(Apache-2.0 AND MIT)", - "dependencies": { - "cids": "^1.1.6", - "multicodec": "^3.0.1", - "multihashes": "^4.0.2" - } - }, - "node_modules/ipfs-only-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ipfs-only-hash/-/ipfs-only-hash-4.0.0.tgz", - "integrity": "sha512-TE1DZCvfw8i3gcsTq3P4TFx3cKFJ3sluu/J3XINkJhIN9OwJgNMqKA+WnKx6ByCb1IoPXsTp1KM7tupElb6SyA==", - "license": "MIT", - "dependencies": { - "ipfs-unixfs-importer": "^7.0.1", - "meow": "^9.0.0" - }, - "bin": { - "ipfs-only-hash": "cli.js" - } - }, - "node_modules/ipfs-unixfs": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-4.0.3.tgz", - "integrity": "sha512-hzJ3X4vlKT8FQ3Xc4M1szaFVjsc1ZydN+E4VQ91aXxfpjFn9G2wsMo1EFdAXNq/BUnN5dgqIOMP5zRYr3DTsAw==", - "license": "MIT", - "dependencies": { - "err-code": "^3.0.1", - "protobufjs": "^6.10.2" - }, - "engines": { - "node": ">=14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/ipfs-unixfs-importer": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-7.0.3.tgz", - "integrity": "sha512-qeFOlD3AQtGzr90sr5Tq1Bi8pT5Nr2tSI8z310m7R4JDYgZc6J1PEZO3XZQ8l1kuGoqlAppBZuOYmPEqaHcVQQ==", - "license": "MIT", - "dependencies": { - "bl": "^5.0.0", - "cids": "^1.1.5", - "err-code": "^3.0.1", - "hamt-sharding": "^2.0.0", - "ipfs-unixfs": "^4.0.3", - "ipld-dag-pb": "^0.22.2", - "it-all": "^1.0.5", - "it-batch": "^1.0.8", - "it-first": "^1.0.6", - "it-parallel-batch": "^1.0.9", - "merge-options": "^3.0.4", - "multihashing-async": "^2.1.0", - "rabin-wasm": "^0.1.4", - "uint8arrays": "^2.1.2" - }, - "engines": { - "node": ">=14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/ipld-dag-pb": { - "version": "0.22.3", - "resolved": "https://registry.npmjs.org/ipld-dag-pb/-/ipld-dag-pb-0.22.3.tgz", - "integrity": "sha512-dfG5C5OVAR4FEP7Al2CrHWvAyIM7UhAQrjnOYOIxXGQz5NlEj6wGX0XQf6Ru6or1na6upvV3NQfstapQG8X2rg==", - "deprecated": "This module has been superseded by @ipld/dag-pb and multiformats", - "license": "MIT", - "dependencies": { - "cids": "^1.0.0", - "interface-ipld-format": "^1.0.0", - "multicodec": "^3.0.1", - "multihashing-async": "^2.0.0", - "protobufjs": "^6.10.2", - "stable": "^0.1.8", - "uint8arrays": "^2.0.5" - }, - "engines": { - "node": ">=6.0.0", - "npm": ">=3.0.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "license": "MIT" - }, - "node_modules/is-core-module": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", - "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/isows": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", - "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "peerDependencies": { - "ws": "*" - } - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/it-all": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/it-all/-/it-all-1.0.6.tgz", - "integrity": "sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A==", - "license": "ISC" - }, - "node_modules/it-batch": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/it-batch/-/it-batch-1.0.9.tgz", - "integrity": "sha512-7Q7HXewMhNFltTsAMdSz6luNhyhkhEtGGbYek/8Xb/GiqYMtwUmopE1ocPSiJKKp3rM4Dt045sNFoUu+KZGNyA==", - "license": "ISC" - }, - "node_modules/it-first": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/it-first/-/it-first-1.0.7.tgz", - "integrity": "sha512-nvJKZoBpZD/6Rtde6FXqwDqDZGF1sCADmr2Zoc0hZsIvnE449gRFnGctxDf09Bzc/FWnHXAdaHVIetY6lrE0/g==", - "license": "ISC" - }, - "node_modules/it-parallel-batch": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/it-parallel-batch/-/it-parallel-batch-1.0.11.tgz", - "integrity": "sha512-UWsWHv/kqBpMRmyZJzlmZeoAMA0F3SZr08FBdbhtbe+MtoEBgr/ZUAKrnenhXCBrsopy76QjRH2K/V8kNdupbQ==", - "license": "ISC", - "dependencies": { - "it-batch": "^1.0.9" - } - }, - "node_modules/jest-diff": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", - "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", - "license": "MIT", - "dependencies": { - "@jest/diff-sequences": "30.0.1", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", - "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "anymatch": "^3.1.3", - "fb-watchman": "^2.0.2", - "graceful-fs": "^4.2.11", - "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "jest-worker": "30.2.0", - "micromatch": "^4.0.8", - "walker": "^1.0.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" - } - }, - "node_modules/jest-matcher-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", - "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.2.0", - "pretty-format": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", - "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.2.0", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-mock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", - "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "jest-util": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-regex-util": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz", - "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@babel/generator": "^7.27.5", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1", - "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.2.0", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", - "babel-preset-current-node-syntax": "^1.2.0", - "chalk": "^4.1.2", - "expect": "30.2.0", - "graceful-fs": "^4.2.11", - "jest-diff": "30.2.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "pretty-format": "30.2.0", - "semver": "^7.7.2", - "synckit": "^0.11.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-util/node_modules/picomatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", - "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-worker": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", - "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.2.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jose": { - "version": "4.14.4", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.14.4.tgz", - "integrity": "sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "license": "MIT" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "3.15.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz", - "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", - "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", - "license": "MIT" - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "license": "MIT" - }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "license": "Apache-2.0" - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/memoirist": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memoirist/-/memoirist-0.3.1.tgz", - "integrity": "sha512-lmk4Z45IuVZPT67nxAdD3rAsNExxMEBFXgCeJGJnoLkYOjmZnJ8Hmi+MGdl9oLKtAENFAAgG8FvV3Z8BNiqy8w==", - "license": "MIT" - }, - "node_modules/meow": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", - "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", - "license": "MIT", - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize": "^1.2.0", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-options": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", - "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", - "license": "MIT", - "dependencies": { - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "license": "MIT" - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "license": "ISC" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "license": "MIT" - }, - "node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "license": "MIT", - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/minimist-options/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mipd": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mipd/-/mipd-0.0.7.tgz", - "integrity": "sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wagmi-dev" - } - ], - "license": "MIT", - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/multibase": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-4.0.6.tgz", - "integrity": "sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ==", - "deprecated": "This module has been superseded by the multiformats module", - "license": "MIT", - "dependencies": { - "@multiformats/base-x": "^4.0.1" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=6.0.0" - } - }, - "node_modules/multicodec": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-3.2.1.tgz", - "integrity": "sha512-+expTPftro8VAW8kfvcuNNNBgb9gPeNYV9dn+z1kJRWF2vih+/S79f2RVeIwmrJBUJ6NT9IUPWnZDQvegEh5pw==", - "deprecated": "This module has been superseded by the multiformats module", - "license": "MIT", - "dependencies": { - "uint8arrays": "^3.0.0", - "varint": "^6.0.0" - } - }, - "node_modules/multicodec/node_modules/uint8arrays": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", - "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", - "license": "MIT", - "dependencies": { - "multiformats": "^9.4.2" - } - }, - "node_modules/multiformats": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", - "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==", - "license": "(Apache-2.0 AND MIT)" - }, - "node_modules/multihashes": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-4.0.3.tgz", - "integrity": "sha512-0AhMH7Iu95XjDLxIeuCOOE4t9+vQZsACyKZ9Fxw2pcsRmlX4iCn1mby0hS0bb+nQOVpdQYWPpnyusw4da5RPhA==", - "license": "MIT", - "dependencies": { - "multibase": "^4.0.1", - "uint8arrays": "^3.0.0", - "varint": "^5.0.2" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=6.0.0" - } - }, - "node_modules/multihashes/node_modules/uint8arrays": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", - "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", - "license": "MIT", - "dependencies": { - "multiformats": "^9.4.2" - } - }, - "node_modules/multihashes/node_modules/varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", - "license": "MIT" - }, - "node_modules/multihashing-async": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/multihashing-async/-/multihashing-async-2.1.4.tgz", - "integrity": "sha512-sB1MiQXPSBTNRVSJc2zM157PXgDtud2nMFUEIvBrsq5Wv96sUclMRK/ecjoP1T/W61UJBqt4tCTwMkUpt2Gbzg==", - "license": "MIT", - "dependencies": { - "blakejs": "^1.1.0", - "err-code": "^3.0.0", - "js-sha3": "^0.8.0", - "multihashes": "^4.0.1", - "murmurhash3js-revisited": "^3.0.0", - "uint8arrays": "^3.0.0" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=6.0.0" - } - }, - "node_modules/multihashing-async/node_modules/uint8arrays": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", - "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", - "license": "MIT", - "dependencies": { - "multiformats": "^9.4.2" - } - }, - "node_modules/murmurhash3js-revisited": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz", - "integrity": "sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==", - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "license": "MIT" - }, - "node_modules/node-localstorage": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-3.0.5.tgz", - "integrity": "sha512-GCwtK33iwVXboZWYcqQHu3aRvXEBwmPkAMRBLeaX86ufhqslyUkLGsi4aW3INEfdQYpUB5M9qtYf3eHvAk2VBg==", - "license": "MIT", - "dependencies": { - "write-file-atomic": "^5.0.1" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/node-releases": { - "version": "2.0.55", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.55.tgz", - "integrity": "sha512-mIrE/Cw9y+9Au6dS5vDKDhQza9YvG6w+ZrS6X+ZzA7yFW/soAeaups4Qzn1bL6g5FVy8WtP79+0j82oPIbqRjQ==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/on-exit-leak-free": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", - "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/openapi-types": { - "version": "12.1.3", - "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", - "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", - "license": "MIT" - }, - "node_modules/ox": { - "version": "0.9.6", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.9.6.tgz", - "integrity": "sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.11.0", - "@noble/ciphers": "^1.3.0", - "@noble/curves": "1.9.1", - "@noble/hashes": "^1.8.0", - "@scure/bip32": "^1.7.0", - "@scure/bip39": "^1.6.0", - "abitype": "^1.0.9", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/ox/node_modules/@noble/curves": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", - "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", - "license": "(MIT AND Zlib)" - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pino": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-9.6.0.tgz", - "integrity": "sha512-i85pKRCt4qMjZ1+L7sy2Ag4t1atFcdbEt76+7iRJn1g2BvsnRMGu9p8pivl9fs63M2kF/A0OacFZhTub+m/qMg==", - "license": "MIT", - "dependencies": { - "atomic-sleep": "^1.0.0", - "fast-redact": "^3.1.1", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^2.0.0", - "pino-std-serializers": "^7.0.0", - "process-warning": "^4.0.0", - "quick-format-unescaped": "^4.0.3", - "real-require": "^0.2.0", - "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^4.0.1", - "thread-stream": "^3.0.0" - }, - "bin": { - "pino": "bin.js" - } - }, - "node_modules/pino-abstract-transport": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", - "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", - "license": "MIT", - "dependencies": { - "split2": "^4.0.0" - } - }, - "node_modules/pino-caller": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pino-caller/-/pino-caller-4.0.0.tgz", - "integrity": "sha512-z0i/iYp4zH02uIQG8LwFK5dMKTdAYgwZM9LSzoOATJ0H5LTeJ3OZeNBpGget9DpnNaewIt5NkN5YGNvkCZ+JbQ==", - "license": "MIT", - "dependencies": { - "source-map-support": "^0.5.13" - }, - "engines": { - "node": ">6.0.0" - } - }, - "node_modules/pino-std-serializers": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", - "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", - "license": "MIT" - }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", - "license": "MIT", - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/process-warning": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.1.tgz", - "integrity": "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "MIT" - }, - "node_modules/protobufjs": { - "version": "6.11.6", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.6.tgz", - "integrity": "sha512-k8BHqgPBOtrlougZZqF2uUk5Z7bN8f0wj+3e8M3hvtSv0NBAz4VBy5f6R5Nxq/l+i7mRFTgNZb2trxqTpHNY/A==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/quick-format-unescaped": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", - "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/rabin-wasm": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/rabin-wasm/-/rabin-wasm-0.1.5.tgz", - "integrity": "sha512-uWgQTo7pim1Rnj5TuWcCewRDTf0PEFTSlaUjWP4eY9EbLV9em08v89oCz/WO+wRxpYuO36XEHp4wgYQnAgOHzA==", - "license": "MIT", - "dependencies": { - "@assemblyscript/loader": "^0.9.4", - "bl": "^5.0.0", - "debug": "^4.3.1", - "minimist": "^1.2.5", - "node-fetch": "^2.6.1", - "readable-stream": "^3.6.0" - }, - "bin": { - "rabin-wasm": "cli/bin.js" - } - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" - }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "license": "MIT", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "license": "ISC" - }, - "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/real-require": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", - "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", - "license": "MIT", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "license": "MIT", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/reduce-flatten": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", - "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", - "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safe-stable-stringify": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", - "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "license": "MIT" - }, - "node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/siwe": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/siwe/-/siwe-2.3.2.tgz", - "integrity": "sha512-aSf+6+Latyttbj5nMu6GF3doMfv2UYj83hhwZgUF20ky6fTS83uVhkQABdIVnEuS8y1bBdk7p6ltb9SmlhTTlA==", - "license": "Apache-2.0", - "dependencies": { - "@spruceid/siwe-parser": "^2.1.2", - "@stablelib/random": "^1.0.1", - "uri-js": "^4.4.1", - "valid-url": "^1.0.9" - }, - "peerDependencies": { - "ethers": "^5.6.8 || ^6.0.8" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/sonic-boom": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", - "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", - "license": "MIT", - "dependencies": { - "atomic-sleep": "^1.0.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sparse-array": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/sparse-array/-/sparse-array-1.3.2.tgz", - "integrity": "sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg==", - "license": "ISC" - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.23", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", - "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", - "license": "CC0-1.0" - }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "license": "ISC", - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "license": "BSD-3-Clause" - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", - "license": "MIT" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-format": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", - "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", - "license": "WTFPL OR MIT" - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/stytch": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/stytch/-/stytch-12.4.0.tgz", - "integrity": "sha512-jyYIfirVnhy3gAtGLEIK5c5tSp5bhi9tUE0JRzItJlwISBW/StMMOvP0hhPUb831EGjV2l1S4YRPg/NqJ+eYNg==", - "license": "MIT", - "dependencies": { - "jose": "^5.6.3", - "undici": "^6.19.5" - }, - "engines": { - "node": ">= 18.0.0" - } - }, - "node_modules/stytch/node_modules/jose": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", - "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/synckit": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.13.tgz", - "integrity": "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==", - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.3.6" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" - } - }, - "node_modules/table-layout": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", - "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", - "license": "MIT", - "dependencies": { - "array-back": "^4.0.1", - "deep-extend": "~0.6.0", - "typical": "^5.2.0", - "wordwrapjs": "^4.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/table-layout/node_modules/array-back": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", - "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/table-layout/node_modules/typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/thread-stream": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.2.0.tgz", - "integrity": "sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw==", - "license": "MIT", - "dependencies": { - "real-require": "^0.2.0" - } - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "license": "BSD-3-Clause" - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-command-line-args": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", - "integrity": "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==", - "license": "ISC", - "dependencies": { - "chalk": "^4.1.0", - "command-line-args": "^5.1.1", - "command-line-usage": "^6.1.0", - "string-format": "^2.0.0" - }, - "bin": { - "write-markdown": "dist/write-markdown.js" - } - }, - "node_modules/ts-essentials": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", - "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", - "license": "MIT", - "peerDependencies": { - "typescript": ">=3.7.0" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typechain": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", - "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", - "license": "MIT", - "dependencies": { - "@types/prettier": "^2.1.1", - "debug": "^4.3.1", - "fs-extra": "^7.0.0", - "glob": "7.1.7", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "mkdirp": "^1.0.4", - "prettier": "^2.3.1", - "ts-command-line-args": "^2.2.0", - "ts-essentials": "^7.0.1" - }, - "bin": { - "typechain": "dist/cli/cli.js" - }, - "peerDependencies": { - "typescript": ">=4.3.0" - } - }, - "node_modules/typechain/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "license": "Apache-2.0", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typestub-ipfs-only-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typestub-ipfs-only-hash/-/typestub-ipfs-only-hash-4.0.0.tgz", - "integrity": "sha512-HKLePX0XiPiyqoueSfvCLL9SIzvKBXjASaRoR0yk/gUbbK7cqejU6/tjhihwmzBCvWbx5aMQ2LYsYIpMK7Ikpg==", - "license": "BSD-2-Clause", - "dependencies": { - "ipfs-only-hash": "^4.0.0" - } - }, - "node_modules/typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/uint8arrays": { - "version": "2.1.10", - "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-2.1.10.tgz", - "integrity": "sha512-Q9/hhJa2836nQfEJSZTmr+pg9+cDJS9XEAp7N2Vg5MzL3bK/mkMVfjscRGYruP9jNda6MAdf4QD/y78gSzkp6A==", - "license": "MIT", - "dependencies": { - "multiformats": "^9.4.2" - } - }, - "node_modules/undici": { - "version": "6.28.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.1.tgz", - "integrity": "sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==", - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz", - "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/valid-url": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", - "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/varint": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", - "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", - "license": "MIT" - }, - "node_modules/viem": { - "version": "2.38.3", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.38.3.tgz", - "integrity": "sha512-By2TutLv07iNHHtWqHHzjGipevYsfGqT7KQbGEmqLco1qTJxKnvBbSviqiu6/v/9REV6Q/FpmIxf2Z7/l5AbcQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@noble/curves": "1.9.1", - "@noble/hashes": "1.8.0", - "@scure/bip32": "1.7.0", - "@scure/bip39": "1.6.0", - "abitype": "1.1.0", - "isows": "1.0.7", - "ox": "0.9.6", - "ws": "8.18.3" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/viem/node_modules/@noble/curves": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", - "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/wordwrapjs": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", - "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", - "license": "MIT", - "dependencies": { - "reduce-flatten": "^2.0.0", - "typical": "^5.2.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/wordwrapjs/node_modules/typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "license": "ISC" - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/zod": { - "version": "3.24.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.3.tgz", - "integrity": "sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-validation-error": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.4.0.tgz", - "integrity": "sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "zod": "^3.18.0" - } - }, - "node_modules/zustand": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.0.tgz", - "integrity": "sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==", - "license": "MIT", - "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@types/react": ">=18.0.0", - "immer": ">=9.0.6", - "react": ">=18.0.0", - "use-sync-external-store": ">=1.2.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - }, - "use-sync-external-store": { - "optional": true - } - } - } - } -} diff --git a/tool/threshold-spike/package.json b/tool/threshold-spike/package.json deleted file mode 100644 index c7589e4..0000000 --- a/tool/threshold-spike/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "@nosus-monad/threshold-spike", - "private": true, - "version": "0.1.0", - "type": "module", - "scripts": { - "check": "node conditions.test.mjs", - "dry-run": "node run.mjs", - "connect": "node run.mjs --connect", - "live": "node run.mjs --live" - }, - "dependencies": { - "@lit-protocol/auth": "8.2.3", - "@lit-protocol/lit-client": "8.3.1", - "@lit-protocol/networks": "8.4.1", - "viem": "2.38.3" - } -} diff --git a/tool/threshold-spike/run.mjs b/tool/threshold-spike/run.mjs deleted file mode 100644 index a723831..0000000 --- a/tool/threshold-spike/run.mjs +++ /dev/null @@ -1,231 +0,0 @@ -import { existsSync } from "node:fs"; -import { dirname, join } from "node:path"; -import { fileURLToPath } from "node:url"; - -import { - createPublicClient, - createWalletClient, - http, - keccak256, - parseAbi, - stringToHex, -} from "viem"; -import { privateKeyToAccount } from "viem/accounts"; - -import { buildCanDecryptConditions, LIT_ACC_CHAIN } from "./conditions.mjs"; - -const spikeRoot = dirname(fileURLToPath(import.meta.url)); -const live = process.argv.includes("--live") || process.env.THRESHOLD_SPIKE_RUN === "1"; -const connectOnly = process.argv.includes("--connect"); -const contractAddress = process.env.DROPS_CONTRACT_ADDRESS; -const dropId = process.env.SPIKE_DROP_ID ?? `0x${"ab".repeat(32)}`; -const senderKey = process.env.SENDER_PRIVATE_KEY; -const recipientKey = process.env.RECIPIENT_PRIVATE_KEY; -const strangerKey = process.env.STRANGER_PRIVATE_KEY; -const rpcUrl = process.env.MONAD_RPC_URL ?? "https://rpc.testnet.monad.xyz"; -const expirySeconds = BigInt(process.env.SPIKE_EXPIRY_SECONDS ?? "300"); -const checkExpiry = process.env.THRESHOLD_SPIKE_CHECK_EXPIRY === "1"; -const probe = "gate-t1-probe"; - -const monadTestnet = { - id: 10143, - name: "Monad Testnet", - nativeCurrency: { name: "MON", symbol: "MON", decimals: 18 }, - rpcUrls: { default: { http: [rpcUrl] } }, -}; - -const dropsAbi = parseAbi([ - "function seal(bytes32 id, bytes32 ciphertextDigest, address recipient, uint64 expiresAt)", - "function acknowledgeOpen(bytes32 id)", - "function canDecrypt(bytes32 id, address account) view returns (bool)", -]); - -const missing = []; -if (!contractAddress) missing.push("DROPS_CONTRACT_ADDRESS"); -if (!senderKey) missing.push("SENDER_PRIVATE_KEY"); -if (!recipientKey) missing.push("RECIPIENT_PRIVATE_KEY"); -if (!strangerKey) missing.push("STRANGER_PRIVATE_KEY"); - -const conditionContract = contractAddress ?? "0x0000000000000000000000000000000000000001"; -const conditions = buildCanDecryptConditions(conditionContract, dropId); - -console.log("NO SUS — Monad Experiment / Gate T1"); -console.log("Lit ACC chain:", LIT_ACC_CHAIN); -console.log("Selected SDK: @lit-protocol/lit-client 8.3.1, @lit-protocol/networks 8.4.1, @lit-protocol/auth 8.2.3 on naga-dev"); -console.log("Condition:"); -console.log(JSON.stringify(conditions, null, 2)); - -if (!live && !connectOnly) { - console.log("\nDry run only. This does not connect to Lit or Monad and does not enable the product gate."); - console.log("Use --connect for a Lit handshake. The full proof requires THRESHOLD_SPIKE_RUN=1, a deployed contract, and three controlled test wallets."); - process.exit(0); -} - -if (!existsSync(join(spikeRoot, "node_modules", "@lit-protocol", "lit-client"))) { - console.error("Lit client is not installed. Run npm install in tool/threshold-spike."); - process.exit(1); -} - -const [{ createLitClient }, networks, auth] = await Promise.all([ - import("@lit-protocol/lit-client"), - import("@lit-protocol/networks"), - import("@lit-protocol/auth"), -]); - -const network = networks.nagaDev ?? networks.nagaTest; -if (!network) { - console.error("The installed @lit-protocol/networks package does not export nagaDev or nagaTest."); - process.exit(1); -} - -const client = await createLitClient({ network }); -console.log("Connected to Lit naga-dev."); - -let encrypted; -try { - encrypted = await client.encrypt({ - dataToEncrypt: new TextEncoder().encode(probe), - evmContractConditions: conditions, - chain: LIT_ACC_CHAIN, - }); - console.log("Lit encrypt accepted the Monad canDecrypt condition."); - console.log("Returned fields:", Object.keys(encrypted)); -} catch (error) { - console.error("Lit encrypt against monadTestnet failed. Record this as Gate T1 evidence, not a product claim."); - console.error(error instanceof Error ? error.message : error); - await client.disconnect?.(); - process.exit(1); -} - -if (connectOnly && !live) { - await client.disconnect?.(); - console.log("Handshake and encrypt-only completed. Product gate remains spike-required."); - process.exit(0); -} - -if (missing.length) { - await client.disconnect?.(); - console.error(`Live proof refused. Missing ${missing.join(", ")}.`); - process.exit(1); -} - -const sender = privateKeyToAccount(senderKey); -const recipient = privateKeyToAccount(recipientKey); -const stranger = privateKeyToAccount(strangerKey); -const publicClient = createPublicClient({ chain: monadTestnet, transport: http(rpcUrl) }); -const senderClient = createWalletClient({ account: sender, chain: monadTestnet, transport: http(rpcUrl) }); -const recipientClient = createWalletClient({ account: recipient, chain: monadTestnet, transport: http(rpcUrl) }); - -const code = await publicClient.getCode({ address: contractAddress }); -if (!code || code === "0x") { - await client.disconnect?.(); - console.error("Live proof refused: DROPS_CONTRACT_ADDRESS has no deployed bytecode on the configured Monad RPC."); - process.exit(1); -} - -const authManager = auth.createAuthManager({ - storage: auth.storagePlugins.localStorageNode({ - appName: "nosus-monad-threshold-spike", - networkName: "naga-dev", - storagePath: join(spikeRoot, ".lit-auth"), - }), -}); - -async function authContextFor(account) { - return authManager.createEoaAuthContext({ - config: { account }, - litClient: client, - authConfig: { - domain: "localhost", - statement: "NO SUS Monad Gate T1 two-wallet test", - }, - }); -} - -async function decryptAs(account) { - return client.decrypt({ - data: encrypted, - evmContractConditions: conditions, - chain: LIT_ACC_CHAIN, - authContext: await authContextFor(account), - }); -} - -async function expectDenied(label, account) { - try { - await decryptAs(account); - } catch { - console.log(`PASS: ${label} was denied.`); - return; - } - throw new Error(`${label} unexpectedly decrypted the probe.`); -} - -async function waitForSuccess(hash) { - const receipt = await publicClient.waitForTransactionReceipt({ hash }); - if (receipt.status !== "success") throw new Error(`Transaction reverted: ${hash}`); - return receipt; -} - -async function waitUntilExpired(expiresAt) { - while ((await publicClient.getBlock()).timestamp < expiresAt) { - await new Promise((resolve) => setTimeout(resolve, 5_000)); - } -} - -try { - const existing = await publicClient.readContract({ - address: contractAddress, - abi: dropsAbi, - functionName: "canDecrypt", - args: [dropId, recipient.address], - }); - if (existing) throw new Error("SPIKE_DROP_ID already grants access. Use a fresh random 32-byte drop ID."); - - await expectDenied("recipient before acknowledgement", recipient); - - const ciphertextDigest = keccak256(stringToHex(encrypted.ciphertext)); - const now = (await publicClient.getBlock()).timestamp; - const sealHash = await senderClient.writeContract({ - address: contractAddress, - abi: dropsAbi, - functionName: "seal", - args: [dropId, ciphertextDigest, recipient.address, now + expirySeconds], - gas: 190_000n, - }); - await waitForSuccess(sealHash); - console.log("PASS: sender sealed the ciphertext digest."); - - const acknowledgeHash = await recipientClient.writeContract({ - address: contractAddress, - abi: dropsAbi, - functionName: "acknowledgeOpen", - args: [dropId], - gas: 100_000n, - }); - await waitForSuccess(acknowledgeHash); - console.log("PASS: named recipient acknowledged the drop."); - - const recipientResult = await decryptAs(recipient); - const recovered = new TextDecoder().decode(recipientResult.decryptedData); - if (recovered !== probe) throw new Error("Recipient decrypt returned unexpected bytes."); - console.log("PASS: acknowledged recipient decrypted the probe."); - - await expectDenied("stranger after acknowledgement", stranger); - - if (checkExpiry) { - console.log("Waiting for the configured expiry before the final denial check."); - await waitUntilExpired(now + expirySeconds); - await expectDenied("recipient after expiry", recipient); - } else { - console.log("Expiry denial is not included. Re-run with THRESHOLD_SPIKE_CHECK_EXPIRY=1 to record it."); - } - - console.log("Gate T1 live proof completed. Record transaction hashes and results in docs/STATUS.md before changing the product gate."); -} catch (error) { - console.error("Gate T1 live proof failed. Product gate remains spike-required."); - console.error(error instanceof Error ? error.message : error); - process.exitCode = 1; -} finally { - await client.disconnect?.(); -} diff --git a/web/AGENTS.md b/web/AGENTS.md deleted file mode 100644 index ae39b6f..0000000 --- a/web/AGENTS.md +++ /dev/null @@ -1,25 +0,0 @@ -# Web scope - -Read the repository-root `AGENTS.md` first. This folder owns the browser -experience only. - -- Keep plaintext and decryption keys out of logs, URLs, local fixtures, and - server routes. -- Do not fake a threshold unlock. The UI must retain its blocked state until - the Lit–Monad testnet gate in `src/lib/threshold.ts` is verified. -- Wallet writes use Monad testnet, an estimated explicit gas limit, and a - visible transaction link. Never add a payment flow. -- Use semantic controls, keyboard focus, strong contrast, and reduced-motion - alternatives. Every screen carries the experiment label. - -Would you like to finalize today's work? If yes, say whether to verify only, build a target, or deploy a named target. - - - -# This is NOT the Next.js you know - -This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices. - -This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean. - - diff --git a/web/README.md b/web/README.md deleted file mode 100644 index dd7801d..0000000 --- a/web/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# web - -The web experience for **NO SUS — Monad Experiment**. It is a testnet-only -recipient acknowledgement and threshold-decrypt experiment. - -## Entry points - -- `src/app/page.tsx` — sender console and live Receipt Wall -- `src/app/d/[id]/page.tsx` — recipient acknowledgement page -- `src/app/verify/[id]/page.tsx` — public receipt verifier -- `src/lib/monad.ts` — Monad chain and contract ABI -- `src/lib/threshold.ts` — the explicit Lit–Monad technical gate -- `src/lib/lit-conditions.ts` — `canDecrypt` access-control condition; unused for encrypt/decrypt until Gate T1 is verified -- `src/app/globals.css` — local design tokens and the flat NO SUS visual system - -## Public contract - -No screen may claim a note can decrypt until `threshold.ts` is changed from -`spike-required` to `verified` with the two-wallet test evidence recorded in -`../docs/STATUS.md`. The UI must show the experimental/test-data label. - -## Allowed dependencies - -Browser components may import `@/lib/*` and other components. They may not -read server-only environment variables or use the Supabase service-role key. -Only `src/lib/server/*` and route handlers may use it. - -## Visual system - -Read [`../docs/DESIGN_SYSTEM.md`](../docs/DESIGN_SYSTEM.md) before visual work. -Use the local Geist assets and semantic tokens in `globals.css`; do not copy -production NO SUS Burn components or reintroduce gradient/glow styling. - -## Checks - -Run `npm run check` for TypeScript. Run `npm run check` in `../tool/threshold-spike` for the -condition-shape test. Use `npm run dev` for a local preview. -Run `npm run build` only through the finalization gate in the root `AGENTS.md`. diff --git a/web/next-env.d.ts b/web/next-env.d.ts deleted file mode 100644 index a419cbe..0000000 --- a/web/next-env.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/// -/// -import "./.next/dev/types/routes.d.ts"; -import "./.next/dev/types/root-params.d.ts"; - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/web/next.config.ts b/web/next.config.ts deleted file mode 100644 index 2f6491c..0000000 --- a/web/next.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { NextConfig } from "next"; - -const nextConfig: NextConfig = { - reactStrictMode: true, -}; - -export default nextConfig; diff --git a/web/package-lock.json b/web/package-lock.json deleted file mode 100644 index 273ed07..0000000 --- a/web/package-lock.json +++ /dev/null @@ -1,1714 +0,0 @@ -{ - "name": "nosus-monad-web", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "nosus-monad-web", - "version": "0.1.0", - "dependencies": { - "@supabase/supabase-js": "2.116.0", - "next": "16.3.5", - "react": "19.3.0", - "react-dom": "19.3.0", - "viem": "2.56.5" - }, - "devDependencies": { - "@types/node": "25.3.5", - "@types/react": "19.2.14", - "@types/react-dom": "19.2.3", - "typescript": "7.0.2" - } - }, - "node_modules/@adraffy/ens-normalize": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", - "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", - "license": "MIT" - }, - "node_modules/@emnapi/runtime": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", - "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@img/colour": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", - "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz", - "integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.3.3" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz", - "integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.3.3" - } - }, - "node_modules/@img/sharp-freebsd-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz", - "integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==", - "license": "Apache-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "dependencies": { - "@img/sharp-wasm32": "0.35.4" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz", - "integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz", - "integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz", - "integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==", - "cpu": [ - "arm" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz", - "integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz", - "integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==", - "cpu": [ - "ppc64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz", - "integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==", - "cpu": [ - "riscv64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz", - "integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==", - "cpu": [ - "s390x" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz", - "integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz", - "integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz", - "integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz", - "integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz", - "integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz", - "integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==", - "cpu": [ - "ppc64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-riscv64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz", - "integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==", - "cpu": [ - "riscv64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz", - "integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==", - "cpu": [ - "s390x" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz", - "integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.3.3" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz", - "integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz", - "integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.3.3" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz", - "integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==", - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.11.3" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-webcontainers-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz", - "integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@img/sharp-wasm32": "0.35.4" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz", - "integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz", - "integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz", - "integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@next/env": { - "version": "16.3.5", - "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.5.tgz", - "integrity": "sha512-NWEXVDMqoEo0ktmU6u0sE2Vg0LOcsD7NnOTJNo3/fEaTfsg+F1bMIxuDmQbda4e3yTIQwVdUREF2yIuMOusKtg==", - "license": "MIT" - }, - "node_modules/@next/swc-darwin-arm64": { - "version": "16.3.5", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.3.5.tgz", - "integrity": "sha512-pMmGgETfKvElucLHtVaeiMRbp2zUbvKx7b1yGko0liBz3cw1mKSggWN/Rp/wPz8z+E1O82u3r4L1Co+ZS5hokQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "16.3.5", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.3.5.tgz", - "integrity": "sha512-76VaGYvf6HPa5/w12yLkE3dXTn9AfdEviI79oEL3aZoAmRLc9rWitjWqyjViVysK/ht/y9YKzFkBrUdi/wGkow==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "16.3.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.3.5.tgz", - "integrity": "sha512-zKDELJ5jSQMHeO/hmXUQsAzagX4bQD4OiMi3pQ5FbUj+yK506oLVHnKA2YXMlbg1EHHqJYtyePOgByIDXD1lqw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "16.3.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.3.5.tgz", - "integrity": "sha512-7Vql0pgzCoHagv6+FNOZoqmJqA52c6zeVbhtS/47qFozO1MSx4ms7x7GHiciY8R5CDsSMKMQjJEryoJLcsBIbA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "16.3.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.3.5.tgz", - "integrity": "sha512-NH/xzehyHEFWE2nlcZon7TB/0+H4shfWCi7S1zka815XCOhJDYZhoeJtOYy0dh0WVRWACVXSyGNFFytoMxUhRg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "16.3.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.3.5.tgz", - "integrity": "sha512-lV4+EhWMfS8jcC+EH2nn/Cm5cn6XsgbE07bU9tMH8fCo0tNAqhyzi1b5wQ/Tn6NGFTvKDY65w3ZH95EjwBRAnQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "16.3.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.3.5.tgz", - "integrity": "sha512-/wKzAREX2RF++MhicjDbg8tGn2AiBIM0+EFeTFKoUEUbW5D6amCJehd5Z5G1H5/gxNdgnwoXMcHz24H/c2tGkQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "16.3.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.3.5.tgz", - "integrity": "sha512-LNdCHzgLFc+UeqMS84LzXPaeBRKyqDN9OMyFAr1OrB0XrNw78IRrEVtZvvA7245W/HsaoeVOQX9jPjPk8jojwA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@noble/ciphers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", - "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/curves": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", - "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/base": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", - "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", - "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.9.0", - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", - "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@supabase/auth-js": { - "version": "2.116.0", - "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.116.0.tgz", - "integrity": "sha512-Cmosty12gyKGK9N3bQb+lMmuAFev5nmUzaR1AsmZHqKOAGzqX1VQzmp49CNPwOx/pw0H9Qqk4rs9yhwTlKpfDg==", - "license": "MIT", - "dependencies": { - "tslib": "2.8.1" - }, - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@supabase/functions-js": { - "version": "2.116.0", - "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.116.0.tgz", - "integrity": "sha512-E+VOc2QDcni/fySqkBFiZhnoB3SGydEdZgFI6/dEAGAHx6yEhB46TN9qb2wXs+E+RSzOBV0R6dasiSlw4xlZAA==", - "license": "MIT", - "dependencies": { - "tslib": "2.8.1" - }, - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@supabase/phoenix": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@supabase/phoenix/-/phoenix-0.4.5.tgz", - "integrity": "sha512-aAn9H9ovVyeApKy11OWOrrOGq8DV68yWeH4ud2lN9fzn4aO8Zb5GLL9m1pUg9nLqIcT+ZDfAcsZe0E/nqdv2lw==", - "license": "MIT" - }, - "node_modules/@supabase/postgrest-js": { - "version": "2.116.0", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.116.0.tgz", - "integrity": "sha512-kGpVZTDHxFTJS3tu+rU0iTAZ+4U0bcLVjxwCk8f3gRhjw3qdCZjTBlgYvc4kGH2XccmAzbkKwXL/mrNHMGSc+A==", - "license": "MIT", - "dependencies": { - "tslib": "2.8.1" - }, - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@supabase/realtime-js": { - "version": "2.116.0", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.116.0.tgz", - "integrity": "sha512-MHAnlXxi2s6yiJsZsQMfs2B3RFxeVfQWxerqYhIMqcCQV/FuY3LIeouPEkXw/ah7wUWMLYwempF9MOCUScyddg==", - "license": "MIT", - "dependencies": { - "@supabase/phoenix": "0.4.5", - "tslib": "2.8.1" - }, - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@supabase/storage-js": { - "version": "2.116.0", - "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.116.0.tgz", - "integrity": "sha512-6/3hR6vccBP6oGM5B6RfbwZcTCKmQOodd/ZWQdsw8yJsU5zO/a//oBL6yLnmgxcjnHSrelW8rsO7hL5DPybyUQ==", - "license": "MIT", - "dependencies": { - "iceberg-js": "^0.8.1", - "tslib": "2.8.1" - }, - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@supabase/supabase-js": { - "version": "2.116.0", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.116.0.tgz", - "integrity": "sha512-YyWmKXt2NspV9iO8FPnlswUFJIRnrLd3oTCb+3ZyYRuKZtBH0xCUDgnUqoyA0fGUxpM/UhfwDjYf/dht/9bp7g==", - "license": "MIT", - "dependencies": { - "@supabase/auth-js": "2.116.0", - "@supabase/functions-js": "2.116.0", - "@supabase/postgrest-js": "2.116.0", - "@supabase/realtime-js": "2.116.0", - "@supabase/storage-js": "2.116.0" - }, - "engines": { - "node": ">=22.0.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - } - } - }, - "node_modules/@swc/helpers": { - "version": "0.5.23", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", - "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@types/node": { - "version": "25.3.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.5.tgz", - "integrity": "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.18.0" - } - }, - "node_modules/@types/react": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", - "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "csstype": "^3.2.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" - } - }, - "node_modules/@typescript/typescript-aix-ppc64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", - "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-darwin-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", - "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-darwin-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", - "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-freebsd-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", - "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-freebsd-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", - "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-arm": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", - "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", - "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-loong64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", - "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-mips64el": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", - "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-ppc64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", - "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-riscv64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", - "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-s390x": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", - "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", - "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-netbsd-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", - "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-netbsd-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", - "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-openbsd-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", - "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-openbsd-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", - "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-sunos-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", - "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-win32-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", - "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-win32-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", - "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/abitype": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz", - "integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3.22.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.11.24", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.24.tgz", - "integrity": "sha512-hYrgxie335U08WqICoGqKRzV1HFXv6zdxwJE4ekCb80CM9a0SVVsN4QPwT67RraRo+9h8IATk6uxHJw7QSkdOg==", - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001810", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", - "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "license": "MIT" - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" - }, - "node_modules/iceberg-js": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz", - "integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==", - "license": "MIT", - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/isows": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", - "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "peerDependencies": { - "ws": "*" - } - }, - "node_modules/nanoid": { - "version": "3.3.19", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", - "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/next": { - "version": "16.3.5", - "resolved": "https://registry.npmjs.org/next/-/next-16.3.5.tgz", - "integrity": "sha512-MdtsTgzyfCPRLC6uJ1mN8ao7lyJ4BB0U6Inhnx3gta1UcCIdHK3yxLG0E8OWQteWD8/Q0qb8A5o7wJaL8M9y2w==", - "license": "MIT", - "dependencies": { - "@next/env": "16.3.5", - "@swc/helpers": "0.5.23", - "baseline-browser-mapping": "^2.9.19", - "caniuse-lite": "^1.0.30001579", - "postcss": "8.5.23", - "styled-jsx": "5.1.6" - }, - "bin": { - "next": "dist/bin/next" - }, - "engines": { - "node": ">=20.9.0" - }, - "optionalDependencies": { - "@next/swc-darwin-arm64": "16.3.5", - "@next/swc-darwin-x64": "16.3.5", - "@next/swc-linux-arm64-gnu": "16.3.5", - "@next/swc-linux-arm64-musl": "16.3.5", - "@next/swc-linux-x64-gnu": "16.3.5", - "@next/swc-linux-x64-musl": "16.3.5", - "@next/swc-win32-arm64-msvc": "16.3.5", - "@next/swc-win32-x64-msvc": "16.3.5", - "sharp": "^0.35.4" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.1.0", - "@playwright/test": "^1.51.1", - "babel-plugin-react-compiler": "*", - "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", - "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", - "sass": "^1.3.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "@playwright/test": { - "optional": true - }, - "babel-plugin-react-compiler": { - "optional": true - }, - "sass": { - "optional": true - } - } - }, - "node_modules/ox": { - "version": "0.14.44", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.14.44.tgz", - "integrity": "sha512-O54qXXHEk4ySamMSyBpI0AeBegS5frxU6+LA6Jb9Sf6kMOxcTNaxYmwZfpOu22DIQsdKfgQxHq8EsAGaoBQScA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.11.0", - "@noble/ciphers": "^1.3.0", - "@noble/curves": "1.9.1", - "@noble/hashes": "^1.8.0", - "@scure/bip32": "^1.7.0", - "@scure/bip39": "^1.6.0", - "abitype": "^1.2.3", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/ox/node_modules/@noble/curves": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", - "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/postcss": { - "version": "8.5.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", - "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.16", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/react": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz", - "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz", - "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==", - "license": "MIT", - "dependencies": { - "scheduler": "^0.28.0" - }, - "peerDependencies": { - "react": "^19.3.0" - } - }, - "node_modules/scheduler": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", - "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", - "license": "MIT" - }, - "node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz", - "integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@img/colour": "^1.1.0", - "detect-libc": "^2.1.2", - "semver": "^7.8.5" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.35.4", - "@img/sharp-darwin-x64": "0.35.4", - "@img/sharp-freebsd-wasm32": "0.35.4", - "@img/sharp-libvips-darwin-arm64": "1.3.3", - "@img/sharp-libvips-darwin-x64": "1.3.3", - "@img/sharp-libvips-linux-arm": "1.3.3", - "@img/sharp-libvips-linux-arm64": "1.3.3", - "@img/sharp-libvips-linux-ppc64": "1.3.3", - "@img/sharp-libvips-linux-riscv64": "1.3.3", - "@img/sharp-libvips-linux-s390x": "1.3.3", - "@img/sharp-libvips-linux-x64": "1.3.3", - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", - "@img/sharp-libvips-linuxmusl-x64": "1.3.3", - "@img/sharp-linux-arm": "0.35.4", - "@img/sharp-linux-arm64": "0.35.4", - "@img/sharp-linux-ppc64": "0.35.4", - "@img/sharp-linux-riscv64": "0.35.4", - "@img/sharp-linux-s390x": "0.35.4", - "@img/sharp-linux-x64": "0.35.4", - "@img/sharp-linuxmusl-arm64": "0.35.4", - "@img/sharp-linuxmusl-x64": "0.35.4", - "@img/sharp-webcontainers-wasm32": "0.35.4", - "@img/sharp-win32-arm64": "0.35.4", - "@img/sharp-win32-ia32": "0.35.4", - "@img/sharp-win32-x64": "0.35.4" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/styled-jsx": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", - "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", - "license": "MIT", - "dependencies": { - "client-only": "0.0.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/typescript": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", - "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", - "devOptional": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc" - }, - "engines": { - "node": ">=16.20.0" - }, - "optionalDependencies": { - "@typescript/typescript-aix-ppc64": "7.0.2", - "@typescript/typescript-darwin-arm64": "7.0.2", - "@typescript/typescript-darwin-x64": "7.0.2", - "@typescript/typescript-freebsd-arm64": "7.0.2", - "@typescript/typescript-freebsd-x64": "7.0.2", - "@typescript/typescript-linux-arm": "7.0.2", - "@typescript/typescript-linux-arm64": "7.0.2", - "@typescript/typescript-linux-loong64": "7.0.2", - "@typescript/typescript-linux-mips64el": "7.0.2", - "@typescript/typescript-linux-ppc64": "7.0.2", - "@typescript/typescript-linux-riscv64": "7.0.2", - "@typescript/typescript-linux-s390x": "7.0.2", - "@typescript/typescript-linux-x64": "7.0.2", - "@typescript/typescript-netbsd-arm64": "7.0.2", - "@typescript/typescript-netbsd-x64": "7.0.2", - "@typescript/typescript-openbsd-arm64": "7.0.2", - "@typescript/typescript-openbsd-x64": "7.0.2", - "@typescript/typescript-sunos-x64": "7.0.2", - "@typescript/typescript-win32-arm64": "7.0.2", - "@typescript/typescript-win32-x64": "7.0.2" - } - }, - "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", - "dev": true, - "license": "MIT" - }, - "node_modules/viem": { - "version": "2.56.5", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.56.5.tgz", - "integrity": "sha512-GuEf/oee0PHgy4D6JIA8u0rY1g+sM5nF+p7HyMHO3vjlHC5G/ljfrgnUOnrES9m5Ny/P3RwWCHjDuN2T6HUWzQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@noble/curves": "1.9.1", - "@noble/hashes": "1.8.0", - "@scure/bip32": "1.7.0", - "@scure/bip39": "1.6.0", - "abitype": "1.2.3", - "isows": "1.0.7", - "ox": "0.14.44", - "ws": "8.21.0" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/viem/node_modules/@noble/curves": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", - "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - } - } -} diff --git a/web/package.json b/web/package.json deleted file mode 100644 index 52360b4..0000000 --- a/web/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "nosus-monad-web", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "check": "tsc --noEmit", - "test:notes": "node --experimental-strip-types --test tests/private-notes.test.ts" - }, - "dependencies": { - "@supabase/supabase-js": "2.116.0", - "next": "16.3.5", - "react": "19.3.0", - "react-dom": "19.3.0", - "viem": "2.56.5" - }, - "devDependencies": { - "@types/node": "25.3.5", - "@types/react": "19.2.14", - "@types/react-dom": "19.2.3", - "typescript": "7.0.2" - } -} diff --git a/web/src/app/api/drops/[id]/route.ts b/web/src/app/api/drops/[id]/route.ts deleted file mode 100644 index e5003cb..0000000 --- a/web/src/app/api/drops/[id]/route.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { NextResponse } from "next/server"; - -import { isDropId } from "@/lib/drop-id"; -import { BackendNotConfiguredError, getExperimentAdmin } from "@/lib/server/supabase"; - -export const dynamic = "force-dynamic"; - -export async function GET(_request: Request, context: { params: Promise<{ id: string }> }) { - const { id } = await context.params; - if (!isDropId(id)) { - return NextResponse.json({ error: "Invalid drop identifier." }, { status: 400 }); - } - - try { - const { data, error } = await getExperimentAdmin() - .from("experiment_drops") - .select("id,sender_wallet,recipient_wallet,opener_wallet,ciphertext_digest,expires_at,sealed_tx_hash,opened_tx_hash,created_at,opened_at") - .eq("id", id.toLowerCase()) - .maybeSingle(); - if (error) throw error; - if (!data) return NextResponse.json({ error: "Drop not found." }, { status: 404 }); - - return NextResponse.json({ - id: data.id, - senderWallet: data.sender_wallet, - recipientWallet: data.recipient_wallet, - openerWallet: data.opener_wallet, - ciphertextDigest: data.ciphertext_digest, - expiresAt: data.expires_at, - sealedTxHash: data.sealed_tx_hash, - openedTxHash: data.opened_tx_hash, - createdAt: data.created_at, - openedAt: data.opened_at, - }); - } catch (error) { - const message = - error instanceof BackendNotConfiguredError - ? error.message - : "The verifier backend is temporarily unavailable."; - return NextResponse.json({ error: message }, { status: 503 }); - } -} diff --git a/web/src/app/api/wall/route.ts b/web/src/app/api/wall/route.ts deleted file mode 100644 index a199631..0000000 --- a/web/src/app/api/wall/route.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { NextResponse } from "next/server"; - -import { BackendNotConfiguredError, getExperimentAdmin } from "@/lib/server/supabase"; - -export const dynamic = "force-dynamic"; - -export async function GET() { - try { - const { data, error } = await getExperimentAdmin() - .from("experiment_drops") - .select("id,sender_wallet,recipient_wallet,opener_wallet,sealed_tx_hash,opened_tx_hash,created_at,opened_at") - .order("created_at", { ascending: false }) - .limit(40); - - if (error) throw error; - return NextResponse.json({ - items: (data ?? []).map((drop) => ({ - id: drop.id, - senderWallet: drop.sender_wallet, - recipientWallet: drop.recipient_wallet, - openerWallet: drop.opener_wallet, - sealedTxHash: drop.sealed_tx_hash, - openedTxHash: drop.opened_tx_hash, - createdAt: drop.created_at, - openedAt: drop.opened_at, - })), - }); - } catch (error) { - const message = - error instanceof BackendNotConfiguredError - ? error.message - : "The Receipt Wall is temporarily unavailable."; - return NextResponse.json({ error: message }, { status: 503 }); - } -} diff --git a/web/src/app/d/[id]/page.tsx b/web/src/app/d/[id]/page.tsx deleted file mode 100644 index e901eee..0000000 --- a/web/src/app/d/[id]/page.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { RecipientConsole } from "@/components/recipient-console"; - -export default async function RecipientPage({ params }: { params: Promise<{ id: string }> }) { - const { id } = await params; - return ; -} diff --git a/web/src/app/error.tsx b/web/src/app/error.tsx deleted file mode 100644 index 3b2da57..0000000 --- a/web/src/app/error.tsx +++ /dev/null @@ -1,17 +0,0 @@ -"use client"; - -import { useEffect } from "react"; - -export default function GlobalError({ reset }: { error: Error; reset: () => void }) { - useEffect(() => { - // Error contents may include wallet/provider data, so they are deliberately not logged. - }, []); - - return ( -
-

SAFE FAILURE

-

The experiment paused before handling any note.

- -
- ); -} diff --git a/web/src/app/fonts/fonts.css b/web/src/app/fonts/fonts.css deleted file mode 100644 index f75451a..0000000 --- a/web/src/app/fonts/fonts.css +++ /dev/null @@ -1,11 +0,0 @@ -@font-face{font-family:"Geist";font-style:normal;font-weight:100 900;font-display:swap;src:url(./geist-fef07dbb0973bf53.woff2)format("woff2");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F} -@font-face{font-family:"Geist";font-style:normal;font-weight:100 900;font-display:swap;src:url(./geist-8a480f0b521d4e75.woff2)format("woff2");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116} -@font-face{font-family:"Geist";font-style:normal;font-weight:100 900;font-display:swap;src:url(./geist-53b9e256198e5412.woff2)format("woff2");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB} -@font-face{font-family:"Geist";font-style:normal;font-weight:100 900;font-display:swap;src:url(./geist-7178b3e590c64307.woff2)format("woff2");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF} -@font-face{font-family:"Geist";font-style:normal;font-weight:100 900;font-display:swap;src:url(./geist-caa3a2e1cccd8315.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD} -@font-face{font-family:"Geist Mono";font-style:normal;font-weight:100 900;font-display:swap;src:url(./geist-mono-5ce348bf30bf5439.woff2)format("woff2");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F} -@font-face{font-family:"Geist Mono";font-style:normal;font-weight:100 900;font-display:swap;src:url(./geist-mono-4fa387ec64143e14.woff2)format("woff2");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116} -@font-face{font-family:"Geist Mono";font-style:normal;font-weight:100 900;font-display:swap;src:url(./geist-mono-6306c77e7c8268e4.woff2)format("woff2");unicode-range:U+2000-2001,U+2004-2008,U+200A,U+23B8-23BD,U+2500-259F} -@font-face{font-family:"Geist Mono";font-style:normal;font-weight:100 900;font-display:swap;src:url(./geist-mono-7d817b4c03b0c5f1.woff2)format("woff2");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB} -@font-face{font-family:"Geist Mono";font-style:normal;font-weight:100 900;font-display:swap;src:url(./geist-mono-bbc41e54d2fcbd21.woff2)format("woff2");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF} -@font-face{font-family:"Geist Mono";font-style:normal;font-weight:100 900;font-display:swap;src:url(./geist-mono-797e433ab948586e.woff2)format("woff2");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD} diff --git a/web/src/app/fonts/geist-53b9e256198e5412.woff2 b/web/src/app/fonts/geist-53b9e256198e5412.woff2 deleted file mode 100644 index 0bcca1b..0000000 Binary files a/web/src/app/fonts/geist-53b9e256198e5412.woff2 and /dev/null differ diff --git a/web/src/app/fonts/geist-7178b3e590c64307.woff2 b/web/src/app/fonts/geist-7178b3e590c64307.woff2 deleted file mode 100644 index 8a1d3df..0000000 Binary files a/web/src/app/fonts/geist-7178b3e590c64307.woff2 and /dev/null differ diff --git a/web/src/app/fonts/geist-8a480f0b521d4e75.woff2 b/web/src/app/fonts/geist-8a480f0b521d4e75.woff2 deleted file mode 100644 index f385e23..0000000 Binary files a/web/src/app/fonts/geist-8a480f0b521d4e75.woff2 and /dev/null differ diff --git a/web/src/app/fonts/geist-caa3a2e1cccd8315.woff2 b/web/src/app/fonts/geist-caa3a2e1cccd8315.woff2 deleted file mode 100644 index 8f01e76..0000000 Binary files a/web/src/app/fonts/geist-caa3a2e1cccd8315.woff2 and /dev/null differ diff --git a/web/src/app/fonts/geist-fef07dbb0973bf53.woff2 b/web/src/app/fonts/geist-fef07dbb0973bf53.woff2 deleted file mode 100644 index 7ab581f..0000000 Binary files a/web/src/app/fonts/geist-fef07dbb0973bf53.woff2 and /dev/null differ diff --git a/web/src/app/fonts/geist-mono-4fa387ec64143e14.woff2 b/web/src/app/fonts/geist-mono-4fa387ec64143e14.woff2 deleted file mode 100644 index 4fc15d1..0000000 Binary files a/web/src/app/fonts/geist-mono-4fa387ec64143e14.woff2 and /dev/null differ diff --git a/web/src/app/fonts/geist-mono-5ce348bf30bf5439.woff2 b/web/src/app/fonts/geist-mono-5ce348bf30bf5439.woff2 deleted file mode 100644 index c7700cd..0000000 Binary files a/web/src/app/fonts/geist-mono-5ce348bf30bf5439.woff2 and /dev/null differ diff --git a/web/src/app/fonts/geist-mono-6306c77e7c8268e4.woff2 b/web/src/app/fonts/geist-mono-6306c77e7c8268e4.woff2 deleted file mode 100644 index 29dd20f..0000000 Binary files a/web/src/app/fonts/geist-mono-6306c77e7c8268e4.woff2 and /dev/null differ diff --git a/web/src/app/fonts/geist-mono-797e433ab948586e.woff2 b/web/src/app/fonts/geist-mono-797e433ab948586e.woff2 deleted file mode 100644 index cf24126..0000000 Binary files a/web/src/app/fonts/geist-mono-797e433ab948586e.woff2 and /dev/null differ diff --git a/web/src/app/fonts/geist-mono-7d817b4c03b0c5f1.woff2 b/web/src/app/fonts/geist-mono-7d817b4c03b0c5f1.woff2 deleted file mode 100644 index 873f580..0000000 Binary files a/web/src/app/fonts/geist-mono-7d817b4c03b0c5f1.woff2 and /dev/null differ diff --git a/web/src/app/fonts/geist-mono-bbc41e54d2fcbd21.woff2 b/web/src/app/fonts/geist-mono-bbc41e54d2fcbd21.woff2 deleted file mode 100644 index 751a04d..0000000 Binary files a/web/src/app/fonts/geist-mono-bbc41e54d2fcbd21.woff2 and /dev/null differ diff --git a/web/src/app/globals.css b/web/src/app/globals.css deleted file mode 100644 index b0251f9..0000000 --- a/web/src/app/globals.css +++ /dev/null @@ -1,191 +0,0 @@ -@import "./fonts/fonts.css"; - -:root { - /* Raw palette — components use the semantic aliases below. */ - --black: #080808; - --gray-dark: #141414; - --gray: #1e1e1e; - --gray-light: #888888; - --white: #ffffff; - --danger: #ff8a7a; - --page: var(--black); - --surface: var(--gray-dark); - --surface-raised: var(--gray); - --text: var(--white); - --text-muted: var(--gray-light); - --line: rgb(255 255 255 / 18%); - --line-strong: rgb(255 255 255 / 48%); - --focus: var(--white); - --button-primary-bg: var(--white); - --button-primary-text: var(--black); - --radius: 2px; - --sans: "Geist", Arial, sans-serif; - --mono: "Geist Mono", "SFMono-Regular", Consolas, monospace; -} - -* { box-sizing: border-box; } -html { background: var(--page); } -body { margin: 0; background: var(--page); color: var(--text); font-family: var(--sans); font-size: 15px; line-height: 1.5; } -button, input, textarea { font: inherit; } -button { cursor: pointer; } -a { color: inherit; } -button:focus-visible, a:focus-visible, input:focus-visible, textarea:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; } -.app-shell { min-height: 100vh; overflow: hidden; } -.page-shell { min-height: 100vh; } - -.topbar { align-items: center; border-bottom: 1px solid var(--line); display: flex; height: 64px; justify-content: space-between; padding: 0 clamp(18px, 4vw, 68px); } -.wordmark { align-items: center; display: inline-flex; font-family: var(--mono); font-size: 12px; font-weight: 600; gap: 9px; letter-spacing: .08em; text-decoration: none; } -.wordmark-mark { align-items: center; background: var(--white); color: var(--black); display: inline-flex; font-family: var(--sans); font-size: 12px; font-weight: 800; height: 20px; justify-content: center; width: 20px; } -.topbar-actions, .hero-actions, .inline-actions, .footer-links { align-items: center; display: flex; flex-wrap: wrap; gap: 10px; } -.text-link { color: var(--text-muted); font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-decoration: none; text-transform: uppercase; } -.text-link:hover { color: var(--text); } -.wallet-button, .primary-button, .secondary-button, .icon-button { border: 1px solid var(--line-strong); border-radius: var(--radius); font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: .06em; min-height: 38px; padding: 0 14px; text-transform: uppercase; transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease; } -.wallet-button, .secondary-button, .icon-button { background: transparent; color: var(--white); } -.wallet-button:hover, .secondary-button:hover, .icon-button:hover { background: var(--white); border-color: var(--white); color: var(--black); } -.primary-button { background: var(--button-primary-bg); border-color: var(--white); color: var(--button-primary-text); } -.primary-button:hover { background: var(--gray-light); border-color: var(--gray-light); } -.primary-button:disabled, .secondary-button:disabled, .wallet-button:disabled { cursor: not-allowed; opacity: .42; } - -.page-grid { margin: 0 auto; max-width: 1440px; padding: clamp(28px, 5vw, 76px) clamp(18px, 4vw, 68px) 56px; } -.eyebrow, .panel-kicker, .field-label, .step-index, .metric-label, .footer-label, .orb-status { color: var(--text-muted); font-family: var(--mono); font-size: 10px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; } -.experiment-badge { align-items: center; border: 1px solid var(--line); color: var(--text-muted); display: inline-flex; font-family: var(--mono); font-size: 10px; gap: 8px; letter-spacing: .09em; padding: 7px 9px; text-transform: uppercase; } -.experiment-badge::before { background: var(--white); content: ""; display: block; height: 5px; width: 5px; } - -.hero { border-bottom: 1px solid var(--line); display: grid; gap: clamp(34px, 6vw, 92px); grid-template-columns: minmax(0, 1.08fr) minmax(290px, .92fr); padding-bottom: clamp(42px, 7vw, 92px); } -.hero-copy { align-self: center; max-width: 730px; } -.hero h1, .section-heading h2, .page-title { font-size: clamp(44px, 6.3vw, 96px); font-weight: 500; letter-spacing: -.065em; line-height: .93; margin: 18px 0 25px; } -.hero-lede, .section-lede, .page-lede { color: var(--text-muted); font-size: clamp(16px, 1.55vw, 20px); line-height: 1.48; margin: 0; max-width: 570px; } -.hero-actions { margin-top: 31px; } -.trust-line, .gate-note { border-left: 1px solid var(--white); color: var(--text-muted); font-family: var(--mono); font-size: 11px; line-height: 1.65; margin: 31px 0 0; max-width: 570px; padding-left: 13px; } -.honesty-line { border-left: 1px solid var(--white); color: var(--text-muted); font-family: var(--mono); font-size: 11px; line-height: 1.65; margin: 31px 0 0; max-width: 570px; padding-left: 13px; } -.hero-visual { align-items: center; display: flex; justify-content: center; min-height: 400px; } -.hero-orb-wrap { align-items: center; background: var(--surface); border: 1px solid var(--line); display: flex; height: min(34vw, 470px); justify-content: center; min-height: 340px; overflow: hidden; position: relative; width: min(34vw, 470px); } -.hero-grid { border-bottom: 1px solid var(--line); display: grid; gap: clamp(34px, 6vw, 92px); grid-template-columns: minmax(0, 1.08fr) minmax(290px, .92fr); padding: clamp(28px, 5vw, 76px) clamp(18px, 4vw, 68px) clamp(42px, 7vw, 92px); } -.hero-orb-wrap::before, .hero-orb-wrap::after { background: var(--line); content: ""; position: absolute; } -.hero-orb-wrap::before { height: 1px; inset: 50% 0 auto; } -.hero-orb-wrap::after { inset: 0 auto 0 50%; width: 1px; } -.orb-caption { bottom: 15px; color: var(--text-muted); display: flex; font-family: var(--mono); font-size: 10px; gap: 12px; left: 15px; letter-spacing: .08em; position: absolute; text-transform: uppercase; } - -.lock-orb { align-items: center; border: 1px solid var(--line-strong); border-radius: 50%; display: flex; height: 238px; justify-content: center; position: relative; width: 238px; z-index: 1; } -.orb-axis { background: var(--line); position: absolute; } -.orb-axis-horizontal { height: 1px; left: -31px; right: -31px; } -.orb-axis-vertical { bottom: -31px; top: -31px; width: 1px; } -.orb-ring { border: 1px dashed var(--line-strong); border-radius: 50%; inset: 17px; position: absolute; } -.lock-shackle { border: 12px solid var(--white); border-bottom: 0; border-radius: 32px 32px 0 0; height: 64px; left: 50%; position: absolute; top: 58px; transform: translateX(-50%); width: 86px; } -.lock-body { align-items: center; background: var(--white); display: flex; height: 82px; justify-content: center; margin-top: 34px; position: relative; width: 112px; } -.lock-keyhole { background: var(--black); border-radius: 50%; display: block; height: 17px; position: relative; width: 17px; } -.lock-keyhole::after { background: var(--black); content: ""; height: 25px; left: 5px; position: absolute; top: 10px; width: 7px; } -.lock-orb.unlocked .lock-shackle { transform: translateX(-50%) rotate(-23deg) translate(12px, -8px); transform-origin: bottom right; } -.lock-orb.unlocked .lock-body { background: var(--gray-light); } -.orb-status { bottom: 23px; left: 50%; position: absolute; transform: translateX(-50%); } - -.signal-strip { border-bottom: 1px solid var(--line); display: grid; grid-template-columns: repeat(3, 1fr); } -.signal-strip span { border-right: 1px solid var(--line); font-family: var(--mono); font-size: 11px; padding: 16px 18px; } -.signal-strip span:last-child { border-right: 0; } -.signal-strip b { color: var(--text-muted); font-weight: 500; margin-right: 6px; } -.signal-item { border-right: 1px solid var(--line); padding: 16px 18px; } -.signal-item:last-child { border-right: 0; } -.signal-item strong { display: block; font-family: var(--mono); font-size: 11px; font-weight: 500; margin-top: 5px; } -.section { border-bottom: 1px solid var(--line); padding: clamp(54px, 8vw, 104px) 0; } -.section-heading { display: grid; gap: 25px; grid-template-columns: minmax(0, 1fr) minmax(260px, .65fr); margin-bottom: 32px; } -.section-heading h2 { font-size: clamp(34px, 4.8vw, 68px); margin: 0; } -.console-grid, .two-column-grid { display: grid; gap: 16px; grid-template-columns: repeat(2, minmax(0, 1fr)); } -.workspace-grid { display: grid; gap: 16px; grid-template-columns: minmax(0, 1.05fr) minmax(300px, .95fr); padding: clamp(54px, 8vw, 104px) clamp(18px, 4vw, 68px); } -.console-card, .receipt-wall, .drop-panel, .verifier-card { background: var(--surface); border: 1px solid var(--line); padding: clamp(20px, 3vw, 32px); } -.glass-panel { background: var(--surface); border: 1px solid var(--line); padding: clamp(20px, 3vw, 32px); } -.console-card-wide { grid-column: span 2; } -.panel-header, .card-heading, .receipt-row, .metric-row, .field-row { align-items: center; display: flex; justify-content: space-between; } -.panel-header { border-bottom: 1px solid var(--line); margin-bottom: 25px; padding-bottom: 14px; } -.panel-title, .card-title { font-size: 20px; font-weight: 500; letter-spacing: -.03em; margin: 0; } -.panel-heading, .wall-topline { align-items: flex-start; border-bottom: 1px solid var(--line); display: flex; gap: 18px; justify-content: space-between; margin-bottom: 22px; padding-bottom: 15px; } -.panel-heading h2, .wall-topline h2 { font-size: clamp(25px, 3vw, 39px); font-weight: 500; letter-spacing: -.05em; line-height: 1; margin: 7px 0 0; } -.panel-copy { color: var(--text-muted); font-size: 14px; line-height: 1.58; margin: 0 0 24px; } -.step-list, .form-stack, .metric-list { display: grid; } -.form-stack { gap: 18px; } -.step-item { border-top: 1px solid var(--line); display: grid; gap: 16px; grid-template-columns: 34px 1fr auto; padding: 17px 0; } -.step-item:last-child, .metric-row:last-child, .field-row:last-child, .receipt-row:last-child { border-bottom: 1px solid var(--line); } -.step-title { font-size: 14px; font-weight: 500; margin: 0; } -.step-detail, .help-text, .muted-copy { color: var(--text-muted); font-size: 12px; line-height: 1.6; margin: 4px 0 0; } -.status-chip { border: 1px solid var(--line-strong); color: var(--text-muted); font-family: var(--mono); font-size: 9px; letter-spacing: .1em; padding: 5px 7px; text-transform: uppercase; white-space: nowrap; } -.status-chip.ready, .status-chip.opened { background: var(--white); border-color: var(--white); color: var(--black); } -.status-chip.blocked, .status-chip.expired, .status-chip.error { border-color: var(--danger); color: var(--danger); } -.field-label { display: block; margin-bottom: 8px; } -.seal-form label { display: block; font-family: var(--mono); font-size: 10px; font-weight: 600; letter-spacing: .1em; margin-bottom: 8px; text-transform: uppercase; } -.seal-form textarea { background: var(--black); border: 1px solid var(--line-strong); border-radius: var(--radius); color: var(--white); display: block; min-height: 128px; padding: 12px; resize: vertical; width: 100%; } -.seal-form textarea::placeholder { color: var(--text-muted); } -.form-footer { align-items: center; color: var(--text-muted); display: flex; font-family: var(--mono); font-size: 11px; justify-content: space-between; margin-top: 12px; } -.text-input, .text-area { background: var(--black); border: 1px solid var(--line-strong); border-radius: var(--radius); color: var(--text); min-height: 42px; padding: 11px 12px; width: 100%; } -.text-area { min-height: 125px; resize: vertical; } -.text-input::placeholder, .text-area::placeholder { color: var(--text-muted); } -.gate-note { margin: 18px 0 0; } -.receipt-wall { min-height: 384px; } -.wall-status { color: var(--text-muted); font-family: var(--mono); font-size: 12px; line-height: 1.6; margin: 0; } -.receipt-list { display: grid; margin-top: 18px; } -.receipt-list { list-style: none; padding: 0; } -.receipt-list li { align-items: center; border-top: 1px solid var(--line); display: grid; font-family: var(--mono); font-size: 11px; gap: 10px; grid-template-columns: auto 1fr auto; padding: 14px 0; } -.receipt-state { border: 1px solid var(--line-strong); font-size: 9px; letter-spacing: .09em; padding: 4px 6px; } -.receipt-state.opened { background: var(--white); border-color: var(--white); color: var(--black); } -.empty-wall { align-items: center; border: 1px dashed var(--line-strong); color: var(--text-muted); display: flex; flex-direction: column; font-family: var(--mono); font-size: 12px; justify-content: center; margin-top: 20px; min-height: 206px; padding: 26px; text-align: center; } -.empty-wall p { line-height: 1.6; max-width: 290px; } -.empty-glyph { color: var(--white); font-size: 30px; } -.receipt-row { border-top: 1px solid var(--line); gap: 14px; padding: 15px 0; } -.receipt-id, .hash-value, .mono-value { font-family: var(--mono); font-size: 11px; overflow-wrap: anywhere; } -.receipt-meta { color: var(--text-muted); font-family: var(--mono); font-size: 10px; margin-top: 3px; } -.live-indicator { align-items: center; color: var(--text-muted); display: inline-flex; font-family: var(--mono); font-size: 10px; gap: 7px; letter-spacing: .08em; text-transform: uppercase; } -.live-indicator i { animation: signal 1.4s steps(2, end) infinite; background: var(--white); display: inline-block; height: 6px; width: 6px; } -.page-header { border-bottom: 1px solid var(--line); margin-bottom: 32px; padding-bottom: 32px; } -.page-title { font-size: clamp(40px, 5.5vw, 78px); margin-bottom: 18px; } -.metric-row, .field-row { border-top: 1px solid var(--line); gap: 20px; padding: 14px 0; } -.metric-value { font-family: var(--mono); font-size: 12px; text-align: right; } -.empty-state { border: 1px dashed var(--line-strong); color: var(--text-muted); font-family: var(--mono); font-size: 12px; padding: 28px; text-align: center; } -.site-footer { color: var(--text-muted); display: flex; font-family: var(--mono); font-size: 10px; justify-content: space-between; letter-spacing: .06em; padding: 24px clamp(18px, 4vw, 68px); text-transform: uppercase; } -.text-button { color: var(--white); font-family: var(--mono); font-size: 11px; letter-spacing: .04em; text-underline-offset: 4px; } -.text-button:hover { color: var(--text-muted); } -.muted { color: var(--text-muted); } -.inline-error { border-left: 1px solid var(--danger); color: var(--danger); font-family: var(--mono); font-size: 11px; line-height: 1.6; margin: 16px 0 0; padding-left: 12px; } -.small-note { color: var(--text-muted); font-family: var(--mono); font-size: 11px; line-height: 1.6; margin: 16px 0 0; } -.wallet-control { align-items: end; display: flex; flex-direction: column; gap: 5px; } -.wallet-pulse { color: var(--danger); font-family: var(--mono); font-size: 10px; } -.recipient-page, .verifier-page, .simple-page { margin: 0 auto; max-width: 1240px; min-height: 100vh; padding: clamp(28px, 5vw, 76px) clamp(18px, 4vw, 68px); } -.recipient-grid { align-items: center; border-bottom: 1px solid var(--line); display: grid; gap: clamp(30px, 8vw, 120px); grid-template-columns: minmax(0, 1fr) minmax(280px, .7fr); padding: 28px 0 58px; } -.recipient-copy h1, .verifier-page h1, .simple-page h1 { font-size: clamp(40px, 5.5vw, 78px); font-weight: 500; letter-spacing: -.06em; line-height: .94; margin: 14px 0 22px; } -.recipient-copy > p:not(.eyebrow):not(.inline-error):not(.small-note), .verifier-lede { color: var(--text-muted); font-size: 17px; line-height: 1.55; max-width: 560px; } -.recipient-orb { align-items: center; background: var(--surface); border: 1px solid var(--line); display: flex; justify-content: center; min-height: 360px; } -.receipt-facts { border-top: 1px solid var(--line); margin: 27px 0; } -.receipt-facts div { border-bottom: 1px solid var(--line); display: grid; gap: 15px; grid-template-columns: 105px 1fr; padding: 12px 0; } -.receipt-facts dt, .verifier-grid dt { color: var(--text-muted); font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; } -.receipt-facts dd, .verifier-grid dd { font-family: var(--mono); font-size: 11px; margin: 0; overflow-wrap: anywhere; } -.blocked-decrypt { margin-top: 18px; } -.blocked-decrypt h2 { font-size: 26px; font-weight: 500; letter-spacing: -.04em; margin: 8px 0; } -.blocked-decrypt p:not(.eyebrow) { color: var(--text-muted); max-width: 720px; } -.receipt-card { background: var(--surface); border: 1px solid var(--line); margin-top: 30px; padding: clamp(20px, 3vw, 32px); } -.receipt-card-header { align-items: center; border-bottom: 1px solid var(--line); display: flex; gap: 16px; justify-content: space-between; padding-bottom: 14px; } -.receipt-card-header code { font-family: var(--mono); font-size: 10px; overflow-wrap: anywhere; text-align: right; } -.verifier-grid { display: grid; gap: 0 28px; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 18px 0; } -.verifier-grid div { border-top: 1px solid var(--line); padding: 13px 0; } -.verifier-grid dd { margin-top: 6px; } -.receipt-links { display: flex; flex-wrap: wrap; gap: 18px; } -.loading-line { color: var(--text-muted); font-family: var(--mono); font-size: 12px; } -@keyframes signal { 50% { opacity: .24; } } - -@media (max-width: 800px) { - .topbar { height: auto; min-height: 64px; padding-bottom: 12px; padding-top: 12px; } - .hero, .hero-grid, .section-heading, .console-grid, .two-column-grid, .workspace-grid, .recipient-grid { grid-template-columns: 1fr; } - .hero { padding-bottom: 48px; } - .hero-visual { min-height: 300px; order: -1; } - .hero-orb-wrap { height: min(78vw, 400px); min-height: 290px; width: min(78vw, 400px); } - .console-card-wide { grid-column: auto; } - .signal-strip { grid-template-columns: 1fr; } - .signal-item, .signal-strip span { border-bottom: 1px solid var(--line); border-right: 0; } - .signal-item:last-child, .signal-strip span:last-child { border-bottom: 0; } - .step-item { grid-template-columns: 28px 1fr; } - .step-item .status-chip { grid-column: 2; justify-self: start; } - .site-footer { flex-direction: column; gap: 12px; } - .verifier-grid { grid-template-columns: 1fr; } - .receipt-list li { align-items: start; grid-template-columns: auto 1fr; } - .receipt-list li > span:last-child { grid-column: 2; } -} - -@media (prefers-reduced-motion: reduce) { - *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: .01ms !important; } -} diff --git a/web/src/app/layout.tsx b/web/src/app/layout.tsx deleted file mode 100644 index a50e240..0000000 --- a/web/src/app/layout.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import type { Metadata } from "next"; - -import "./globals.css"; - -export const metadata: Metadata = { - title: "NO SUS — Monad Experiment", - description: "Private notes with wallet acceptance receipts. An experimental Monad Testnet experience.", -}; - -export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) { - return ( - - {children} - - ); -} diff --git a/web/src/app/not-found.tsx b/web/src/app/not-found.tsx deleted file mode 100644 index 31ffdc5..0000000 --- a/web/src/app/not-found.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import Link from "next/link"; - -import { ExperimentBadge } from "@/components/experiment-badge"; - -export default function NotFound() { - return ( -
- -

404 / DROP NOT FOUND

-

This link does not identify a recorded experiment drop.

- Back to the experiment -
- ); -} diff --git a/web/src/app/operator/page.tsx b/web/src/app/operator/page.tsx deleted file mode 100644 index d6869b2..0000000 --- a/web/src/app/operator/page.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import Link from "next/link"; -import { HomeDashboard } from "@/components/home-dashboard"; - -export default function OperatorPage() { - return <>
Developer setup · Back to private notes
; -} diff --git a/web/src/app/page.tsx b/web/src/app/page.tsx deleted file mode 100644 index 923f663..0000000 --- a/web/src/app/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { ConsumerHome } from "@/features/private-notes/consumer-home"; - -export default function HomePage() { - return ; -} diff --git a/web/src/app/preview/page.tsx b/web/src/app/preview/page.tsx deleted file mode 100644 index 5feaa66..0000000 --- a/web/src/app/preview/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import { SampleJourney } from "@/features/private-notes/sample-journey"; - -export default function PreviewPage() { return ; } diff --git a/web/src/app/verify/[id]/page.tsx b/web/src/app/verify/[id]/page.tsx deleted file mode 100644 index 66a1c6d..0000000 --- a/web/src/app/verify/[id]/page.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { ReceiptVerifier } from "@/components/receipt-verifier"; - -export default async function VerifyPage({ params }: { params: Promise<{ id: string }> }) { - const { id } = await params; - return ; -} diff --git a/web/src/components/experiment-badge.tsx b/web/src/components/experiment-badge.tsx deleted file mode 100644 index 962f91c..0000000 --- a/web/src/components/experiment-badge.tsx +++ /dev/null @@ -1,12 +0,0 @@ -type ExperimentBadgeProps = { - compact?: boolean; -}; - -export function ExperimentBadge({ compact = false }: ExperimentBadgeProps) { - return ( -

- - Experimental · Monad Testnet · Personal test data only -

- ); -} diff --git a/web/src/components/home-dashboard.tsx b/web/src/components/home-dashboard.tsx deleted file mode 100644 index 9d16e54..0000000 --- a/web/src/components/home-dashboard.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import Link from "next/link"; - -import { ExperimentBadge } from "@/components/experiment-badge"; -import { LiveReceiptWall } from "@/components/live-receipt-wall"; -import { LockOrb } from "@/components/lock-orb"; -import { SealConsole } from "@/components/seal-console"; -import { WalletControl } from "@/components/wallet-control"; - -export function HomeDashboard() { - return ( -
- - -
-
- -

One acknowledgement. One chance.

-

The lock only listens after the chain does.

-

- A recipient wallet can request a one-time decrypt only after its acknowledgement is - recorded on Monad Testnet. -

-
- Explore the flow - View receipt verifier -
-

- An on-chain receipt records a wallet action — not human comprehension, identity, - screenshot prevention, or legal proof. -

-
-
- -
MONAD TESTNETTHRESHOLD GATE: T1
-
-
- -
- 01 Encrypt in browser - 02 Seal digest on Monad - 03 Recipient acknowledges - 04 Lit checks access -
- -
- - -
-
- ); -} diff --git a/web/src/components/live-receipt-wall.tsx b/web/src/components/live-receipt-wall.tsx deleted file mode 100644 index e91cc3b..0000000 --- a/web/src/components/live-receipt-wall.tsx +++ /dev/null @@ -1,82 +0,0 @@ -"use client"; - -import { useEffect, useState } from "react"; - -type ReceiptWallItem = { - id: string; - senderWallet: string; - recipientWallet: string | null; - openerWallet: string | null; - sealedTxHash: string | null; - openedTxHash: string | null; - createdAt: string; - openedAt: string | null; -}; - -function abbreviated(value: string | null) { - if (!value) return "Open recipient"; - return `${value.slice(0, 6)}…${value.slice(-4)}`; -} - -export function LiveReceiptWall() { - const [items, setItems] = useState([]); - const [status, setStatus] = useState("Waiting for the isolated backend."); - - useEffect(() => { - let stopped = false; - async function refresh() { - try { - const response = await fetch("/api/wall", { cache: "no-store" }); - if (!response.ok) { - const body = (await response.json()) as { error?: string }; - if (!stopped) setStatus(body.error ?? "Receipt Wall is not configured."); - return; - } - const body = (await response.json()) as { items: ReceiptWallItem[] }; - if (!stopped) { - setItems(body.items); - setStatus(body.items.length ? "Streaming the latest recorded receipts." : "No recorded receipts yet."); - } - } catch { - if (!stopped) setStatus("Receipt Wall cannot reach the local backend yet."); - } - } - void refresh(); - const timer = window.setInterval(refresh, 12_000); - return () => { - stopped = true; - window.clearInterval(timer); - }; - }, []); - - return ( -
-
-
-

Live receipt wall / 02

-

A signal, not surveillance.

-
-