diff --git a/.agents/memory/todo.md b/.agents/memory/todo.md index 4e2fd00..a35e185 100644 --- a/.agents/memory/todo.md +++ b/.agents/memory/todo.md @@ -1,3 +1,44 @@ +# Task Plan: Documentation English Translation (2026-03-12) + +- [x] Inspect public markdown files and identify Japanese text that should be translated. +- [x] Translate `README.md` and `docs/*.md` to English while preserving technical meaning. +- [x] Verify that no Japanese text remains in the public documentation set. +- [x] Record the translation scope and verification results in the review section. + +# Review: Documentation English Translation (2026-03-12) + +- Rewrote `README.md` in English and aligned it with the current repository structure, Metaplex Core mint flow, and active Bun-based commands. +- Translated `docs/PRODUCT.md` to English while preserving the existing product context and relationship to `doom-index`. +- Translated `docs/DOOM_INDEX_NFT_MINT_REQUIREMENTS.md` to English while keeping the document structure, technical requirements, and JSON example intact. +- Verified with `rg -n "[ぁ-んァ-ン一-龯]" README.md docs --glob '*.md'`, which returned no matches. + +# Task Plan: Test Module Reorganization (2026-03-12) + +- [x] Inspect the current contract test coverage and map tests to the corresponding source modules. +- [x] Refactor `tests/src` so contract tests are organized by source-aligned modules instead of a single `lib.rs`. +- [x] Run the contract-focused verification commands after the reorganization. +- [x] Record the final structure and verification outcomes in the review section. + +# Review: Test Module Reorganization (2026-03-12) + +- Replaced the monolithic `tests/src/lib.rs` with a thin module entry plus shared helpers in `tests/src/test_context.rs`. +- Organized contract tests under `tests/src/instructions/` so each file now mirrors a program instruction module such as `initialize_collection`, `mint_doom_index_nft`, `transfer_admin`, and `update_base_metadata_url`. +- Split the previous combined admin-control coverage into source-aligned tests for `transfer_admin` and `update_base_metadata_url`, bringing the contract suite to 9 tests. +- Verified with `cargo fmt --all --check`, `cargo test -p tests --lib -- --list`, and `bun run test:contract`. + +# Task Plan: CI Rust + Contract Tests (2026-03-12) + +- [x] Inspect the existing CI workflow and local test scripts to confirm the minimum GitHub Actions changes required. +- [x] Update `.github/workflows/ci.yml` so Rust checks are explicit and contract tests run in CI. +- [x] Run the relevant local verification commands for the updated workflow. +- [x] Record the implementation result and verification outcomes in the review section. + +# Review: CI Rust + Contract Tests (2026-03-12) + +- Kept the existing CI setup intact and made the Rust-side test coverage explicit in `.github/workflows/ci.yml`. +- Replaced the generic `Run tests` step with separate `Run Rust tests` and `Run contract tests` steps so the workflow clearly shows both execution paths. +- Verified locally with `bun run format:ts:check`, `cargo fmt --all --check`, `cargo clippy --workspace --all-targets --all-features -- -D warnings`, `cargo test --workspace --exclude tests`, and `bun run test:contract`. + # Task Plan - [x] Reproduce the reported diagnostics with a deterministic command. @@ -71,3 +112,132 @@ # Review: Create PR (2026-03-11) - In progress. + +# Task Plan: NFT Mint Requirements Update (2026-03-12) + +- [x] Inspect current repo docs and determine where to store the requirements/design document +- [x] Verify current official Metaplex Core guidance for metadata JSON and devnet validation expectations +- [x] Draft a repository-local requirements/design document for DOOM INDEX NFT mint v0.2 +- [x] Incorporate deterministic URI minting, standard metadata, and 3D model support +- [x] Add explicit devnet verification requirements and acceptance criteria + +# Review: NFT Mint Requirements Update (2026-03-12) + +- Added `docs/DOOM_INDEX_NFT_MINT_REQUIREMENTS.md` as the primary requirements/design draft for the new Metaplex Core-based mint flow. +- Fixed the mint architecture around deterministic per-token metadata URIs and removed the earlier backend approval dependency from the spec. +- Standardized metadata around Metaplex Core JSON fields with `image`, `animation_url`, and `properties.files`, including a GLB example for 3D model support. +- Added devnet-specific functional requirements and an end-to-end validation checklist so the implementation can be verified outside localnet. + +# Task Plan: Contract V1 Implementation (2026-03-12) + +- [x] Upgrade the workspace toolchain and dependencies to Anchor 0.31.x / Solana 2.2.x / `mpl-core` 0.11.x. +- [x] Replace the existing SPL-token NFT program with Contract V1 state, errors, events, and instruction handlers. +- [x] Add Rust integration tests for config initialization, collection initialization, reservation, minting, and admin controls. +- [x] Refactor the program into a module structure modeled after official `mpl-core-anchor-examples` (`constants`, `error`, `events`, `instructions`, `state`, `utils`) instead of a monolithic `lib.rs`. +- [x] Align the implementation with the current requirements doc, including the separated contract-level `upgrade_authority` field and instruction if it remains part of the spec. +- [x] Re-run format and Rust tests after the refactor. +- [x] Investigate and document the current local SBF build blocker caused by Solana platform-tools cargo failing on `edition2024` transitive manifests. +- [x] Add devnet smoke scripts for initialize, reserve, and mint verification. +- [x] Run the full verification set that is feasible locally and record exact blockers for anything that cannot be completed. + +# Notes: Contract V1 Implementation (2026-03-12) + +- Reference project for structure and CPI style: `metaplex-foundation/mpl-core-anchor-examples` +- The current local BPF/SBF build path is blocked by the bundled Solana platform-tools cargo failing on a transitive `edition2024` dependency manifest (`rmp 0.8.15`) before tests can run under `cargo-build-sbf`. + +# Review: Contract V1 Implementation (2026-03-12) + +- Refactored the program from a monolithic `lib.rs` into `constants.rs`, `error.rs`, `events.rs`, `instructions/`, `state/`, and `utils.rs`, following the official `metaplex-foundation/mpl-core-anchor-examples` layout. +- Added the contract-level `upgrade_authority` field and `set_upgrade_authority` instruction so the on-chain config now matches the current requirements document. +- Kept the Core mint path compatible with Metaplex Core `CreateCollectionV2` / `CreateV2`, including the collection-specific rule that assets in a collection must not also set an explicit `update_authority`. +- Reworked the Rust integration tests to run the DOOM program as a host builtin while loading only the official `mpl_core` binary, which avoids the local `cargo-build-sbf` blocker and still exercises the real Core CPI path. +- Added devnet helper scripts under `scripts/devnet/` for `init`, `reserve`, and `mint`, with shared PDA/account encoding logic in `scripts/devnet/common.ts`. +- Verified with `cargo fmt --all`, `cargo clippy -p doom-nft-program --all-features --all-targets -- -D warnings`, `./scripts/test-contract-v1.sh`, and `bun x tsc --noEmit`. +- Remaining limitation: the local Solana platform-tools cargo still cannot build this dependency graph to SBF because it chokes on a transitive `edition2024` manifest. The contract test workflow now avoids that path by using the host processor for this program. + +# Task Plan: Devnet Deploy Smoke Test (2026-03-12) + +- [ ] Inspect the current Anchor/devnet configuration, wallet state, and existing smoke scripts. +- [ ] Confirm whether a fresh SBF build is possible from the current source tree or whether deployment must use the checked-in artifact. +- [ ] Deploy the DOOM NFT program to Solana devnet with Anchor-compatible tooling and record the final program id. +- [ ] Run the devnet smoke flow for config initialization, collection initialization, token reservation, and NFT minting. +- [ ] Inspect the on-chain/accounts outputs and metadata fetches to confirm the expected state transitions. +- [ ] Record exact commands, signatures, addresses, and blockers in the review section. + +# Review: Devnet Deploy Smoke Test (2026-03-12) + +- Aligned the repository to the actual deploy keypair returned by `anchor keys list` by switching the program id from `AavECgzCbVhHeBGAfcUgT1tYEC4N4B96E8XtF9H1fMGt` to `u929SRVcCFcGM2iyYkMykDRq7xW4N9ozEMU3Vo1hgfP` in `Anchor.toml`, `programs/doom-nft-program/src/lib.rs`, and `scripts/devnet/common.ts`. +- Added `anchor_version = "0.31.1"` and a `[programs.devnet]` entry to `Anchor.toml` so the workspace config matches the installed deploy key and Anchor crate version. +- Reproduced the original `anchor build` blocker under bundled `platform-tools v1.51` / `cargo 1.84.1`, where `rmp 0.8.15` failed due to the unstabilized `edition2024` manifest requirement. +- Installed newer Solana platform-tools and confirmed `cargo-build-sbf --tools-version v1.53 --manifest-path programs/doom-nft-program/Cargo.toml --sbf-out-dir target/deploy` succeeds, producing an up-to-date SBF artifact for the current source tree. +- Generated a dedicated devnet payer at `target/devnet/deployer.json` (`HmFV8YND3fAqhu1eP2Tii45sCUQu2FMUcaZdgmf1hmd9`) to avoid mutating the user's default Solana wallet. +- Deployment is currently blocked because every attempted faucet path left the payer at `0 SOL`: `solana airdrop` against `api.devnet.solana.com` failed with rate limiting for 5 / 2 / 1 / 0.5 / 0.1 SOL, and alternative public RPC paths were either paid-tier only, API-key-gated, or rate-limited as well. +- Until a devnet payer is funded, the remaining `anchor deploy` and on-chain smoke steps (`init`, `reserve`, `mint`, plus any admin instruction checks) cannot be executed. + +# Task Plan: Local Fee Measurement (2026-03-12) + +- [ ] Check the standard fee-reporting capabilities available in Anchor CLI and Solana CLI/RPC. +- [ ] Start a fresh local validator and fund the local deploy/test wallet. +- [ ] Deploy the program to localnet and record the deployment spend from balance deltas and transaction metadata. +- [ ] Execute local `initialize`, `reserve`, and `mint` flows with reachable metadata fixtures. +- [ ] Measure each instruction's network fee and rent-bearing account creations from balances and transaction details. +- [ ] Record the findings and the recommended standard tooling in the review section. + +# Review: Local Fee Measurement (2026-03-12) + +- Anchor CLI 0.32.1 の `deploy` / `test` help と公式 CLI docs を確認したが、Anchor 自体に標準の fee estimator / fee reporter はなかった。実測と見積りは Solana 側の `solana rent`, `getFeeForMessage`, `simulateTransaction`, `getTransaction.meta`, `solana confirm -v` を使うのが標準経路。 +- `solana-test-validator` を `target/localnet-ledger` で起動し、`mpl-core` を `--upgradeable-program CoREEN... target/test-sbf/mpl_core_program.so none` で genesis にロードした。 +- `python3 -m http.server 8123 --directory target/local-fixtures` で local metadata fixture を配信し、`BASE_METADATA_URL=http://127.0.0.1:8123` のまま `init -> reserve -> mint` を localnet で実行できた。 +- `anchor deploy --provider.cluster http://127.0.0.1:8899 --provider.wallet target/devnet/deployer.json` は成功し、program id `u929...` / data length `331336 bytes` / signature `4K2N3oif...` を確認した。 +- local deploy の総支出は `2.31019408 SOL` (`2310194080` lamports) で、内訳は program-data rent `2.30730264 SOL` + executable program account rent `0.00114144 SOL` + deploy transaction fees `0.00175 SOL` だった。 +- `initialize_global_config` (`4uMhwnyi...`) は `3721640` lamports (`0.00372164 SOL`) で、内訳は fee `5000` + `GlobalConfig` rent `3716640`。`computeUnitsConsumed = 10633`。 +- `initialize_collection` (`qVj2Rgi...`) は `1569040` lamports (`0.00156904 SOL`) で、内訳は fee `10000` + collection asset rent `1559040`。`computeUnitsConsumed = 15302`。 +- `reserve_token_id` (`5rJadHXM...`) は `1243880` lamports (`0.00124388 SOL`) で、内訳は fee `5000` + reservation rent `1238880`。`computeUnitsConsumed = 10190`。 +- `mint_doom_index_nft` (`2cevXVJF...`) は `3208240` lamports (`0.00320824 SOL`) で、内訳は fee `10000` + Core asset rent `3198240`。`computeUnitsConsumed = 25713`。 +- localnet で作られた account sizes は `GlobalConfig = 406 bytes`, collection asset `96 bytes`, reservation `50 bytes`, minted Core asset `116 bytes`。対応する rent は `solana rent` の実測と一致した。 + +# Task Plan: Code Review Against main (2026-03-12) + +- [ ] Inspect the diff against merge base `c1efa75aca4c3898e5ab0f6deeed665d7f9989df`. +- [ ] Validate changed code paths for behavioral regressions and test coverage gaps. +- [ ] Summarize prioritized, actionable findings with an overall correctness verdict. + +# Task Plan: Review Fixes For Test Fixture + Wallet Defaults (2026-03-12) + +- [x] Inspect the reported regressions in `scripts/build-test-sbf.sh`, `scripts/devnet/common.ts`, and `Anchor.toml`. +- [x] Replace the live Core program dump path with a version-pinned test fixture source. +- [x] Add or update coverage for devnet wallet resolution so the default path is exercised. +- [x] Align Anchor and devnet helper wallet defaults without depending on an untracked `target/` file. +- [x] Update docs that describe the contract-test fixture workflow if they no longer match behavior. +- [x] Run the relevant verification commands and record the exact outcomes. + +# Review: Review Fixes For Test Fixture + Wallet Defaults (2026-03-12) + +- Reverted `Anchor.toml` to the stable default wallet `~/.config/solana/id.json` so direct `anchor` commands no longer depend on the untracked `target/devnet/deployer.json`. +- Updated `scripts/devnet/common.ts` so wallet resolution now uses `ANCHOR_WALLET` first, then `provider.wallet` from `Anchor.toml`, then the stable default. This keeps the devnet helper scripts aligned with Anchor's configured wallet. +- Added `scripts/devnet/common.test.ts` to cover the wallet-resolution precedence and fallback behavior. +- Replaced the live `solana program dump` path in `scripts/build-test-sbf.sh` with a copy of a checked-in fixture. +- Added `tests/fixtures/mpl_core_program.so` and `tests/fixtures/mpl_core_program.so.sha256`, pinned to the official Metaplex Core release asset `release/core@0.9.10` with SHA-256 `604d401ea0c6c7b530c42274deeb903c953c1ef930bc5468497f60f3128493cc`. +- Updated `README.md` and `tests/fixtures/README.md` so the contract-test fixture workflow and provenance match the implementation. +- Verified with `bun test scripts/devnet/common.test.ts`, `bun x tsc --noEmit`, `bun run format:check`, `bun run lint`, and `bun run test:contract`. + +# Task Plan: Verify And Fix Review Findings (2026-03-12) + +- [x] Verify each reported finding against the current codebase and skip any already-fixed items. +- [x] Add or extend tests first for the confirmed behavior gaps in Rust and TypeScript helpers. +- [x] Implement the minimum code changes needed in the program, scripts, and package tooling. +- [x] Run focused and full verification commands. +- [x] Record which findings were fixed versus already resolved in the review section. + +# Review: Verify And Fix Review Findings (2026-03-12) + +- Added an explicit `typecheck` script and wired it into `check`, with `tsconfig.json` scoped to `scripts/**/*.ts` so the devnet scripts are covered by `tsc --noEmit`. +- Tightened program-side authority handling by requiring `transfer_admin` to be co-signed by the current `admin`, the current `upgrade_authority`, and the `new_admin` signer, which gives `GlobalConfig.upgrade_authority` a real privilege gate instead of leaving it unused. +- Removed the crate-wide deprecated lint suppression and replaced it with a wrapper module that localizes the Anchor 0.31 `#[program]` macro deprecation allowance while keeping `clippy -D warnings` green. +- Hardened `validate_base_metadata_url` to reject whitespace, non-HTTPS URLs, trailing slashes, and values over 256 bytes; aligned `scripts/devnet/init.ts` with the same constraints. +- Replaced the hard-coded asset name literal with `COLLECTION_NAME` and introduced `CollectionMismatch` so collection-address failures are reported accurately. +- Made `loadOrCreateKeypair` atomic with exclusive create mode `0o600`, added reserve retry logic on reservation contention, and fixed `scripts/test-contract-v1.sh` to run from `ROOT_DIR`. +- Updated `scripts/devnet/mint.ts` to decode the URI from the minted on-chain Metaplex Core asset account and to fall back from `HEAD` to `GET` when validating `image` and `animation_url`. +- Extended Rust and TypeScript coverage for reservation misuse, paused minting, transfer-admin handshakes, keypair permissions, reserve retries, on-chain URI decoding, and HEAD-to-GET asset validation. +- Verified and intentionally skipped two stale comments because the current code already addressed them: `scripts/build-test-sbf.sh` no longer reuses a dumped `mpl_core_program.so`, and the redundant `let config = global_config;` alias in `tests/src/lib.rs` was already gone after the earlier test-module split. +- Verified with `bun test scripts/devnet/common.test.ts scripts/devnet/mint.test.ts`, `cargo clippy --workspace --all-targets --all-features -- -D warnings`, `bun run check`, and the `bun run check` path’s `./scripts/test-contract-v1.sh` contract suite. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70ab23e..b6120ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,8 @@ on: jobs: checks: runs-on: ubuntu-latest + env: + SOLANA_VERSION: 2.2.1 steps: - name: Checkout @@ -24,6 +26,11 @@ jobs: with: components: rustfmt, clippy + - name: Setup Solana Tooling + uses: solana-developers/github-actions/setup-all@c6bdbee471a1a4f40490af635e9af66071d36853 # v0.2.7 + with: + solana_version: ${{ env.SOLANA_VERSION }} + - name: Cache Rust uses: Swatinem/rust-cache@v2 @@ -39,5 +46,8 @@ jobs: - name: Run Clippy run: cargo clippy --workspace --all-targets --all-features -- -D warnings - - name: Run tests - run: cargo test --workspace + - name: Run Rust tests + run: cargo test --workspace --exclude tests + + - name: Run contract tests + run: bun run test:contract diff --git a/.gitignore b/.gitignore index 2e0446b..7a60902 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ target node_modules test-ledger .yarn + +.agents/memory/ \ No newline at end of file diff --git a/Anchor.toml b/Anchor.toml index e11f494..0a263d0 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -1,12 +1,16 @@ [toolchain] -package_manager = "bun" +package_manager = "npm" +anchor_version = "0.31.1" [features] resolution = true skip-lint = false [programs.localnet] -doom_nft_program = "AavECgzCbVhHeBGAfcUgT1tYEC4N4B96E8XtF9H1fMGt" +doom_nft_program = "u929SRVcCFcGM2iyYkMykDRq7xW4N9ozEMU3Vo1hgfP" + +[programs.devnet] +doom_nft_program = "u929SRVcCFcGM2iyYkMykDRq7xW4N9ozEMU3Vo1hgfP" [registry] url = "https://api.apr.dev" diff --git a/Cargo.lock b/Cargo.lock index e754a53..00bf459 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,16 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - [[package]] name = "adler2" version = "2.0.1" @@ -20,30 +10,30 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aead" -version = "0.4.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ + "crypto-common", "generic-array", ] [[package]] name = "aes" -version = "0.7.5" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", "cpufeatures", - "opaque-debug", ] [[package]] name = "aes-gcm-siv" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" dependencies = [ "aead", "aes", @@ -54,6 +44,82 @@ dependencies = [ "zeroize", ] +[[package]] +name = "agave-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a2c365c0245cbb8959de725fc2b44c754b673fdf34c9a7f9d4a25c35a7bf1" +dependencies = [ + "ahash 0.8.12", + "solana-epoch-schedule", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", + "solana-svm-feature-set", +] + +[[package]] +name = "agave-io-uring" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a10b918a355bc78764aceb688dbbb6af72425f62be9dbfb7beb00b6d3803a0bd" +dependencies = [ + "io-uring", + "libc", + "log", + "slab", + "smallvec", +] + +[[package]] +name = "agave-precompiles" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d60d73657792af7f2464e9181d13c3979e94bb09841d9ffa014eef4ef0492b77" +dependencies = [ + "agave-feature-set", + "bincode", + "digest 0.10.7", + "ed25519-dalek", + "libsecp256k1", + "openssl", + "sha3", + "solana-ed25519-program", + "solana-message", + "solana-precompile-error", + "solana-pubkey", + "solana-sdk-ids", + "solana-secp256k1-program", + "solana-secp256r1-program", +] + +[[package]] +name = "agave-reserved-account-keys" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8289c8a8a2ef5aa10ce49a070f360f4e035ee3410b8d8f3580fb39d8cf042581" +dependencies = [ + "agave-feature-set", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "agave-transaction-view" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e8f8ca0615dc3684c63f3aceacea30be8c60986cd41a1e795878ea17df2a4" +dependencies = [ + "solana-hash", + "solana-message", + "solana-packet", + "solana-pubkey", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-svm-transaction", +] + [[package]] name = "ahash" version = "0.7.8" @@ -102,17 +168,11 @@ dependencies = [ "alloc-no-stdlib", ] -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - [[package]] name = "anchor-attribute-access-control" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f619f1d04f53621925ba8a2e633ba5a6081f2ae14758cbb67f38fd823e0a3e" +checksum = "3f70fd141a4d18adf11253026b32504f885447048c7494faf5fa83b01af9c0cf" dependencies = [ "anchor-syn", "proc-macro2", @@ -122,12 +182,12 @@ dependencies = [ [[package]] name = "anchor-attribute-account" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f2a3e1df4685f18d12a943a9f2a7456305401af21a07c9fe076ef9ecd6e400" +checksum = "715a261c57c7679581e06f07a74fa2af874ac30f86bd8ea07cca4a7e5388a064" dependencies = [ "anchor-syn", - "bs58 0.5.1", + "bs58", "proc-macro2", "quote", "syn 1.0.109", @@ -135,9 +195,9 @@ dependencies = [ [[package]] name = "anchor-attribute-constant" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9423945cb55627f0b30903288e78baf6f62c6c8ab28fb344b6b25f1ffee3dca7" +checksum = "730d6df8ae120321c5c25e0779e61789e4b70dc8297102248902022f286102e4" dependencies = [ "anchor-syn", "quote", @@ -146,9 +206,9 @@ dependencies = [ [[package]] name = "anchor-attribute-error" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ed12720033cc3c3bf3cfa293349c2275cd5ab99936e33dd4bf283aaad3e241" +checksum = "27e6e449cc3a37b2880b74dcafb8e5a17b954c0e58e376432d7adc646fb333ef" dependencies = [ "anchor-syn", "quote", @@ -157,9 +217,9 @@ dependencies = [ [[package]] name = "anchor-attribute-event" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eef4dc0371eba2d8c8b54794b0b0eb786a234a559b77593d6f80825b6d2c77a2" +checksum = "d7710e4c54adf485affcd9be9adec5ef8846d9c71d7f31e16ba86ff9fc1dd49f" dependencies = [ "anchor-syn", "proc-macro2", @@ -169,39 +229,26 @@ dependencies = [ [[package]] name = "anchor-attribute-program" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b18c4f191331e078d4a6a080954d1576241c29c56638783322a18d308ab27e4f" +checksum = "05ecfd49b2aeadeb32f35262230db402abed76ce87e27562b34f61318b2ec83c" dependencies = [ + "anchor-lang-idl", "anchor-syn", + "anyhow", + "bs58", + "heck 0.3.3", + "proc-macro2", "quote", + "serde_json", "syn 1.0.109", ] -[[package]] -name = "anchor-client" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb48c4a7911038da546dc752655a29fa49f6bd50ebc1edca218bac8da1012acd" -dependencies = [ - "anchor-lang", - "anyhow", - "futures", - "regex", - "serde", - "solana-account-decoder", - "solana-client", - "solana-sdk", - "thiserror", - "tokio", - "url", -] - [[package]] name = "anchor-derive-accounts" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de10d6e9620d3bcea56c56151cad83c5992f50d5960b3a9bebc4a50390ddc3c" +checksum = "be89d160793a88495af462a7010b3978e48e30a630c91de47ce2c1d3cb7a6149" dependencies = [ "anchor-syn", "quote", @@ -210,12 +257,12 @@ dependencies = [ [[package]] name = "anchor-derive-serde" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e2e5be518ec6053d90a2a7f26843dbee607583c779e6c8395951b9739bdfbe" +checksum = "abc6ee78acb7bfe0c2dd2abc677aaa4789c0281a0c0ef01dbf6fe85e0fd9e6e4" dependencies = [ "anchor-syn", - "borsh-derive-internal 0.10.4", + "borsh-derive-internal", "proc-macro2", "quote", "syn 1.0.109", @@ -223,9 +270,9 @@ dependencies = [ [[package]] name = "anchor-derive-space" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecc31d19fa54840e74b7a979d44bcea49d70459de846088a1d71e87ba53c419" +checksum = "134a01c0703f6fd355a0e472c033f6f3e41fac1ef6e370b20c50f4c8d022cea7" dependencies = [ "proc-macro2", "quote", @@ -234,9 +281,9 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35da4785497388af0553586d55ebdc08054a8b1724720ef2749d313494f2b8ad" +checksum = "e6bab117055905e930f762c196e08f861f8dfe7241b92cee46677a3b15561a0a" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -247,38 +294,49 @@ dependencies = [ "anchor-derive-accounts", "anchor-derive-serde", "anchor-derive-space", - "anchor-syn", - "arrayref", - "base64 0.13.1", + "anchor-lang-idl", + "base64 0.21.7", "bincode", "borsh 0.10.4", "bytemuck", - "getrandom 0.2.16", "solana-program", - "thiserror", + "thiserror 1.0.69", ] [[package]] -name = "anchor-spl" -version = "0.29.0" +name = "anchor-lang-idl" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c4fd6e43b2ca6220d2ef1641539e678bfc31b6cc393cf892b373b5997b6a39a" +checksum = "32e8599d21995f68e296265aa5ab0c3cef582fd58afec014d01bd0bce18a4418" dependencies = [ - "anchor-lang", - "solana-program", - "spl-associated-token-account", - "spl-token", - "spl-token-2022 0.9.0", + "anchor-lang-idl-spec", + "anyhow", + "heck 0.3.3", + "regex", + "serde", + "serde_json", + "sha2 0.10.9", +] + +[[package]] +name = "anchor-lang-idl-spec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bdf143115440fe621bdac3a29a1f7472e09f6cd82b2aa569429a0c13f103838" +dependencies = [ + "anyhow", + "serde", ] [[package]] name = "anchor-syn" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9101b84702fed2ea57bd22992f75065da5648017135b844283a2f6d74f27825" +checksum = "5dc7a6d90cc643df0ed2744862cdf180587d1e5d28936538c18fc8908489ed67" dependencies = [ "anyhow", - "bs58 0.5.1", + "bs58", + "cargo_toml", "heck 0.3.3", "proc-macro2", "quote", @@ -286,7 +344,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "syn 1.0.109", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -298,15 +356,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anstream" version = "0.6.21" @@ -363,6 +412,20 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "aquamarine" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f50776554130342de4836ba542aa85a4ddb361690d7e8df13774d7284c3d5c2" +dependencies = [ + "include_dir", + "itertools 0.10.5", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "ark-bn254" version = "0.4.0" @@ -386,7 +449,7 @@ dependencies = [ "ark-std", "derivative", "hashbrown 0.13.2", - "itertools", + "itertools 0.10.5", "num-traits", "zeroize", ] @@ -403,7 +466,7 @@ dependencies = [ "ark-std", "derivative", "digest 0.10.7", - "itertools", + "itertools 0.10.5", "num-bigint 0.4.6", "num-traits", "paste", @@ -510,7 +573,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -550,7 +613,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", - "event-listener", + "event-listener 2.5.3", "futures-core", ] @@ -568,12 +631,14 @@ dependencies = [ ] [[package]] -name = "async-mutex" -version = "1.4.1" +name = "async-lock" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73112ce9e1059d8604242af62c7ec8e5975ac58ac251686c8403b45e8a6fe778" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ - "event-listener", + "event-listener 5.4.1", + "event-listener-strategy", + "pin-project-lite", ] [[package]] @@ -587,6 +652,12 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atty" version = "0.2.14" @@ -623,10 +694,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "base64ct" -version = "1.8.0" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bincode" @@ -637,12 +708,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.10.0" @@ -681,7 +746,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array", ] @@ -694,22 +758,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "borsh" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" -dependencies = [ - "borsh-derive 0.9.3", - "hashbrown 0.11.2", -] - [[package]] name = "borsh" version = "0.10.4" @@ -730,27 +778,14 @@ dependencies = [ "cfg_aliases", ] -[[package]] -name = "borsh-derive" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" -dependencies = [ - "borsh-derive-internal 0.9.3", - "borsh-schema-derive-internal 0.9.3", - "proc-macro-crate 0.1.5", - "proc-macro2", - "syn 1.0.109", -] - [[package]] name = "borsh-derive" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" dependencies = [ - "borsh-derive-internal 0.10.4", - "borsh-schema-derive-internal 0.10.4", + "borsh-derive-internal", + "borsh-schema-derive-internal", "proc-macro-crate 0.1.5", "proc-macro2", "syn 1.0.109", @@ -769,17 +804,6 @@ dependencies = [ "syn 2.0.110", ] -[[package]] -name = "borsh-derive-internal" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "borsh-derive-internal" version = "0.10.4" @@ -791,17 +815,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "borsh-schema-derive-internal" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "borsh-schema-derive-internal" version = "0.10.4" @@ -834,12 +847,6 @@ dependencies = [ "alloc-stdlib", ] -[[package]] -name = "bs58" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" - [[package]] name = "bs58" version = "0.5.1" @@ -896,6 +903,29 @@ name = "bytes" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +dependencies = [ + "serde", +] + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] [[package]] name = "caps" @@ -906,6 +936,16 @@ dependencies = [ "libc", ] +[[package]] +name = "cargo_toml" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be" +dependencies = [ + "serde", + "toml 0.8.23", +] + [[package]] name = "cc" version = "1.2.47" @@ -918,6 +958,12 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfg-if" version = "1.0.4" @@ -930,6 +976,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "cfg_eval" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45565fc9416b9896014f5732ac776f810ee53a66730c17e4020c3ec064a8f88f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "chrono" version = "0.4.42" @@ -937,51 +994,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "iana-time-zone", - "js-sys", "num-traits", - "serde", - "wasm-bindgen", "windows-link", ] [[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - -[[package]] -name = "clap" -version = "2.34.0" +name = "chrono-humanize" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "799627e6b4d27827a814e837b9d8a504832086081806d45b1afa34dc982b023b" dependencies = [ - "ansi_term", - "atty", - "bitflags 1.3.2", - "strsim 0.8.0", - "textwrap 0.11.0", - "unicode-width 0.1.14", - "vec_map", + "chrono", ] [[package]] -name = "clap" -version = "3.2.25" +name = "cipher" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_lex 0.2.4", - "indexmap 1.9.3", - "once_cell", - "strsim 0.10.0", - "termcolor", - "textwrap 0.16.2", + "crypto-common", + "inout", ] [[package]] @@ -1002,8 +1035,8 @@ checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstream", "anstyle", - "clap_lex 0.7.6", - "strsim 0.11.1", + "clap_lex", + "strsim", ] [[package]] @@ -1018,15 +1051,6 @@ dependencies = [ "syn 2.0.110", ] -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - [[package]] name = "clap_lex" version = "0.7.6" @@ -1052,6 +1076,16 @@ dependencies = [ "unreachable", ] +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "compression-codecs" version = "0.4.32" @@ -1088,7 +1122,7 @@ dependencies = [ "encode_unicode", "libc", "once_cell", - "unicode-width 0.2.2", + "unicode-width", "windows-sys 0.59.0", ] @@ -1112,12 +1146,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - [[package]] name = "constant_time_eq" version = "0.3.1" @@ -1126,9 +1154,9 @@ checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "core-foundation" -version = "0.9.4" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -1205,6 +1233,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] @@ -1220,32 +1249,60 @@ dependencies = [ [[package]] name = "ctr" -version = "0.8.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ "cipher", ] [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "serde", "subtle", "zeroize", ] [[package]] -name = "darling" -version = "0.20.11" +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "darling" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ "darling_core", "darling_macro", @@ -1253,23 +1310,23 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.11.1", + "strsim", "syn 2.0.110", ] [[package]] name = "darling_macro" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", @@ -1287,6 +1344,7 @@ dependencies = [ "lock_api", "once_cell", "parking_lot_core", + "rayon", ] [[package]] @@ -1295,15 +1353,6 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", -] - [[package]] name = "der-parser" version = "8.2.0" @@ -1345,16 +1394,10 @@ dependencies = [ ] [[package]] -name = "dialoguer" -version = "0.10.4" +name = "difflib" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" -dependencies = [ - "console", - "shell-words", - "tempfile", - "zeroize", -] +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" [[package]] name = "digest" @@ -1376,6 +1419,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "dir-diff" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ad16bf5f84253b50d6557681c58c3ab67c47c77d39fed9aeb56e947290bd10" +dependencies = [ + "walkdir", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -1415,8 +1467,9 @@ name = "doom-nft-program" version = "0.1.0" dependencies = [ "anchor-lang", - "anchor-spl", + "mpl-core", "solana-program", + "url", ] [[package]] @@ -1424,9 +1477,15 @@ name = "doom-nft-program-migration" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.53", + "clap", ] +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + [[package]] name = "eager" version = "0.1.0" @@ -1448,7 +1507,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ - "curve25519-dalek", + "curve25519-dalek 3.2.0", "ed25519", "rand 0.7.3", "serde", @@ -1468,6 +1527,18 @@ dependencies = [ "sha2 0.10.9", ] +[[package]] +name = "educe" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0042ff8246a363dbe77d2ceedb073339e85a804b9a47636c6e016a9a32c05f" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "either" version = "1.15.0" @@ -1480,15 +1551,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - [[package]] name = "enum-iterator" version = "1.5.0" @@ -1509,6 +1571,19 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "enum-ordinalize" +version = "3.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf1fa3f06bbff1ea5b1a9c7b14aa992a39657db60a2759457328d7e058f49ee" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "env_logger" version = "0.9.3" @@ -1544,6 +1619,39 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener 5.4.1", + "pin-project-lite", +] + +[[package]] +name = "fastbloom" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7f34442dbe69c60fe8eaf58a8cafff81a1f278816d8ab4db255b3bef4ac3c4" +dependencies = [ + "getrandom 0.3.4", + "libm", + "rand 0.9.2", + "siphasher 1.0.2", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -1556,12 +1664,53 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "filetime" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +dependencies = [ + "cfg-if", + "libc", + "libredox", +] + [[package]] name = "find-msvc-tools" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +[[package]] +name = "five8" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75b8549488b4715defcb0d8a8a1c1c76a80661b5fa106b4ca0e7fce59d7d875" +dependencies = [ + "five8_core", +] + +[[package]] +name = "five8_const" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26dec3da8bc3ef08f2c04f61eab298c3ab334523e55f076354d6d6f613799a7b" +dependencies = [ + "five8_core", +] + +[[package]] +name = "five8_core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2551bf44bc5f776c15044b9b94153a00198be06743e262afaaa61f11ac7523a5" + [[package]] name = "flate2" version = "1.1.5" @@ -1572,6 +1721,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1579,10 +1737,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "foldhash" -version = "0.1.5" +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" @@ -1593,6 +1760,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fragile" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" + [[package]] name = "futures" version = "0.3.31" @@ -1664,6 +1837,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.31" @@ -1688,7 +1867,6 @@ version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "serde", "typenum", "version_check", ] @@ -1736,65 +1914,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasip2", + "wasm-bindgen", ] [[package]] -name = "goblin" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143" -dependencies = [ - "log", - "plain", - "scroll", -] - -[[package]] -name = "h2" -version = "0.3.27" +name = "governor" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.12.1", - "slab", - "tokio", - "tokio-util", - "tracing", + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.8.5", + "smallvec", + "spinning_top", ] [[package]] name = "hash32" -version = "0.2.1" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" dependencies = [ "byteorder", ] [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash 0.7.8", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.13.2" @@ -1810,17 +1974,6 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -[[package]] -name = "hashbrown" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] - [[package]] name = "hashbrown" version = "0.16.1" @@ -1836,6 +1989,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" @@ -1904,14 +2063,36 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + [[package]] name = "http-body" -version = "0.4.6" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.4.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "http", + "futures-core", + "http 1.4.0", + "http-body", "pin-project-lite", ] @@ -1921,12 +2102,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - [[package]] name = "humantime" version = "2.3.0" @@ -1935,40 +2110,63 @@ checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "hyper" -version = "0.14.32" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ + "atomic-waker", "bytes", "futures-channel", "futures-core", - "futures-util", - "h2", - "http", + "http 1.4.0", "http-body", "httparse", - "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.10", + "pin-utils", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] [[package]] name = "hyper-rustls" -version = "0.24.2" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http 1.4.0", + "hyper", + "hyper-util", + "rustls 0.23.37", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.4", + "tower-service", + "webpki-roots 1.0.6", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", "futures-util", - "http", + "http 1.4.0", + "http-body", "hyper", - "rustls", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.1", "tokio", - "tokio-rustls", + "tower-service", + "tracing", ] [[package]] @@ -2120,13 +2318,22 @@ dependencies = [ ] [[package]] -name = "indexmap" -version = "1.9.3" +name = "include_dir" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" dependencies = [ - "autocfg", - "hashbrown 0.12.3", + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" +dependencies = [ + "proc-macro2", + "quote", ] [[package]] @@ -2148,19 +2355,49 @@ dependencies = [ "console", "number_prefix", "portable-atomic", - "unicode-width 0.2.2", + "unicode-width", "web-time", ] [[package]] -name = "ipnet" -version = "2.11.0" +name = "inout" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] [[package]] -name = "is_terminal_polyfill" -version = "1.70.2" +name = "io-uring" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd7bddefd0a8833b88a4b68f90dae22c7450d11b354198baee3874fd811b344" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" @@ -2173,12 +2410,43 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine 4.6.7", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jobserver" version = "0.1.34" @@ -2214,6 +2482,27 @@ dependencies = [ "serde_json", ] +[[package]] +name = "kaigan" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba15de5aeb137f0f65aa3bf82187647f1285abfe5b20c80c2c37f7007ad519a" +dependencies = [ + "borsh 0.10.4", + "serde", +] + +[[package]] +name = "kaigan" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f25ded719a2354f6b1a51d0c0741c25bc7afe038617664eb37f6418439eb084" +dependencies = [ + "anchor-lang", + "borsh 0.10.4", + "serde", +] + [[package]] name = "keccak" version = "0.1.5" @@ -2235,6 +2524,24 @@ version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libredox" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +dependencies = [ + "bitflags", + "libc", + "plain", + "redox_syscall 0.7.3", +] + [[package]] name = "libsecp256k1" version = "0.6.0" @@ -2292,7 +2599,7 @@ dependencies = [ "ark-bn254", "ark-ff", "num-bigint 0.4.6", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2322,6 +2629,40 @@ version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +[[package]] +name = "lru" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" +dependencies = [ + "hashbrown 0.12.3", +] + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "lz4" +version = "1.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20b523e860d03443e98350ceaac5e71c6ba89aea7d960769ec3ce37f4de5af4" +dependencies = [ + "lz4-sys", +] + +[[package]] +name = "lz4-sys" +version = "1.11.1+lz4-1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "memchr" version = "2.7.6" @@ -2338,12 +2679,12 @@ dependencies = [ ] [[package]] -name = "memoffset" -version = "0.7.1" +name = "memmap2" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" dependencies = [ - "autocfg", + "libc", ] [[package]] @@ -2367,12 +2708,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2400,19 +2735,92 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "mockall" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "lazy_static", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "modular-bitfield" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a53d79ba8304ac1c4f9eb3b9d281f21f7be9d4626f72ce7df4ad8fbde4f38a74" +dependencies = [ + "modular-bitfield-impl", + "static_assertions", +] + +[[package]] +name = "modular-bitfield-impl" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "mpl-core" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502b2373d5c32f944dc095a250a5c5e5d283cad1a0f55d9e18ee267235b40e89" +dependencies = [ + "anchor-lang", + "base64 0.22.1", + "borsh 0.10.4", + "kaigan 0.3.0", + "modular-bitfield", + "num-derive 0.3.3", + "num-traits", + "rmp-serde", + "serde_json", + "solana-program", + "thiserror 1.0.69", +] + [[package]] name = "nix" -version = "0.26.4" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cfg-if", + "cfg_aliases", "libc", - "memoffset 0.7.1", - "pin-utils", + "memoffset", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + [[package]] name = "nom" version = "7.1.3" @@ -2423,6 +2831,18 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + [[package]] name = "num" version = "0.2.1" @@ -2547,37 +2967,16 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive 0.6.1", -] - [[package]] name = "num_enum" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ - "num_enum_derive 0.7.5", + "num_enum_derive", "rustversion", ] -[[package]] -name = "num_enum_derive" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 2.0.110", -] - [[package]] name = "num_enum_derive" version = "0.7.5" @@ -2623,17 +3022,84 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "openssl-probe" -version = "0.1.6" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "openssl-src" +version = "300.5.5+3.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f1787d533e03597a7934fd0a765f0d28e94ecc5fb7789f8053b1e699a56f709" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "opentelemetry" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +checksum = "6105e89802af13fdf48c49d7646d3b533a70e536d818aae7e78ba0433d01acb8" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures-channel", + "futures-executor", + "futures-util", + "js-sys", + "lazy_static", + "percent-encoding", + "pin-project", + "rand 0.8.5", + "thiserror 1.0.69", +] [[package]] -name = "os_str_bytes" -version = "6.6.1" +name = "parking" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -2653,7 +3119,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", "windows-link", ] @@ -2664,15 +3130,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pbkdf2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" -dependencies = [ - "crypto-mac", -] - [[package]] name = "pbkdf2" version = "0.11.0" @@ -2706,6 +3163,26 @@ dependencies = [ "num", ] +[[package]] +name = "pin-project" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -2718,17 +3195,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - [[package]] name = "pkg-config" version = "0.3.32" @@ -2743,9 +3209,9 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "polyval" -version = "0.5.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", @@ -2784,22 +3250,42 @@ dependencies = [ ] [[package]] -name = "proc-macro-crate" -version = "0.1.5" +name = "predicates" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" +dependencies = [ + "difflib", + "float-cmp", + "itertools 0.10.5", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144" + +[[package]] +name = "predicates-tree" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2" dependencies = [ - "toml", + "predicates-core", + "termtree", ] [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "toml 0.5.11", ] [[package]] @@ -2811,6 +3297,27 @@ dependencies = [ "toml_edit 0.23.7", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", +] + [[package]] name = "proc-macro2" version = "1.0.103" @@ -2840,52 +3347,76 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "quanta" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.1+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quinn" -version = "0.10.2" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", + "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", - "rustls", - "thiserror", + "rustls 0.23.37", + "socket2 0.6.1", + "thiserror 2.0.18", "tokio", "tracing", + "web-time", ] [[package]] name = "quinn-proto" -version = "0.10.6" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ "bytes", - "rand 0.8.5", - "ring 0.16.20", + "fastbloom", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", "rustc-hash", - "rustls", - "rustls-native-certs", + "rustls 0.23.37", + "rustls-pki-types", + "rustls-platform-verifier", "slab", - "thiserror", + "thiserror 2.0.18", "tinyvec", "tracing", + "web-time", ] [[package]] name = "quinn-udp" -version = "0.4.1" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ - "bytes", + "cfg_aliases", "libc", - "socket2 0.5.10", + "once_cell", + "socket2 0.6.1", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.60.2", ] [[package]] @@ -2927,6 +3458,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -2947,6 +3488,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -2965,6 +3516,15 @@ dependencies = [ "getrandom 0.2.16", ] +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -2983,6 +3543,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags", +] + [[package]] name = "rayon" version = "1.11.0" @@ -3004,24 +3573,21 @@ dependencies = [ ] [[package]] -name = "rcgen" -version = "0.10.0" +name = "redox_syscall" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "pem", - "ring 0.16.20", - "time", - "yasna", + "bitflags", ] [[package]] name = "redox_syscall" -version = "0.5.18" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" dependencies = [ - "bitflags 2.10.0", + "bitflags", ] [[package]] @@ -3055,60 +3621,57 @@ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.11.27" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "async-compression", - "base64 0.21.7", + "base64 0.22.1", "bytes", - "encoding_rs", + "futures-channel", "futures-core", "futures-util", - "h2", - "http", + "http 1.4.0", "http-body", + "http-body-util", "hyper", "hyper-rustls", - "ipnet", + "hyper-util", "js-sys", "log", - "mime", - "once_cell", "percent-encoding", "pin-project-lite", - "rustls", - "rustls-pemfile", + "quinn", + "rustls 0.23.37", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", - "tokio-rustls", - "tokio-util", + "tokio-rustls 0.26.4", + "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.4", - "winreg", + "webpki-roots 1.0.6", ] [[package]] -name = "ring" -version = "0.16.20" +name = "reqwest-middleware" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +checksum = "57f17d28a6e6acfe1733fe24bcd30774d13bffa4b8a22535b4c8c98423088d4e" dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted 0.7.1", - "web-sys", - "winapi", + "anyhow", + "async-trait", + "http 1.4.0", + "reqwest", + "serde", + "thiserror 1.0.69", + "tower-service", ] [[package]] @@ -3121,29 +3684,27 @@ dependencies = [ "cfg-if", "getrandom 0.2.16", "libc", - "untrusted 0.9.0", + "untrusted", "windows-sys 0.52.0", ] [[package]] -name = "rpassword" -version = "7.4.0" +name = "rmp" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d4c8b64f049c6721ec8ccec37ddfc3d641c4a7fca57e8f2a89de509c73df39" +checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c" dependencies = [ - "libc", - "rtoolbox", - "windows-sys 0.59.0", + "num-traits", ] [[package]] -name = "rtoolbox" -version = "0.0.3" +name = "rmp-serde" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cc970b249fbe527d6e02e0a227762c9108b2f49d81094fe357ffc6d14d7f6f" +checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155" dependencies = [ - "libc", - "windows-sys 0.52.0", + "rmp", + "serde", ] [[package]] @@ -3154,9 +3715,9 @@ checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc_version" @@ -3182,7 +3743,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.10.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -3196,40 +3757,93 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring 0.17.14", - "rustls-webpki", + "ring", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.23.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki 0.103.9", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pki-types", "schannel", "security-framework", ] [[package]] -name = "rustls-pemfile" -version = "1.0.4" +name = "rustls-pki-types" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ - "base64 0.21.7", + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.37", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.9", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", ] +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.14", - "untrusted 0.9.0", + "ring", + "untrusted", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] @@ -3244,6 +3858,15 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.28" @@ -3259,43 +3882,23 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "scroll" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" -dependencies = [ - "scroll_derive", -] - -[[package]] -name = "scroll_derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.110", -] - [[package]] name = "sct" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.14", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] name = "security-framework" -version = "2.11.1" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ - "bitflags 2.10.0", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -3318,6 +3921,15 @@ version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +[[package]] +name = "seqlock" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5c67b6f14ecc5b86c66fa63d76b5092352678545a8a3cdae80aef5128371910" +dependencies = [ + "parking_lot", +] + [[package]] name = "serde" version = "1.0.228" @@ -3328,6 +3940,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + [[package]] name = "serde_bytes" version = "0.11.19" @@ -3371,6 +3992,15 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3385,19 +4015,19 @@ dependencies = [ [[package]] name = "serde_with" -version = "2.3.3" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +checksum = "381b283ce7bc6b476d903296fb59d0d36633652b633b27f64db4fb46dcbfc3b9" dependencies = [ - "serde", + "serde_core", "serde_with_macros", ] [[package]] name = "serde_with_macros" -version = "2.3.3" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +checksum = "a6d4e30573c8cb306ed6ab1dca8423eec9a463ea0e155f45399455e0368b27e0" dependencies = [ "darling", "proc-macro2", @@ -3440,18 +4070,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug", -] - [[package]] name = "sha3" version = "0.10.8" @@ -3463,10 +4081,13 @@ dependencies = [ ] [[package]] -name = "shell-words" -version = "1.1.0" +name = "sharded-slab" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] [[package]] name = "shlex" @@ -3474,6 +4095,16 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + [[package]] name = "signal-hook-registry" version = "1.4.7" @@ -3501,6 +4132,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "siphasher" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + [[package]] name = "sized-chunks" version = "0.6.5" @@ -3544,1013 +4181,3069 @@ dependencies = [ ] [[package]] -name = "solana-account-decoder" -version = "1.18.26" +name = "solana-account" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b109fd3a106e079005167e5b0e6f6d2c88bbedec32530837b584791a8b5abf36" +checksum = "0f949fe4edaeaea78c844023bfc1c898e0b1f5a100f8a8d2d0f85d0a7b090258" dependencies = [ - "Inflector", - "base64 0.21.7", "bincode", - "bs58 0.4.0", - "bv", - "lazy_static", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-sysvar", +] + +[[package]] +name = "solana-account-decoder-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5519e8343325b707f17fbed54fcefb325131b692506d0af9e08a539d15e4f8cf" +dependencies = [ + "base64 0.22.1", + "bs58", "serde", "serde_derive", "serde_json", - "solana-config-program", - "solana-sdk", - "spl-token", - "spl-token-2022 1.0.0", - "spl-token-group-interface", - "spl-token-metadata-interface", - "thiserror", + "solana-account", + "solana-pubkey", "zstd", ] [[package]] -name = "solana-clap-utils" -version = "1.18.26" +name = "solana-account-info" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074ef478856a45d5627270fbc6b331f91de9aae7128242d9e423931013fb8a2a" +checksum = "c8f5152a288ef1912300fc6efa6c2d1f9bb55d9398eb6c72326360b8063987da" dependencies = [ - "chrono", - "clap 2.34.0", - "rpassword", - "solana-remote-wallet", - "solana-sdk", - "thiserror", - "tiny-bip39", - "uriparse", - "url", + "bincode", + "serde", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", ] [[package]] -name = "solana-client" -version = "1.18.26" +name = "solana-accounts-db" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24a9f32c42402c4b9484d5868ac74b7e0a746e3905d8bfd756e1203e50cbb87e" +checksum = "dbbe35141711500d113dfc7aa79eb250c4458f04e759a67ba4bffc3e6cddc402" dependencies = [ - "async-trait", + "agave-io-uring", + "ahash 0.8.12", + "bincode", + "blake3", + "bv", + "bytemuck", + "bytemuck_derive", + "bzip2", + "crossbeam-channel", + "dashmap", + "indexmap", + "io-uring", + "itertools 0.12.1", + "log", + "lz4", + "memmap2 0.9.10", + "modular-bitfield", + "num_cpus", + "num_enum", + "rand 0.8.5", + "rayon", + "seqlock", + "serde", + "serde_derive", + "slab", + "smallvec", + "solana-account", + "solana-address-lookup-table-interface", + "solana-bucket-map", + "solana-clock", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-genesis-config", + "solana-hash", + "solana-lattice-hash", + "solana-measure", + "solana-message", + "solana-metrics", + "solana-nohash-hasher", + "solana-pubkey", + "solana-rayon-threadlimit", + "solana-rent-collector", + "solana-reward-info", + "solana-sha256-hasher", + "solana-slot-hashes", + "solana-svm-transaction", + "solana-system-interface", + "solana-sysvar", + "solana-time-utils", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "spl-generic-token", + "static_assertions", + "tar", + "tempfile", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-address-lookup-table-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1673f67efe870b64a65cb39e6194be5b26527691ce5922909939961a6e6b395" +dependencies = [ + "bincode", + "bytemuck", + "serde", + "serde_derive", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-slot-hashes", +] + +[[package]] +name = "solana-atomic-u64" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52e52720efe60465b052b9e7445a01c17550666beec855cce66f44766697bc2" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "solana-banks-client" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68548570c38a021c724b5aa0112f45a54bdf7ff1b041a042848e034a95a96994" +dependencies = [ + "borsh 1.5.7", + "futures", + "solana-account", + "solana-banks-interface", + "solana-clock", + "solana-commitment-config", + "solana-hash", + "solana-message", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-signature", + "solana-sysvar", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "tarpc", + "thiserror 2.0.18", + "tokio", + "tokio-serde", +] + +[[package]] +name = "solana-banks-interface" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6d90edc435bf488ef7abed4dcb1f94fa1970102cbabb25688f58417fd948286" +dependencies = [ + "serde", + "serde_derive", + "solana-account", + "solana-clock", + "solana-commitment-config", + "solana-hash", + "solana-message", + "solana-pubkey", + "solana-signature", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "tarpc", +] + +[[package]] +name = "solana-banks-server" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36080e4a97afe47f8b56356a0cabc3b1dadfb09efb4ea8c44d79d19a4e7d6534" +dependencies = [ + "agave-feature-set", + "bincode", + "crossbeam-channel", + "futures", + "solana-account", + "solana-banks-interface", + "solana-client", + "solana-clock", + "solana-commitment-config", + "solana-hash", + "solana-message", + "solana-pubkey", + "solana-runtime", + "solana-runtime-transaction", + "solana-send-transaction-service", + "solana-signature", + "solana-svm", + "solana-transaction", + "solana-transaction-error", + "tarpc", + "tokio", + "tokio-serde", +] + +[[package]] +name = "solana-big-mod-exp" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75db7f2bbac3e62cfd139065d15bcda9e2428883ba61fc8d27ccb251081e7567" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "solana-define-syscall", +] + +[[package]] +name = "solana-bincode" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a3787b8cf9c9fe3dd360800e8b70982b9e5a8af9e11c354b6665dd4a003adc" +dependencies = [ + "bincode", + "serde", + "solana-instruction", +] + +[[package]] +name = "solana-blake3-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0801e25a1b31a14494fc80882a036be0ffd290efc4c2d640bfcca120a4672" +dependencies = [ + "blake3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-bn254" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4420f125118732833f36facf96a27e7b78314b2d642ba07fa9ffdacd8d79e243" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "bytemuck", + "solana-define-syscall", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-borsh" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718333bcd0a1a7aed6655aa66bef8d7fb047944922b2d3a18f49cbc13e73d004" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.7", +] + +[[package]] +name = "solana-bpf-loader-program" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aec57dcd80d0f6879956cad28854a6eebaed6b346ce56908ea01a9f36ab259" +dependencies = [ + "bincode", + "libsecp256k1", + "num-traits", + "qualifier_attr", + "scopeguard", + "solana-account", + "solana-account-info", + "solana-big-mod-exp", + "solana-bincode", + "solana-blake3-hasher", + "solana-bn254", + "solana-clock", + "solana-cpi", + "solana-curve25519", + "solana-hash", + "solana-instruction", + "solana-keccak-hasher", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-log-collector", + "solana-measure", + "solana-packet", + "solana-poseidon", + "solana-program-entrypoint", + "solana-program-runtime", + "solana-pubkey", + "solana-sbpf", + "solana-sdk-ids", + "solana-secp256k1-recover", + "solana-sha256-hasher", + "solana-stable-layout", + "solana-svm-feature-set", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", + "solana-timings", + "solana-transaction-context", + "solana-type-overrides", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-bucket-map" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e067a30c43dc66f300584034ce1526da882d3100d45a10613a4e554b3e1e3937" +dependencies = [ + "bv", + "bytemuck", + "bytemuck_derive", + "memmap2 0.9.10", + "modular-bitfield", + "num_enum", + "rand 0.8.5", + "solana-clock", + "solana-measure", + "solana-pubkey", + "tempfile", +] + +[[package]] +name = "solana-builtins" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d61a31b63b52b0d268cbcd56c76f50314867d7f8e07a0f2c62ee7c9886e07b2" +dependencies = [ + "agave-feature-set", + "solana-bpf-loader-program", + "solana-compute-budget-program", + "solana-hash", + "solana-loader-v4-program", + "solana-program-runtime", + "solana-pubkey", + "solana-sdk-ids", + "solana-stake-program", + "solana-system-program", + "solana-vote-program", + "solana-zk-elgamal-proof-program", + "solana-zk-token-proof-program", +] + +[[package]] +name = "solana-builtins-default-costs" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ca69a299a6c969b18ea381a02b40c9e4dda04b2af0d15a007c1184c82163bbb" +dependencies = [ + "agave-feature-set", + "ahash 0.8.12", + "log", + "solana-bpf-loader-program", + "solana-compute-budget-program", + "solana-loader-v4-program", + "solana-pubkey", + "solana-sdk-ids", + "solana-stake-program", + "solana-system-program", + "solana-vote-program", +] + +[[package]] +name = "solana-client" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc55d1f263e0be4127daf33378d313ea0977f9ffd3fba50fa544ca26722fc695" +dependencies = [ + "async-trait", "bincode", "dashmap", "futures", "futures-util", - "indexmap 2.12.1", + "indexmap", "indicatif", "log", "quinn", "rayon", + "solana-account", + "solana-client-traits", + "solana-commitment-config", "solana-connection-cache", + "solana-epoch-info", + "solana-hash", + "solana-instruction", + "solana-keypair", "solana-measure", - "solana-metrics", + "solana-message", + "solana-pubkey", "solana-pubsub-client", "solana-quic-client", + "solana-quic-definitions", "solana-rpc-client", "solana-rpc-client-api", "solana-rpc-client-nonce-utils", - "solana-sdk", + "solana-signature", + "solana-signer", "solana-streamer", "solana-thin-client", + "solana-time-utils", "solana-tpu-client", + "solana-transaction", + "solana-transaction-error", "solana-udp-client", - "thiserror", + "thiserror 2.0.18", "tokio", ] [[package]] -name = "solana-config-program" -version = "1.18.26" +name = "solana-client-traits" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d75b803860c0098e021a26f0624129007c15badd5b0bc2fbd9f0e1a73060d3b" +checksum = "83f0071874e629f29e0eb3dab8a863e98502ac7aba55b7e0df1803fc5cac72a7" +dependencies = [ + "solana-account", + "solana-commitment-config", + "solana-epoch-info", + "solana-hash", + "solana-instruction", + "solana-keypair", + "solana-message", + "solana-pubkey", + "solana-signature", + "solana-signer", + "solana-system-interface", + "solana-transaction", + "solana-transaction-error", +] + +[[package]] +name = "solana-clock" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8584296123df8fe229b95e2ebfd37ae637fe9db9b7d4dd677ac5a78e80dbfce" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-cluster-type" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ace9fea2daa28354d107ea879cff107181d85cd4e0f78a2bedb10e1a428c97e" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", +] + +[[package]] +name = "solana-commitment-config" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac49c4dde3edfa832de1697e9bcdb7c3b3f7cb7a1981b7c62526c8bb6700fb73" dependencies = [ - "bincode", - "chrono", "serde", "serde_derive", +] + +[[package]] +name = "solana-compute-budget" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f4fc63bc2276a1618ca0bfc609da7448534ecb43a1cb387cdf9eaa2dc7bc272" +dependencies = [ + "solana-fee-structure", "solana-program-runtime", - "solana-sdk", +] + +[[package]] +name = "solana-compute-budget-instruction" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503d94430f6d3c5ac1e1fa6a342c1c714d5b03c800999e7b6cf235298f0b5341" +dependencies = [ + "agave-feature-set", + "log", + "solana-borsh", + "solana-builtins-default-costs", + "solana-compute-budget", + "solana-compute-budget-interface", + "solana-instruction", + "solana-packet", + "solana-pubkey", + "solana-sdk-ids", + "solana-svm-transaction", + "solana-transaction-error", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-compute-budget-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8432d2c4c22d0499aa06d62e4f7e333f81777b3d7c96050ae9e5cb71a8c3aee4" +dependencies = [ + "borsh 1.5.7", + "serde", + "serde_derive", + "solana-instruction", + "solana-sdk-ids", +] + +[[package]] +name = "solana-compute-budget-program" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "072b02beed1862c6b7b7a8a699379594c4470a9371c711856a0a3c266dcf57e5" +dependencies = [ + "solana-program-runtime", +] + +[[package]] +name = "solana-config-program-client" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53aceac36f105fd4922e29b4f0c1f785b69d7b3e7e387e384b8985c8e0c3595e" +dependencies = [ + "bincode", + "borsh 0.10.4", + "kaigan 0.2.6", + "serde", + "solana-program", ] [[package]] name = "solana-connection-cache" -version = "1.18.26" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9306ede13e8ceeab8a096bcf5fa7126731e44c201ca1721ea3c38d89bcd4111" +checksum = "45c1cff5ebb26aefff52f1a8e476de70ec1683f8cc6e4a8c86b615842d91f436" dependencies = [ "async-trait", "bincode", "crossbeam-channel", "futures-util", - "indexmap 2.12.1", + "indexmap", "log", "rand 0.8.5", "rayon", - "rcgen", + "solana-keypair", "solana-measure", "solana-metrics", - "solana-sdk", - "thiserror", + "solana-time-utils", + "solana-transaction-error", + "thiserror 2.0.18", "tokio", ] [[package]] -name = "solana-frozen-abi" -version = "1.18.26" +name = "solana-cost-model" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03ab2c30c15311b511c0d1151e4ab6bc9a3e080a37e7c6e7c2d96f5784cf9434" +checksum = "b24b35813c678ed40ca91f989a3c9e1780e6aef0139e15731785bca1189443c3" dependencies = [ - "block-buffer 0.10.4", - "bs58 0.4.0", - "bv", - "either", - "generic-array", - "im", - "lazy_static", + "agave-feature-set", + "ahash 0.8.12", "log", - "memmap2", - "rustc_version", + "solana-bincode", + "solana-borsh", + "solana-builtins-default-costs", + "solana-clock", + "solana-compute-budget", + "solana-compute-budget-instruction", + "solana-compute-budget-interface", + "solana-fee-structure", + "solana-metrics", + "solana-packet", + "solana-pubkey", + "solana-runtime-transaction", + "solana-sdk-ids", + "solana-svm-transaction", + "solana-system-interface", + "solana-transaction-error", + "solana-vote-program", +] + +[[package]] +name = "solana-cpi" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc71126edddc2ba014622fc32d0f5e2e78ec6c5a1e0eb511b85618c09e9ea11" +dependencies = [ + "solana-account-info", + "solana-define-syscall", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-stable-layout", +] + +[[package]] +name = "solana-curve25519" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae4261b9a8613d10e77ac831a8fa60b6fa52b9b103df46d641deff9f9812a23" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-define-syscall", + "subtle", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-decode-error" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" +dependencies = [ + "num-traits", +] + +[[package]] +name = "solana-define-syscall" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae3e2abcf541c8122eafe9a625d4d194b4023c20adde1e251f94e056bb1aee2" + +[[package]] +name = "solana-derivation-path" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "939756d798b25c5ec3cca10e06212bdca3b1443cb9bb740a38124f58b258737b" +dependencies = [ + "derivation-path", + "qstring", + "uriparse", +] + +[[package]] +name = "solana-ed25519-program" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feafa1691ea3ae588f99056f4bdd1293212c7ece28243d7da257c443e84753" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "ed25519-dalek", + "solana-feature-set", + "solana-instruction", + "solana-precompile-error", + "solana-sdk-ids", +] + +[[package]] +name = "solana-epoch-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ef6f0b449290b0b9f32973eefd95af35b01c5c0c34c569f936c34c5b20d77b" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-epoch-rewards" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-epoch-rewards-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c5fd2662ae7574810904585fd443545ed2b568dbd304b25a31e79ccc76e81b" +dependencies = [ + "siphasher 0.3.11", + "solana-hash", + "solana-pubkey", +] + +[[package]] +name = "solana-epoch-schedule" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fce071fbddecc55d727b1d7ed16a629afe4f6e4c217bc8d00af3b785f6f67ed" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-example-mocks" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84461d56cbb8bb8d539347151e0525b53910102e4bced875d49d5139708e39d3" +dependencies = [ + "serde", + "serde_derive", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-hash", + "solana-instruction", + "solana-keccak-hasher", + "solana-message", + "solana-nonce", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-feature-gate-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f5c5382b449e8e4e3016fb05e418c53d57782d8b5c30aa372fc265654b956d" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-feature-set" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93b93971e289d6425f88e6e3cb6668c4b05df78b3c518c249be55ced8efd6b6d" +dependencies = [ + "ahash 0.8.12", + "lazy_static", + "solana-epoch-schedule", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-fee" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16beda37597046b1edd1cea6fa7caaed033c091f99ec783fe59c82828bc2adb8" +dependencies = [ + "agave-feature-set", + "solana-fee-structure", + "solana-svm-transaction", +] + +[[package]] +name = "solana-fee-calculator" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89bc408da0fb3812bc3008189d148b4d3e08252c79ad810b245482a3f70cd8d" +dependencies = [ + "log", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-fee-structure" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33adf673581c38e810bf618f745bf31b683a0a4a4377682e6aaac5d9a058dd4e" +dependencies = [ + "serde", + "serde_derive", + "solana-message", + "solana-native-token", +] + +[[package]] +name = "solana-genesis-config" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3725085d47b96d37fef07a29d78d2787fc89a0b9004c66eed7753d1e554989f" +dependencies = [ + "bincode", + "chrono", + "memmap2 0.5.10", + "serde", + "serde_derive", + "solana-account", + "solana-clock", + "solana-cluster-type", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-hash", + "solana-inflation", + "solana-keypair", + "solana-logger", + "solana-poh-config", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-sha256-hasher", + "solana-shred-version", + "solana-signer", + "solana-time-utils", +] + +[[package]] +name = "solana-hard-forks" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c28371f878e2ead55611d8ba1b5fb879847156d04edea13693700ad1a28baf" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-hash" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" +dependencies = [ + "borsh 1.5.7", + "bytemuck", + "bytemuck_derive", + "five8", + "js-sys", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-sanitize", + "wasm-bindgen", +] + +[[package]] +name = "solana-inflation" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23eef6a09eb8e568ce6839573e4966850e85e9ce71e6ae1a6c930c1c43947de3" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-instruction" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab5682934bd1f65f8d2c16f21cb532526fcc1a09f796e2cacdb091eee5774ad" +dependencies = [ + "bincode", + "borsh 1.5.7", + "getrandom 0.2.16", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "serde_json", + "solana-define-syscall", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0e85a6fad5c2d0c4f5b91d34b8ca47118fc593af706e523cdbedf846a954f57" +dependencies = [ + "bitflags", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-serialize-utils", + "solana-sysvar-id", +] + +[[package]] +name = "solana-keccak-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7aeb957fbd42a451b99235df4942d96db7ef678e8d5061ef34c9b34cae12f79" +dependencies = [ + "sha3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-keypair" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd3f04aa1a05c535e93e121a95f66e7dcccf57e007282e8255535d24bf1e98bb" +dependencies = [ + "ed25519-dalek", + "ed25519-dalek-bip32", + "five8", + "rand 0.7.3", + "solana-derivation-path", + "solana-pubkey", + "solana-seed-derivable", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "wasm-bindgen", +] + +[[package]] +name = "solana-last-restart-slot" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6360ac2fdc72e7463565cd256eedcf10d7ef0c28a1249d261ec168c1b55cdd" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-lattice-hash" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6effe24897d8e02484ad87272634028d096f0e061b66b298f8df5031ff7fc0" +dependencies = [ + "base64 0.22.1", + "blake3", + "bs58", + "bytemuck", +] + +[[package]] +name = "solana-loader-v2-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ab08006dad78ae7cd30df8eea0539e207d08d91eaefb3e1d49a446e1c49654" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f7162a05b8b0773156b443bccd674ea78bb9aa406325b467ea78c06c99a63a2" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-loader-v4-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "706a777242f1f39a83e2a96a2a6cb034cb41169c6ecbee2cf09cb873d9659e7e" +dependencies = [ "serde", "serde_bytes", "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-loader-v4-program" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ab01855d851fa2fb6034b0d48de33d77d5c5f5fb4b0353d8e4a934cc03d48a" +dependencies = [ + "log", + "qualifier_attr", + "solana-account", + "solana-bincode", + "solana-bpf-loader-program", + "solana-instruction", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-log-collector", + "solana-measure", + "solana-packet", + "solana-program-runtime", + "solana-pubkey", + "solana-sbpf", + "solana-sdk-ids", + "solana-transaction-context", + "solana-type-overrides", +] + +[[package]] +name = "solana-log-collector" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d945b1cf5bf7cbd6f5b78795beda7376370c827640df43bb2a1c17b492dc106" +dependencies = [ + "log", +] + +[[package]] +name = "solana-logger" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8e777ec1afd733939b532a42492d888ec7c88d8b4127a5d867eb45c6eb5cd5" +dependencies = [ + "env_logger", + "lazy_static", + "libc", + "log", + "signal-hook", +] + +[[package]] +name = "solana-measure" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11dcd67cd2ae6065e494b64e861e0498d046d95a61cbbf1ae3d58be1ea0f42ed" + +[[package]] +name = "solana-message" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1796aabce376ff74bf89b78d268fa5e683d7d7a96a0a4e4813ec34de49d5314b" +dependencies = [ + "bincode", + "blake3", + "lazy_static", + "serde", + "serde_derive", + "solana-bincode", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-system-interface", + "solana-transaction-error", + "wasm-bindgen", +] + +[[package]] +name = "solana-metrics" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0375159d8460f423d39e5103dcff6e07796a5ec1850ee1fcfacfd2482a8f34b5" +dependencies = [ + "crossbeam-channel", + "gethostname", + "log", + "reqwest", + "solana-cluster-type", + "solana-sha256-hasher", + "solana-time-utils", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-msg" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36a1a14399afaabc2781a1db09cb14ee4cc4ee5c7a5a3cfcc601811379a8092" +dependencies = [ + "solana-define-syscall", +] + +[[package]] +name = "solana-native-token" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61515b880c36974053dd499c0510066783f0cc6ac17def0c7ef2a244874cf4a9" + +[[package]] +name = "solana-net-utils" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a9e831d0f09bd92135d48c5bc79071bb59c0537b9459f1b4dec17ecc0558fa" +dependencies = [ + "anyhow", + "bincode", + "bytes", + "itertools 0.12.1", + "log", + "nix", + "rand 0.8.5", + "serde", + "serde_derive", + "socket2 0.5.10", + "solana-serde", + "tokio", + "url", +] + +[[package]] +name = "solana-nohash-hasher" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8a731ed60e89177c8a7ab05fe0f1511cedd3e70e773f288f9de33a9cfdc21e" + +[[package]] +name = "solana-nonce" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703e22eb185537e06204a5bd9d509b948f0066f2d1d814a6f475dafb3ddf1325" +dependencies = [ + "serde", + "serde_derive", + "solana-fee-calculator", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-nonce-account" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde971a20b8dbf60144d6a84439dda86b5466e00e2843091fe731083cda614da" +dependencies = [ + "solana-account", + "solana-hash", + "solana-nonce", + "solana-sdk-ids", +] + +[[package]] +name = "solana-offchain-message" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b526398ade5dea37f1f147ce55dae49aa017a5d7326606359b0445ca8d946581" +dependencies = [ + "num_enum", + "solana-hash", + "solana-packet", + "solana-pubkey", + "solana-sanitize", + "solana-sha256-hasher", + "solana-signature", + "solana-signer", +] + +[[package]] +name = "solana-packet" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "004f2d2daf407b3ec1a1ca5ec34b3ccdfd6866dd2d3c7d0715004a96e4b6d127" +dependencies = [ + "bincode", + "bitflags", + "cfg_eval", + "serde", + "serde_derive", + "serde_with", +] + +[[package]] +name = "solana-perf" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37192c0be5c222ca49dbc5667288c5a8bb14837051dd98e541ee4dad160a5da9" +dependencies = [ + "ahash 0.8.12", + "bincode", + "bv", + "bytes", + "caps", + "curve25519-dalek 4.1.3", + "dlopen2", + "fnv", + "libc", + "log", + "nix", + "rand 0.8.5", + "rayon", + "serde", + "solana-hash", + "solana-message", + "solana-metrics", + "solana-packet", + "solana-pubkey", + "solana-rayon-threadlimit", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-time-utils", +] + +[[package]] +name = "solana-poh-config" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d650c3b4b9060082ac6b0efbbb66865089c58405bfb45de449f3f2b91eccee75" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-poseidon" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbac4eb90016eeb1d37fa36e592d3a64421510c49666f81020736611c319faff" +dependencies = [ + "ark-bn254", + "light-poseidon", + "solana-define-syscall", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-precompile-error" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d87b2c1f5de77dfe2b175ee8dd318d196aaca4d0f66f02842f80c852811f9f8" +dependencies = [ + "num-traits", + "solana-decode-error", +] + +[[package]] +name = "solana-precompiles" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36e92768a57c652edb0f5d1b30a7d0bc64192139c517967c18600debe9ae3832" +dependencies = [ + "lazy_static", + "solana-ed25519-program", + "solana-feature-set", + "solana-message", + "solana-precompile-error", + "solana-pubkey", + "solana-sdk-ids", + "solana-secp256k1-program", + "solana-secp256r1-program", +] + +[[package]] +name = "solana-presigner" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a57a24e6a4125fc69510b6774cd93402b943191b6cddad05de7281491c90fe" +dependencies = [ + "solana-pubkey", + "solana-signature", + "solana-signer", +] + +[[package]] +name = "solana-program" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98eca145bd3545e2fbb07166e895370576e47a00a7d824e325390d33bf467210" +dependencies = [ + "bincode", + "blake3", + "borsh 0.10.4", + "borsh 1.5.7", + "bs58", + "bytemuck", + "console_error_panic_hook", + "console_log", + "getrandom 0.2.16", + "lazy_static", + "log", + "memoffset", + "num-bigint 0.4.6", + "num-derive 0.4.2", + "num-traits", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-address-lookup-table-interface", + "solana-atomic-u64", + "solana-big-mod-exp", + "solana-bincode", + "solana-blake3-hasher", + "solana-borsh", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-example-mocks", + "solana-feature-gate-interface", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-keccak-hasher", + "solana-last-restart-slot", + "solana-loader-v2-interface", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-message", + "solana-msg", + "solana-native-token", + "solana-nonce", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-secp256k1-recover", + "solana-serde-varint", + "solana-serialize-utils", + "solana-sha256-hasher", + "solana-short-vec", + "solana-slot-hashes", + "solana-slot-history", + "solana-stable-layout", + "solana-stake-interface", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", + "solana-vote-interface", + "thiserror 2.0.18", + "wasm-bindgen", +] + +[[package]] +name = "solana-program-entrypoint" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32ce041b1a0ed275290a5008ee1a4a6c48f5054c8a3d78d313c08958a06aedbd" +dependencies = [ + "solana-account-info", + "solana-msg", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "solana-program-error" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775" +dependencies = [ + "borsh 1.5.7", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-pubkey", +] + +[[package]] +name = "solana-program-memory" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a5426090c6f3fd6cfdc10685322fede9ca8e5af43cd6a59e98bfe4e91671712" +dependencies = [ + "solana-define-syscall", +] + +[[package]] +name = "solana-program-option" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc677a2e9bc616eda6dbdab834d463372b92848b2bfe4a1ed4e4b4adba3397d0" + +[[package]] +name = "solana-program-pack" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "319f0ef15e6e12dc37c597faccb7d62525a509fec5f6975ecb9419efddeb277b" +dependencies = [ + "solana-program-error", +] + +[[package]] +name = "solana-program-runtime" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5653001e07b657c9de6f0417cf9add1cf4325903732c480d415655e10cc86704" +dependencies = [ + "base64 0.22.1", + "bincode", + "enum-iterator", + "itertools 0.12.1", + "log", + "percentage", + "rand 0.8.5", + "serde", + "solana-account", + "solana-clock", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-structure", + "solana-hash", + "solana-instruction", + "solana-last-restart-slot", + "solana-log-collector", + "solana-measure", + "solana-metrics", + "solana-program-entrypoint", + "solana-pubkey", + "solana-rent", + "solana-sbpf", + "solana-sdk-ids", + "solana-slot-hashes", + "solana-stable-layout", + "solana-svm-callback", + "solana-svm-feature-set", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", + "solana-timings", + "solana-transaction-context", + "solana-type-overrides", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-program-test" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3cff7a296c11ff2f02ff391eb4b5c641d09c8eed8a7a674d235b2ccb575b9ca" +dependencies = [ + "agave-feature-set", + "assert_matches", + "async-trait", + "base64 0.22.1", + "bincode", + "chrono-humanize", + "crossbeam-channel", + "log", + "serde", + "solana-account", + "solana-account-info", + "solana-accounts-db", + "solana-banks-client", + "solana-banks-interface", + "solana-banks-server", + "solana-clock", + "solana-commitment-config", + "solana-compute-budget", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-genesis-config", + "solana-hash", + "solana-instruction", + "solana-keypair", + "solana-loader-v3-interface", + "solana-log-collector", + "solana-logger", + "solana-message", + "solana-msg", + "solana-native-token", + "solana-poh-config", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-runtime", + "solana-pubkey", + "solana-rent", + "solana-runtime", + "solana-sbpf", + "solana-sdk-ids", + "solana-signer", + "solana-stable-layout", + "solana-stake-interface", + "solana-svm", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", + "solana-timings", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "solana-vote-program", + "spl-generic-token", + "thiserror 2.0.18", + "tokio", +] + +[[package]] +name = "solana-pubkey" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.7", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "five8", + "five8_const", + "getrandom 0.2.16", + "js-sys", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-decode-error", + "solana-define-syscall", + "solana-sanitize", + "solana-sha256-hasher", + "wasm-bindgen", +] + +[[package]] +name = "solana-pubsub-client" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d18a7476e1d2e8df5093816afd8fffee94fbb6e442d9be8e6bd3e85f88ce8d5c" +dependencies = [ + "crossbeam-channel", + "futures-util", + "http 0.2.12", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder-client-types", + "solana-clock", + "solana-pubkey", + "solana-rpc-client-types", + "solana-signature", + "thiserror 2.0.18", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", +] + +[[package]] +name = "solana-quic-client" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44feb5f4a97494459c435aa56de810500cc24e22d0afc632990a8e54a07c05a4" +dependencies = [ + "async-lock", + "async-trait", + "futures", + "itertools 0.12.1", + "log", + "quinn", + "quinn-proto", + "rustls 0.23.37", + "solana-connection-cache", + "solana-keypair", + "solana-measure", + "solana-metrics", + "solana-net-utils", + "solana-pubkey", + "solana-quic-definitions", + "solana-rpc-client-api", + "solana-signer", + "solana-streamer", + "solana-tls-utils", + "solana-transaction-error", + "thiserror 2.0.18", + "tokio", +] + +[[package]] +name = "solana-quic-definitions" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf0d4d5b049eb1d0c35f7b18f305a27c8986fc5c0c9b383e97adaa35334379e" +dependencies = [ + "solana-keypair", +] + +[[package]] +name = "solana-rayon-threadlimit" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02cc2a4cae3ef7bb6346b35a60756d2622c297d5fa204f96731db9194c0dc75b" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "solana-rent" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1aea8fdea9de98ca6e8c2da5827707fb3842833521b528a713810ca685d2480" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-rent-collector" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "127e6dfa51e8c8ae3aa646d8b2672bc4ac901972a338a9e1cd249e030564fb9d" +dependencies = [ + "serde", + "serde_derive", + "solana-account", + "solana-clock", + "solana-epoch-schedule", + "solana-genesis-config", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", +] + +[[package]] +name = "solana-rent-debits" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f6f9113c6003492e74438d1288e30cffa8ccfdc2ef7b49b9e816d8034da18cd" +dependencies = [ + "solana-pubkey", + "solana-reward-info", +] + +[[package]] +name = "solana-reserved-account-keys" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4b22ea19ca2a3f28af7cd047c914abf833486bf7a7c4a10fc652fff09b385b1" +dependencies = [ + "lazy_static", + "solana-feature-set", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-reward-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18205b69139b1ae0ab8f6e11cdcb627328c0814422ad2482000fa2ca54ae4a2f" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-rpc-client" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8d3161ac0918178e674c1f7f1bfac40de3e7ed0383bd65747d63113c156eaeb" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bincode", + "bs58", + "futures", + "indicatif", + "log", + "reqwest", + "reqwest-middleware", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account", + "solana-account-decoder-client-types", + "solana-clock", + "solana-commitment-config", + "solana-epoch-info", + "solana-epoch-schedule", + "solana-feature-gate-interface", + "solana-hash", + "solana-instruction", + "solana-message", + "solana-pubkey", + "solana-rpc-client-api", + "solana-signature", + "solana-transaction", + "solana-transaction-error", + "solana-transaction-status-client-types", + "solana-version", + "solana-vote-interface", + "tokio", +] + +[[package]] +name = "solana-rpc-client-api" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dbc138685c79d88a766a8fd825057a74ea7a21e1dd7f8de275ada899540fff7" +dependencies = [ + "anyhow", + "jsonrpc-core", + "reqwest", + "reqwest-middleware", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder-client-types", + "solana-clock", + "solana-rpc-client-types", + "solana-signer", + "solana-transaction-error", + "solana-transaction-status-client-types", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-rpc-client-nonce-utils" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f0ee41b9894ff36adebe546a110b899b0d0294b07845d8acdc73822e6af4b0" +dependencies = [ + "solana-account", + "solana-commitment-config", + "solana-hash", + "solana-message", + "solana-nonce", + "solana-pubkey", + "solana-rpc-client", + "solana-sdk-ids", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-rpc-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea428a81729255d895ea47fba9b30fd4dacbfe571a080448121bd0592751676" +dependencies = [ + "base64 0.22.1", + "bs58", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account", + "solana-account-decoder-client-types", + "solana-clock", + "solana-commitment-config", + "solana-fee-calculator", + "solana-inflation", + "solana-pubkey", + "solana-transaction-error", + "solana-transaction-status-client-types", + "solana-version", + "spl-generic-token", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-runtime" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a3f83d5af95937504ec3447415b13ca5f1326cad3c3f790f2c66ee2153f0919" +dependencies = [ + "agave-feature-set", + "agave-precompiles", + "agave-reserved-account-keys", + "ahash 0.8.12", + "aquamarine", + "arrayref", + "assert_matches", + "base64 0.22.1", + "bincode", + "blake3", + "bv", + "bytemuck", + "bzip2", + "crossbeam-channel", + "dashmap", + "dir-diff", + "flate2", + "fnv", + "im", + "itertools 0.12.1", + "libc", + "log", + "lz4", + "memmap2 0.9.10", + "mockall", + "modular-bitfield", + "num-derive 0.4.2", + "num-traits", + "num_cpus", + "num_enum", + "percentage", + "qualifier_attr", + "rand 0.8.5", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "serde_with", + "solana-account", + "solana-account-info", + "solana-accounts-db", + "solana-address-lookup-table-interface", + "solana-bpf-loader-program", + "solana-bucket-map", + "solana-builtins", + "solana-client-traits", + "solana-clock", + "solana-commitment-config", + "solana-compute-budget", + "solana-compute-budget-instruction", + "solana-compute-budget-interface", + "solana-cost-model", + "solana-cpi", + "solana-ed25519-program", + "solana-epoch-info", + "solana-epoch-rewards-hasher", + "solana-epoch-schedule", + "solana-feature-gate-interface", + "solana-fee", + "solana-fee-calculator", + "solana-fee-structure", + "solana-genesis-config", + "solana-hard-forks", + "solana-hash", + "solana-inflation", + "solana-instruction", + "solana-keypair", + "solana-lattice-hash", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-measure", + "solana-message", + "solana-metrics", + "solana-native-token", + "solana-nohash-hasher", + "solana-nonce", + "solana-nonce-account", + "solana-packet", + "solana-perf", + "solana-poh-config", + "solana-precompile-error", + "solana-program-runtime", + "solana-pubkey", + "solana-rayon-threadlimit", + "solana-rent", + "solana-rent-collector", + "solana-rent-debits", + "solana-reward-info", + "solana-runtime-transaction", + "solana-sdk-ids", + "solana-secp256k1-program", + "solana-seed-derivable", + "solana-serde", + "solana-sha256-hasher", + "solana-signature", + "solana-signer", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface", + "solana-stake-program", + "solana-svm", + "solana-svm-callback", + "solana-svm-rent-collector", + "solana-svm-transaction", + "solana-system-interface", + "solana-system-transaction", + "solana-sysvar", + "solana-sysvar-id", + "solana-time-utils", + "solana-timings", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "solana-transaction-status-client-types", + "solana-unified-scheduler-logic", + "solana-version", + "solana-vote", + "solana-vote-interface", + "solana-vote-program", + "spl-generic-token", + "static_assertions", + "strum", + "strum_macros", + "symlink", + "tar", + "tempfile", + "thiserror 2.0.18", + "zstd", +] + +[[package]] +name = "solana-runtime-transaction" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca52090550885453ac7a26a0fd7d6ffe057dd1d52c350cde17887b004a0ddcd0" +dependencies = [ + "agave-transaction-view", + "log", + "solana-compute-budget", + "solana-compute-budget-instruction", + "solana-hash", + "solana-message", + "solana-pubkey", + "solana-sdk-ids", + "solana-signature", + "solana-svm-transaction", + "solana-transaction", + "solana-transaction-error", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-sanitize" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf" + +[[package]] +name = "solana-sbpf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "474a2d95dc819898ded08d24f29642d02189d3e1497bbb442a92a3997b7eb55f" +dependencies = [ + "byteorder", + "combine 3.8.1", + "hash32", + "libc", + "log", + "rand 0.8.5", + "rustc-demangle", + "thiserror 2.0.18", + "winapi", +] + +[[package]] +name = "solana-sdk" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cc0e4a7635b902791c44b6581bfb82f3ada32c5bc0929a64f39fe4bb384c86a" +dependencies = [ + "bincode", + "bs58", + "getrandom 0.1.16", + "js-sys", + "serde", + "serde_json", + "solana-account", + "solana-bn254", + "solana-client-traits", + "solana-cluster-type", + "solana-commitment-config", + "solana-compute-budget-interface", + "solana-decode-error", + "solana-derivation-path", + "solana-ed25519-program", + "solana-epoch-info", + "solana-epoch-rewards-hasher", + "solana-feature-set", + "solana-fee-structure", + "solana-genesis-config", + "solana-hard-forks", + "solana-inflation", + "solana-instruction", + "solana-keypair", + "solana-message", + "solana-native-token", + "solana-nonce-account", + "solana-offchain-message", + "solana-packet", + "solana-poh-config", + "solana-precompile-error", + "solana-precompiles", + "solana-presigner", + "solana-program", + "solana-program-memory", + "solana-pubkey", + "solana-quic-definitions", + "solana-rent-collector", + "solana-rent-debits", + "solana-reserved-account-keys", + "solana-reward-info", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-secp256k1-program", + "solana-secp256k1-recover", + "solana-secp256r1-program", + "solana-seed-derivable", + "solana-seed-phrase", + "solana-serde", + "solana-serde-varint", + "solana-short-vec", + "solana-shred-version", + "solana-signature", + "solana-signer", + "solana-system-transaction", + "solana-time-utils", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "solana-validator-exit", + "thiserror 2.0.18", + "wasm-bindgen", +] + +[[package]] +name = "solana-sdk-ids" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5d8b9cc68d5c88b062a33e23a6466722467dde0035152d8fb1afbcdf350a5f" +dependencies = [ + "solana-pubkey", +] + +[[package]] +name = "solana-sdk-macro" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86280da8b99d03560f6ab5aca9de2e38805681df34e0bb8f238e69b29433b9df" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "solana-secp256k1-program" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f19833e4bc21558fe9ec61f239553abe7d05224347b57d65c2218aeeb82d6149" +dependencies = [ + "bincode", + "digest 0.10.7", + "libsecp256k1", + "serde", + "serde_derive", + "sha3", + "solana-feature-set", + "solana-instruction", + "solana-precompile-error", + "solana-sdk-ids", + "solana-signature", +] + +[[package]] +name = "solana-secp256k1-recover" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa3120b6cdaa270f39444f5093a90a7b03d296d362878f7a6991d6de3bbe496" +dependencies = [ + "borsh 1.5.7", + "libsecp256k1", + "solana-define-syscall", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-secp256r1-program" +version = "2.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce0ae46da3071a900f02d367d99b2f3058fe2e90c5062ac50c4f20cfedad8f0f" +dependencies = [ + "bytemuck", + "openssl", + "solana-feature-set", + "solana-instruction", + "solana-precompile-error", + "solana-sdk-ids", +] + +[[package]] +name = "solana-seed-derivable" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beb82b5adb266c6ea90e5cf3967235644848eac476c5a1f2f9283a143b7c97f" +dependencies = [ + "solana-derivation-path", +] + +[[package]] +name = "solana-seed-phrase" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36187af2324f079f65a675ec22b31c24919cb4ac22c79472e85d819db9bbbc15" +dependencies = [ + "hmac 0.12.1", + "pbkdf2", + "sha2 0.10.9", +] + +[[package]] +name = "solana-send-transaction-service" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f838b10e5b35e68987de6b2dfec19a3ba9d48509f26110c3d738125e07d2e915" +dependencies = [ + "async-trait", + "crossbeam-channel", + "itertools 0.12.1", + "log", + "solana-client", + "solana-clock", + "solana-connection-cache", + "solana-hash", + "solana-keypair", + "solana-measure", + "solana-metrics", + "solana-nonce-account", + "solana-pubkey", + "solana-quic-definitions", + "solana-runtime", + "solana-signature", + "solana-time-utils", + "solana-tpu-client-next", + "tokio", + "tokio-util 0.7.17", +] + +[[package]] +name = "solana-serde" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1931484a408af466e14171556a47adaa215953c7f48b24e5f6b0282763818b04" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serde-varint" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a7e155eba458ecfb0107b98236088c3764a09ddf0201ec29e52a0be40857113" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serialize-utils" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "817a284b63197d2b27afdba829c5ab34231da4a9b4e763466a003c40ca4f535e" +dependencies = [ + "solana-instruction", + "solana-pubkey", + "solana-sanitize", +] + +[[package]] +name = "solana-sha256-hasher" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa3feb32c28765f6aa1ce8f3feac30936f16c5c3f7eb73d63a5b8f6f8ecdc44" +dependencies = [ "sha2 0.10.9", - "solana-frozen-abi-macro", - "subtle", - "thiserror", + "solana-define-syscall", + "solana-hash", ] [[package]] -name = "solana-frozen-abi-macro" -version = "1.18.26" +name = "solana-short-vec" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c142f779c3633ac83c84d04ff06c70e1f558c876f13358bed77ba629c7417932" +checksum = "5c54c66f19b9766a56fa0057d060de8378676cb64987533fa088861858fc5a69" dependencies = [ - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.110", + "serde", ] [[package]] -name = "solana-logger" -version = "1.18.26" +name = "solana-shred-version" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121d36ffb3c6b958763312cbc697fbccba46ee837d3a0aa4fc0e90fcb3b884f3" +checksum = "afd3db0461089d1ad1a78d9ba3f15b563899ca2386351d38428faa5350c60a98" dependencies = [ - "env_logger", - "lazy_static", - "log", + "solana-hard-forks", + "solana-hash", + "solana-sha256-hasher", ] [[package]] -name = "solana-measure" -version = "1.18.26" +name = "solana-signature" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c01a7f9cdc9d9d37a3d5651b2fe7ec9d433c2a3470b9f35897e373b421f0737" +checksum = "64c8ec8e657aecfc187522fc67495142c12f35e55ddeca8698edbb738b8dbd8c" dependencies = [ - "log", - "solana-sdk", + "ed25519-dalek", + "five8", + "rand 0.8.5", + "serde", + "serde-big-array", + "serde_derive", + "solana-sanitize", ] [[package]] -name = "solana-metrics" -version = "1.18.26" +name = "solana-signer" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e36052aff6be1536bdf6f737c6e69aca9dbb6a2f3f582e14ecb0ddc0cd66ce" +checksum = "7c41991508a4b02f021c1342ba00bcfa098630b213726ceadc7cb032e051975b" dependencies = [ - "crossbeam-channel", - "gethostname", - "lazy_static", - "log", - "reqwest", - "solana-sdk", - "thiserror", + "solana-pubkey", + "solana-signature", + "solana-transaction-error", ] [[package]] -name = "solana-net-utils" -version = "1.18.26" +name = "solana-slot-hashes" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a1f5c6be9c5b272866673741e1ebc64b2ea2118e5c6301babbce526fdfb15f4" +checksum = "0c8691982114513763e88d04094c9caa0376b867a29577939011331134c301ce" dependencies = [ - "bincode", - "clap 3.2.25", - "crossbeam-channel", - "log", - "nix", - "rand 0.8.5", "serde", "serde_derive", - "socket2 0.5.10", - "solana-logger", - "solana-sdk", - "solana-version", - "tokio", - "url", + "solana-hash", + "solana-sdk-ids", + "solana-sysvar-id", ] [[package]] -name = "solana-perf" -version = "1.18.26" +name = "solana-slot-history" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28acaf22477566a0fbddd67249ea5d859b39bacdb624aff3fadd3c5745e2643c" +checksum = "97ccc1b2067ca22754d5283afb2b0126d61eae734fc616d23871b0943b0d935e" dependencies = [ - "ahash 0.8.12", - "bincode", "bv", - "caps", - "curve25519-dalek", - "dlopen2", - "fnv", - "lazy_static", - "libc", - "log", - "nix", - "rand 0.8.5", - "rayon", - "rustc_version", "serde", - "solana-frozen-abi", - "solana-frozen-abi-macro", - "solana-metrics", - "solana-rayon-threadlimit", - "solana-sdk", - "solana-vote-program", + "serde_derive", + "solana-sdk-ids", + "solana-sysvar-id", ] [[package]] -name = "solana-program" -version = "1.18.26" +name = "solana-stable-layout" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c10f4588cefd716b24a1a40dd32c278e43a560ab8ce4de6b5805c9d113afdfa1" +checksum = "9f14f7d02af8f2bc1b5efeeae71bc1c2b7f0f65cd75bcc7d8180f2c762a57f54" dependencies = [ - "ark-bn254", - "ark-ec", - "ark-ff", - "ark-serialize", - "base64 0.21.7", - "bincode", - "bitflags 2.10.0", - "blake3", - "borsh 0.10.4", - "borsh 0.9.3", - "borsh 1.5.7", - "bs58 0.4.0", - "bv", - "bytemuck", - "cc", - "console_error_panic_hook", - "console_log", - "curve25519-dalek", - "getrandom 0.2.16", - "itertools", - "js-sys", - "lazy_static", - "libc", - "libsecp256k1", - "light-poseidon", - "log", - "memoffset 0.9.1", - "num-bigint 0.4.6", - "num-derive 0.4.2", - "num-traits", - "parking_lot", - "rand 0.8.5", - "rustc_version", - "rustversion", - "serde", - "serde_bytes", - "serde_derive", - "serde_json", - "sha2 0.10.9", - "sha3 0.10.8", - "solana-frozen-abi", - "solana-frozen-abi-macro", - "solana-sdk-macro", - "thiserror", - "tiny-bip39", - "wasm-bindgen", - "zeroize", + "solana-instruction", + "solana-pubkey", ] [[package]] -name = "solana-program-runtime" -version = "1.18.26" +name = "solana-stake-interface" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf0c3eab2a80f514289af1f422c121defb030937643c43b117959d6f1932fb5" +checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" dependencies = [ - "base64 0.21.7", - "bincode", - "eager", - "enum-iterator", - "itertools", - "libc", - "log", - "num-derive 0.4.2", + "borsh 0.10.4", + "borsh 1.5.7", "num-traits", - "percentage", - "rand 0.8.5", - "rustc_version", "serde", - "solana-frozen-abi", - "solana-frozen-abi-macro", - "solana-measure", - "solana-metrics", - "solana-sdk", - "solana_rbpf", - "thiserror", + "serde_derive", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-system-interface", + "solana-sysvar-id", ] [[package]] -name = "solana-pubsub-client" -version = "1.18.26" +name = "solana-stake-program" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b064e76909d33821b80fdd826e6757251934a52958220c92639f634bea90366d" +checksum = "500e9b9d11573f12de91e94f9c4459882cd5ffc692776af49b610d6fcc0b167f" dependencies = [ - "crossbeam-channel", - "futures-util", + "agave-feature-set", + "bincode", "log", - "reqwest", - "semver", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder", - "solana-rpc-client-api", - "solana-sdk", - "thiserror", - "tokio", - "tokio-stream", - "tokio-tungstenite", - "tungstenite", - "url", + "solana-account", + "solana-bincode", + "solana-clock", + "solana-config-program-client", + "solana-genesis-config", + "solana-instruction", + "solana-log-collector", + "solana-native-token", + "solana-packet", + "solana-program-runtime", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-stake-interface", + "solana-sysvar", + "solana-transaction-context", + "solana-type-overrides", + "solana-vote-interface", ] [[package]] -name = "solana-quic-client" -version = "1.18.26" +name = "solana-streamer" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a90e40ee593f6e9ddd722d296df56743514ae804975a76d47e7afed4e3da244" +checksum = "5643516e5206b89dd4bdf67c39815606d835a51a13260e43349abdb92d241b1d" dependencies = [ - "async-mutex", - "async-trait", + "async-channel", + "bytes", + "crossbeam-channel", + "dashmap", "futures", - "itertools", - "lazy_static", + "futures-util", + "governor", + "histogram", + "indexmap", + "itertools 0.12.1", + "libc", "log", + "nix", + "pem", + "percentage", "quinn", "quinn-proto", - "rcgen", - "rustls", - "solana-connection-cache", + "rand 0.8.5", + "rustls 0.23.37", + "smallvec", + "socket2 0.5.10", + "solana-keypair", "solana-measure", "solana-metrics", "solana-net-utils", - "solana-rpc-client-api", - "solana-sdk", - "solana-streamer", - "thiserror", + "solana-packet", + "solana-perf", + "solana-pubkey", + "solana-quic-definitions", + "solana-signature", + "solana-signer", + "solana-time-utils", + "solana-tls-utils", + "solana-transaction-error", + "solana-transaction-metrics-tracker", + "thiserror 2.0.18", "tokio", + "tokio-util 0.7.17", + "x509-parser", ] [[package]] -name = "solana-rayon-threadlimit" -version = "1.18.26" +name = "solana-svm" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66468f9c014992167de10cc68aad6ac8919a8c8ff428dc88c0d2b4da8c02b8b7" +checksum = "006180b920e8d8c1dab4f6a0fda248b5b97d912eda4c872534d178bc31231bec" dependencies = [ - "lazy_static", - "num_cpus", + "ahash 0.8.12", + "log", + "percentage", + "serde", + "serde_derive", + "solana-account", + "solana-clock", + "solana-fee-structure", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-loader-v4-program", + "solana-log-collector", + "solana-measure", + "solana-message", + "solana-nonce", + "solana-nonce-account", + "solana-program-entrypoint", + "solana-program-pack", + "solana-program-runtime", + "solana-pubkey", + "solana-rent", + "solana-rent-collector", + "solana-rent-debits", + "solana-sdk-ids", + "solana-svm-callback", + "solana-svm-feature-set", + "solana-svm-rent-collector", + "solana-svm-transaction", + "solana-system-interface", + "solana-sysvar-id", + "solana-timings", + "solana-transaction-context", + "solana-transaction-error", + "solana-type-overrides", + "spl-generic-token", + "thiserror 2.0.18", ] [[package]] -name = "solana-remote-wallet" -version = "1.18.26" +name = "solana-svm-callback" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c191019f4d4f84281a6d0dd9a43181146b33019627fc394e42e08ade8976b431" +checksum = "7cef9f7d5cfb5d375081a6c8ad712a6f0e055a15890081f845acf55d8254a7a2" dependencies = [ - "console", - "dialoguer", - "log", - "num-derive 0.4.2", - "num-traits", - "parking_lot", - "qstring", - "semver", - "solana-sdk", - "thiserror", - "uriparse", + "solana-account", + "solana-precompile-error", + "solana-pubkey", ] [[package]] -name = "solana-rpc-client" -version = "1.18.26" +name = "solana-svm-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f24b836eb4d74ec255217bdbe0f24f64a07adeac31aca61f334f91cd4a3b1d5" + +[[package]] +name = "solana-svm-rent-collector" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ed4628e338077c195ddbf790693d410123d17dec0a319b5accb4aaee3fb15c" +checksum = "030200d7f3ce4879f9d8c980ceb9e1d5e9a302866db035776496069b20c427b4" dependencies = [ - "async-trait", - "base64 0.21.7", - "bincode", - "bs58 0.4.0", - "indicatif", - "log", - "reqwest", - "semver", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder", - "solana-rpc-client-api", - "solana-sdk", - "solana-transaction-status", - "solana-version", - "solana-vote-program", - "tokio", + "solana-account", + "solana-clock", + "solana-pubkey", + "solana-rent", + "solana-rent-collector", + "solana-sdk-ids", + "solana-transaction-context", + "solana-transaction-error", ] [[package]] -name = "solana-rpc-client-api" -version = "1.18.26" +name = "solana-svm-transaction" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c913551faa4a1ae4bbfef6af19f3a5cf847285c05b4409e37c8993b3444229" +checksum = "ab717b9539375ebb088872c6c87d1d8832d19f30f154ecc530154d23f60a6f0c" dependencies = [ - "base64 0.21.7", - "bs58 0.4.0", - "jsonrpc-core", - "reqwest", - "semver", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder", - "solana-sdk", - "solana-transaction-status", - "solana-version", - "spl-token-2022 1.0.0", - "thiserror", + "solana-hash", + "solana-message", + "solana-pubkey", + "solana-sdk-ids", + "solana-signature", + "solana-transaction", ] [[package]] -name = "solana-rpc-client-nonce-utils" -version = "1.18.26" +name = "solana-system-interface" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a47b6bb1834e6141a799db62bbdcf80d17a7d58d7bc1684c614e01a7293d7cf" +checksum = "94d7c18cb1a91c6be5f5a8ac9276a1d7c737e39a21beba9ea710ab4b9c63bc90" dependencies = [ - "clap 2.34.0", - "solana-clap-utils", - "solana-rpc-client", - "solana-sdk", - "thiserror", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-pubkey", + "wasm-bindgen", ] [[package]] -name = "solana-sdk" -version = "1.18.26" +name = "solana-system-program" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "580ad66c2f7a4c3cb3244fe21440546bd500f5ecb955ad9826e92a78dded8009" +checksum = "23ca36cef39aea7761be58d4108a56a2e27042fb1e913355fdb142a05fc7eab7" dependencies = [ - "assert_matches", - "base64 0.21.7", "bincode", - "bitflags 2.10.0", - "borsh 1.5.7", - "bs58 0.4.0", - "bytemuck", - "byteorder", - "chrono", - "derivation-path", - "digest 0.10.7", - "ed25519-dalek", - "ed25519-dalek-bip32", - "generic-array", - "hmac 0.12.1", - "itertools", - "js-sys", - "lazy_static", - "libsecp256k1", "log", - "memmap2", - "num-derive 0.4.2", - "num-traits", - "num_enum 0.7.5", - "pbkdf2 0.11.0", - "qstring", - "qualifier_attr", - "rand 0.7.3", - "rand 0.8.5", - "rustc_version", - "rustversion", "serde", - "serde_bytes", "serde_derive", - "serde_json", - "serde_with", - "sha2 0.10.9", - "sha3 0.10.8", - "siphasher", - "solana-frozen-abi", - "solana-frozen-abi-macro", - "solana-logger", - "solana-program", - "solana-sdk-macro", - "thiserror", - "uriparse", - "wasm-bindgen", + "solana-account", + "solana-bincode", + "solana-fee-calculator", + "solana-instruction", + "solana-log-collector", + "solana-nonce", + "solana-nonce-account", + "solana-packet", + "solana-program-runtime", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", + "solana-sysvar", + "solana-transaction-context", + "solana-type-overrides", ] [[package]] -name = "solana-sdk-macro" -version = "1.18.26" +name = "solana-system-transaction" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b75d0f193a27719257af19144fdaebec0415d1c9e9226ae4bd29b791be5e9bd" +checksum = "5bd98a25e5bcba8b6be8bcbb7b84b24c2a6a8178d7fb0e3077a916855ceba91a" dependencies = [ - "bs58 0.4.0", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.110", + "solana-hash", + "solana-keypair", + "solana-message", + "solana-pubkey", + "solana-signer", + "solana-system-interface", + "solana-transaction", ] [[package]] -name = "solana-security-txt" -version = "1.1.2" +name = "solana-sysvar" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "156bb61a96c605fa124e052d630dba2f6fb57e08c7d15b757e1e958b3ed7b3fe" +checksum = "b8c3595f95069f3d90f275bb9bd235a1973c4d059028b0a7f81baca2703815db" dependencies = [ - "hashbrown 0.15.2", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-last-restart-slot", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface", + "solana-sysvar-id", ] [[package]] -name = "solana-streamer" -version = "1.18.26" +name = "solana-sysvar-id" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8476e41ad94fe492e8c06697ee35912cf3080aae0c9e9ac6430835256ccf056" +checksum = "5762b273d3325b047cfda250787f8d796d781746860d5d0a746ee29f3e8812c1" dependencies = [ - "async-channel", - "bytes", - "crossbeam-channel", - "futures-util", - "histogram", - "indexmap 2.12.1", - "itertools", - "libc", - "log", - "nix", - "pem", - "percentage", - "pkcs8", - "quinn", - "quinn-proto", - "rand 0.8.5", - "rcgen", - "rustls", - "smallvec", - "solana-metrics", - "solana-perf", - "solana-sdk", - "thiserror", - "tokio", - "x509-parser", + "solana-pubkey", + "solana-sdk-ids", ] [[package]] name = "solana-thin-client" -version = "1.18.26" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c02245d0d232430e79dc0d624aa42d50006097c3aec99ac82ac299eaa3a73f" +checksum = "6c1025715a113e0e2e379b30a6bfe4455770dc0759dabf93f7dbd16646d5acbe" dependencies = [ "bincode", "log", "rayon", + "solana-account", + "solana-client-traits", + "solana-clock", + "solana-commitment-config", "solana-connection-cache", + "solana-epoch-info", + "solana-hash", + "solana-instruction", + "solana-keypair", + "solana-message", + "solana-pubkey", "solana-rpc-client", "solana-rpc-client-api", - "solana-sdk", + "solana-signature", + "solana-signer", + "solana-system-interface", + "solana-transaction", + "solana-transaction-error", +] + +[[package]] +name = "solana-time-utils" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af261afb0e8c39252a04d026e3ea9c405342b08c871a2ad8aa5448e068c784c" + +[[package]] +name = "solana-timings" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c49b842dfc53c1bf9007eaa6730296dea93b4fce73f457ce1080af43375c0d6" +dependencies = [ + "eager", + "enum-iterator", + "solana-pubkey", +] + +[[package]] +name = "solana-tls-utils" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14494aa87a75a883d1abcfee00f1278a28ecc594a2f030084879eb40570728f6" +dependencies = [ + "rustls 0.23.37", + "solana-keypair", + "solana-pubkey", + "solana-signer", + "x509-parser", ] [[package]] name = "solana-tpu-client" -version = "1.18.26" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67251506ed03de15f1347b46636b45c47da6be75015b4a13f0620b21beb00566" +checksum = "17895ce70fd1dd93add3fbac87d599954ded93c63fa1c66f702d278d96a6da14" dependencies = [ "async-trait", "bincode", "futures-util", - "indexmap 2.12.1", + "indexmap", "indicatif", "log", "rayon", + "solana-client-traits", + "solana-clock", + "solana-commitment-config", "solana-connection-cache", + "solana-epoch-schedule", "solana-measure", - "solana-metrics", + "solana-message", + "solana-net-utils", + "solana-pubkey", "solana-pubsub-client", + "solana-quic-definitions", "solana-rpc-client", "solana-rpc-client-api", - "solana-sdk", - "thiserror", + "solana-signature", + "solana-signer", + "solana-transaction", + "solana-transaction-error", + "thiserror 2.0.18", "tokio", ] [[package]] -name = "solana-transaction-status" -version = "1.18.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3d36db1b2ab2801afd5482aad9fb15ed7959f774c81a77299fdd0ddcf839d4" -dependencies = [ - "Inflector", - "base64 0.21.7", - "bincode", - "borsh 0.10.4", - "bs58 0.4.0", - "lazy_static", - "log", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder", - "solana-sdk", - "spl-associated-token-account", - "spl-memo", - "spl-token", - "spl-token-2022 1.0.0", - "thiserror", -] - -[[package]] -name = "solana-udp-client" -version = "1.18.26" +name = "solana-tpu-client-next" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a754a3c2265eb02e0c35aeaca96643951f03cee6b376afe12e0cf8860ffccd1" +checksum = "418739a37f0c1806c4e273d7705103e53c74b423fc13044a99d9f7884524ae02" dependencies = [ "async-trait", + "log", + "lru", + "quinn", + "rustls 0.23.37", + "solana-clock", "solana-connection-cache", - "solana-net-utils", - "solana-sdk", + "solana-keypair", + "solana-measure", + "solana-metrics", + "solana-quic-definitions", + "solana-rpc-client", "solana-streamer", - "thiserror", + "solana-time-utils", + "solana-tls-utils", + "solana-tpu-client", + "thiserror 2.0.18", "tokio", + "tokio-util 0.7.17", ] [[package]] -name = "solana-version" -version = "1.18.26" +name = "solana-transaction" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f44776bd685cc02e67ba264384acc12ef2931d01d1a9f851cb8cdbd3ce455b9e" +checksum = "80657d6088f721148f5d889c828ca60c7daeedac9a8679f9ec215e0c42bcbf41" dependencies = [ - "log", - "rustc_version", - "semver", + "bincode", "serde", "serde_derive", - "solana-frozen-abi", - "solana-frozen-abi-macro", - "solana-sdk", + "solana-bincode", + "solana-feature-set", + "solana-hash", + "solana-instruction", + "solana-keypair", + "solana-message", + "solana-precompiles", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-signer", + "solana-system-interface", + "solana-transaction-error", + "wasm-bindgen", ] [[package]] -name = "solana-vote-program" -version = "1.18.26" +name = "solana-transaction-context" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25810970c91feb579bd3f67dca215fce971522e42bfd59696af89c5dfebd997c" +checksum = "54a312304361987a85b2ef2293920558e6612876a639dd1309daf6d0d59ef2fe" dependencies = [ "bincode", - "log", - "num-derive 0.4.2", - "num-traits", - "rustc_version", "serde", "serde_derive", - "solana-frozen-abi", - "solana-frozen-abi-macro", - "solana-metrics", - "solana-program", - "solana-program-runtime", - "solana-sdk", - "thiserror", + "solana-account", + "solana-instruction", + "solana-instructions-sysvar", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", ] [[package]] -name = "solana-zk-token-sdk" -version = "1.18.26" +name = "solana-transaction-error" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cbdf4249b6dfcbba7d84e2b53313698043f60f8e22ce48286e6fbe8a17c8d16" +checksum = "222a9dc8fdb61c6088baab34fc3a8b8473a03a7a5fd404ed8dd502fa79b67cb1" dependencies = [ - "aes-gcm-siv", - "base64 0.21.7", - "bincode", - "bytemuck", - "byteorder", - "curve25519-dalek", - "getrandom 0.1.16", - "itertools", - "lazy_static", - "merlin", - "num-derive 0.4.2", - "num-traits", - "rand 0.7.3", "serde", - "serde_json", - "sha3 0.9.1", - "solana-program", - "solana-sdk", - "subtle", - "thiserror", - "zeroize", + "serde_derive", + "solana-instruction", + "solana-sanitize", ] [[package]] -name = "solana_rbpf" -version = "0.8.3" +name = "solana-transaction-metrics-tracker" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da5d083187e3b3f453e140f292c09186881da8a02a7b5e27f645ee26de3d9cc5" +checksum = "03fc4e1b6252dc724f5ee69db6229feb43070b7318651580d2174da8baefb993" dependencies = [ - "byteorder", - "combine", - "goblin", - "hash32", - "libc", + "base64 0.22.1", + "bincode", "log", "rand 0.8.5", - "rustc-demangle", - "scroll", - "thiserror", - "winapi", + "solana-packet", + "solana-perf", + "solana-short-vec", + "solana-signature", ] [[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spki" -version = "0.5.4" +name = "solana-transaction-status-client-types" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "51f1d7c2387c35850848212244d2b225847666cb52d3bd59a5c409d2c300303d" dependencies = [ - "base64ct", - "der", + "base64 0.22.1", + "bincode", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder-client-types", + "solana-commitment-config", + "solana-message", + "solana-reward-info", + "solana-signature", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "thiserror 2.0.18", ] [[package]] -name = "spl-associated-token-account" -version = "2.3.0" +name = "solana-type-overrides" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "992d9c64c2564cc8f63a4b508bf3ebcdf2254b0429b13cd1d31adb6162432a5f" +checksum = "41d80c44761eb398a157d809a04840865c347e1831ae3859b6100c0ee457bc1a" dependencies = [ - "assert_matches", - "borsh 0.10.4", - "num-derive 0.4.2", - "num-traits", - "solana-program", - "spl-token", - "spl-token-2022 1.0.0", - "thiserror", + "rand 0.8.5", ] [[package]] -name = "spl-discriminator" -version = "0.1.0" +name = "solana-udp-client" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" +checksum = "2dd36227dd3035ac09a89d4239551d2e3d7d9b177b61ccc7c6d393c3974d0efa" dependencies = [ - "bytemuck", - "solana-program", - "spl-discriminator-derive", + "async-trait", + "solana-connection-cache", + "solana-keypair", + "solana-net-utils", + "solana-streamer", + "solana-transaction-error", + "thiserror 2.0.18", + "tokio", ] [[package]] -name = "spl-discriminator-derive" -version = "0.1.2" +name = "solana-unified-scheduler-logic" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" +checksum = "ca8d0560b66257004b5a3497b2b8a09486035a742b888ed4eca0efa9211c932a" dependencies = [ - "quote", - "spl-discriminator-syn", - "syn 2.0.110", + "assert_matches", + "solana-pubkey", + "solana-runtime-transaction", + "solana-transaction", + "static_assertions", + "unwrap_none", ] [[package]] -name = "spl-discriminator-syn" -version = "0.1.2" +name = "solana-validator-exit" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fea7be851bd98d10721782ea958097c03a0c2a07d8d4997041d0ece6319a63" -dependencies = [ - "proc-macro2", - "quote", - "sha2 0.10.9", - "syn 2.0.110", - "thiserror", -] +checksum = "7bbf6d7a3c0b28dd5335c52c0e9eae49d0ae489a8f324917faf0ded65a812c1d" [[package]] -name = "spl-memo" -version = "4.0.0" +name = "solana-version" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" +checksum = "3324d46c7f7b7f5d34bf7dc71a2883bdc072c7b28ca81d0b2167ecec4cf8da9f" dependencies = [ - "solana-program", + "agave-feature-set", + "rand 0.8.5", + "semver", + "serde", + "serde_derive", + "solana-sanitize", + "solana-serde-varint", ] [[package]] -name = "spl-pod" -version = "0.1.0" +name = "solana-vote" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" +checksum = "67f9f6132f699605e11df62631ae4861b21cb2d99f0fca1b852d277c982107f9" dependencies = [ - "borsh 0.10.4", - "bytemuck", - "solana-program", - "solana-zk-token-sdk", - "spl-program-error", -] - -[[package]] -name = "spl-program-error" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" + "itertools 0.12.1", + "log", + "serde", + "serde_derive", + "solana-account", + "solana-bincode", + "solana-clock", + "solana-hash", + "solana-instruction", + "solana-keypair", + "solana-packet", + "solana-pubkey", + "solana-sdk-ids", + "solana-serialize-utils", + "solana-signature", + "solana-signer", + "solana-svm-transaction", + "solana-transaction", + "solana-vote-interface", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-vote-interface" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b80d57478d6599d30acc31cc5ae7f93ec2361a06aefe8ea79bc81739a08af4c3" dependencies = [ + "bincode", "num-derive 0.4.2", "num-traits", - "solana-program", - "spl-program-error-derive", - "thiserror", -] - -[[package]] -name = "spl-program-error-derive" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1845dfe71fd68f70382232742e758557afe973ae19e6c06807b2c30f5d5cb474" -dependencies = [ - "proc-macro2", - "quote", - "sha2 0.10.9", - "syn 2.0.110", -] - -[[package]] -name = "spl-tlv-account-resolution" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9" -dependencies = [ - "bytemuck", - "solana-program", - "spl-discriminator", - "spl-pod", - "spl-program-error", - "spl-type-length-value", + "serde", + "serde_derive", + "solana-clock", + "solana-decode-error", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-serde-varint", + "solana-serialize-utils", + "solana-short-vec", + "solana-system-interface", ] [[package]] -name = "spl-tlv-account-resolution" -version = "0.5.1" +name = "solana-vote-program" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "615d381f48ddd2bb3c57c7f7fb207591a2a05054639b18a62e785117dd7a8683" +checksum = "908d0e72c8b83e48762eb3e8c9114497cf4b1d66e506e360c46aba9308e71299" dependencies = [ - "bytemuck", - "solana-program", - "spl-discriminator", - "spl-pod", - "spl-program-error", - "spl-type-length-value", + "agave-feature-set", + "bincode", + "log", + "num-derive 0.4.2", + "num-traits", + "serde", + "serde_derive", + "solana-account", + "solana-bincode", + "solana-clock", + "solana-epoch-schedule", + "solana-hash", + "solana-instruction", + "solana-keypair", + "solana-packet", + "solana-program-runtime", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-signer", + "solana-slot-hashes", + "solana-transaction", + "solana-transaction-context", + "solana-vote-interface", + "thiserror 2.0.18", ] [[package]] -name = "spl-token" -version = "4.0.0" +name = "solana-zk-elgamal-proof-program" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060" +checksum = "70cea14481d8efede6b115a2581f27bc7c6fdfba0752c20398456c3ac1245fc4" dependencies = [ - "arrayref", + "agave-feature-set", "bytemuck", - "num-derive 0.3.3", + "num-derive 0.4.2", "num-traits", - "num_enum 0.6.1", - "solana-program", - "thiserror", + "solana-instruction", + "solana-log-collector", + "solana-program-runtime", + "solana-sdk-ids", + "solana-zk-sdk", ] [[package]] -name = "spl-token-2022" -version = "0.9.0" +name = "solana-zk-sdk" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86" +checksum = "97b9fc6ec37d16d0dccff708ed1dd6ea9ba61796700c3bb7c3b401973f10f63b" dependencies = [ - "arrayref", + "aes-gcm-siv", + "base64 0.22.1", + "bincode", "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "itertools 0.12.1", + "js-sys", + "merlin", "num-derive 0.4.2", "num-traits", - "num_enum 0.7.5", - "solana-program", - "solana-zk-token-sdk", - "spl-memo", - "spl-pod", - "spl-token", - "spl-token-metadata-interface", - "spl-transfer-hook-interface 0.3.0", - "spl-type-length-value", - "thiserror", + "rand 0.8.5", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-seed-derivable", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "subtle", + "thiserror 2.0.18", + "wasm-bindgen", + "zeroize", ] [[package]] -name = "spl-token-2022" -version = "1.0.0" +name = "solana-zk-token-proof-program" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d697fac19fd74ff472dfcc13f0b442dd71403178ce1de7b5d16f83a33561c059" +checksum = "579752ad6ea2a671995f13c763bf28288c3c895cb857a518cc4ebab93c9a8dde" dependencies = [ - "arrayref", + "agave-feature-set", "bytemuck", "num-derive 0.4.2", "num-traits", - "num_enum 0.7.5", - "solana-program", - "solana-security-txt", + "solana-instruction", + "solana-log-collector", + "solana-program-runtime", + "solana-sdk-ids", "solana-zk-token-sdk", - "spl-memo", - "spl-pod", - "spl-token", - "spl-token-group-interface", - "spl-token-metadata-interface", - "spl-transfer-hook-interface 0.4.1", - "spl-type-length-value", - "thiserror", ] [[package]] -name = "spl-token-group-interface" -version = "0.1.0" +name = "solana-zk-token-sdk" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b889509d49fa74a4a033ca5dae6c2307e9e918122d97e58562f5c4ffa795c75d" +checksum = "5055e5df94abd5badf4f947681c893375bdb6f8f543c05d2a7ab9647a6a9d205" dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", "bytemuck", - "solana-program", - "spl-discriminator", - "spl-pod", - "spl-program-error", -] - -[[package]] -name = "spl-token-metadata-interface" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" -dependencies = [ - "borsh 0.10.4", - "solana-program", - "spl-discriminator", - "spl-pod", - "spl-program-error", - "spl-type-length-value", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "itertools 0.12.1", + "merlin", + "num-derive 0.4.2", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-curve25519", + "solana-derivation-path", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-seed-derivable", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "subtle", + "thiserror 2.0.18", + "zeroize", ] [[package]] -name = "spl-transfer-hook-interface" +name = "spinning_top" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b" -dependencies = [ - "arrayref", - "bytemuck", - "solana-program", - "spl-discriminator", - "spl-pod", - "spl-program-error", - "spl-tlv-account-resolution 0.4.0", - "spl-type-length-value", -] - -[[package]] -name = "spl-transfer-hook-interface" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aabdb7c471566f6ddcee724beb8618449ea24b399e58d464d6b5bc7db550259" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" dependencies = [ - "arrayref", - "bytemuck", - "solana-program", - "spl-discriminator", - "spl-pod", - "spl-program-error", - "spl-tlv-account-resolution 0.5.1", - "spl-type-length-value", + "lock_api", ] [[package]] -name = "spl-type-length-value" -version = "0.3.0" +name = "spl-generic-token" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" +checksum = "741a62a566d97c58d33f9ed32337ceedd4e35109a686e31b1866c5dfa56abddc" dependencies = [ "bytemuck", - "solana-program", - "spl-discriminator", - "spl-pod", - "spl-program-error", + "solana-pubkey", ] [[package]] @@ -4560,28 +7253,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] -name = "strsim" -version = "0.8.0" +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] -name = "strsim" -version = "0.11.1" +name = "strum" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] [[package]] name = "subtle" -version = "2.4.1" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "symlink" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a" [[package]] name = "syn" @@ -4607,9 +7322,12 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "0.1.2" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] [[package]] name = "synstructure" @@ -4635,24 +7353,49 @@ dependencies = [ ] [[package]] -name = "system-configuration" -version = "0.5.1" +name = "tar" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", + "filetime", + "libc", + "xattr", ] [[package]] -name = "system-configuration-sys" -version = "0.5.0" +name = "tarpc" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +checksum = "1c38a012bed6fb9681d3bf71ffaa4f88f3b4b9ed3198cda6e4c8462d24d4bb80" dependencies = [ - "core-foundation-sys", - "libc", + "anyhow", + "fnv", + "futures", + "humantime", + "opentelemetry", + "pin-project", + "rand 0.8.5", + "serde", + "static_assertions", + "tarpc-plugins", + "thiserror 1.0.69", + "tokio", + "tokio-serde", + "tokio-util 0.6.10", + "tracing", + "tracing-opentelemetry", +] + +[[package]] +name = "tarpc-plugins" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee42b4e559f17bce0385ebf511a7beb67d5cc33c12c96b7f4e9789919d9c10f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -4677,49 +7420,73 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" + [[package]] name = "tests" version = "0.1.0" dependencies = [ - "anchor-client", + "anchor-lang", "doom-nft-program", + "mpl-core", + "solana-program-test", + "solana-sdk", + "tokio", ] [[package]] -name = "textwrap" -version = "0.11.0" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "unicode-width 0.1.14", + "thiserror-impl 1.0.69", ] [[package]] -name = "textwrap" -version = "0.16.2" +name = "thiserror" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] [[package]] -name = "thiserror" +name = "thiserror-impl" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "thiserror-impl", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] name = "thiserror-impl" -version = "1.0.69" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", "syn 2.0.110", ] +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + [[package]] name = "time" version = "0.3.44" @@ -4751,25 +7518,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny-bip39" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" -dependencies = [ - "anyhow", - "hmac 0.8.1", - "once_cell", - "pbkdf2 0.4.0", - "rand 0.7.3", - "rustc-hash", - "sha2 0.9.9", - "thiserror", - "unicode-normalization", - "wasm-bindgen", - "zeroize", -] - [[package]] name = "tinystr" version = "0.8.2" @@ -4829,10 +7577,36 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls", + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls 0.23.37", "tokio", ] +[[package]] +name = "tokio-serde" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "911a61637386b789af998ee23f50aa30d5fd7edcec8d6d3dedae5e5815205466" +dependencies = [ + "bincode", + "bytes", + "educe", + "futures-core", + "futures-sink", + "pin-project", + "serde", + "serde_json", +] + [[package]] name = "tokio-stream" version = "0.1.17" @@ -4852,13 +7626,28 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls", + "rustls 0.21.12", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tungstenite", "webpki-roots 0.25.4", ] +[[package]] +name = "tokio-util" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "slab", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.17" @@ -4881,11 +7670,26 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", +] + [[package]] name = "toml_datetime" version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] [[package]] name = "toml_datetime" @@ -4898,13 +7702,16 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.12.1", + "indexmap", + "serde", + "serde_spanned", "toml_datetime 0.6.11", - "winnow 0.5.40", + "toml_write", + "winnow", ] [[package]] @@ -4913,10 +7720,10 @@ version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ - "indexmap 2.12.1", + "indexmap", "toml_datetime 0.7.3", "toml_parser", - "winnow 0.7.13", + "winnow", ] [[package]] @@ -4925,9 +7732,59 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ - "winnow 0.7.13", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "async-compression", + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http 1.4.0", + "http-body", + "http-body-util", + "iri-string", + "pin-project-lite", + "tokio", + "tokio-util 0.7.17", + "tower", + "tower-layer", + "tower-service", ] +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + [[package]] name = "tower-service" version = "0.3.3" @@ -4959,11 +7816,36 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "fbbe89715c1dbbb790059e2565353978564924ee85017b5fff365c872ff6721f" dependencies = [ "once_cell", + "opentelemetry", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "sharded-slab", + "thread_local", + "tracing-core", ] [[package]] @@ -4981,13 +7863,13 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.12", "httparse", "log", "rand 0.8.5", - "rustls", + "rustls 0.21.12", "sha1", - "thiserror", + "thiserror 1.0.69", "url", "utf-8", "webpki-roots 0.24.0", @@ -5005,27 +7887,12 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" -[[package]] -name = "unicode-normalization" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-segmentation" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - [[package]] name = "unicode-width" version = "0.2.2" @@ -5040,11 +7907,11 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "generic-array", + "crypto-common", "subtle", ] @@ -5059,15 +7926,15 @@ dependencies = [ [[package]] name = "untrusted" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] -name = "untrusted" -version = "0.9.0" +name = "unwrap_none" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +checksum = "461d0c5956fcc728ecc03a3a961e4adc9a7975d86f6f8371389a289517c02ca9" [[package]] name = "uriparse" @@ -5110,10 +7977,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] -name = "vec_map" -version = "0.8.2" +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" @@ -5127,6 +8000,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -5235,13 +8118,22 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" dependencies = [ - "rustls-webpki", + "rustls-webpki 0.101.7", ] [[package]] @@ -5250,6 +8142,15 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -5342,11 +8243,11 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.42.2", ] [[package]] @@ -5387,17 +8288,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -5435,9 +8336,9 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" @@ -5453,9 +8354,9 @@ checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" @@ -5471,9 +8372,9 @@ checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" @@ -5501,9 +8402,9 @@ checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" @@ -5519,9 +8420,9 @@ checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" @@ -5537,9 +8438,9 @@ checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" @@ -5555,9 +8456,9 @@ checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" @@ -5571,15 +8472,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.7.13" @@ -5589,16 +8481,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "wit-bindgen" version = "0.46.0" @@ -5625,17 +8507,18 @@ dependencies = [ "nom", "oid-registry", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] [[package]] -name = "yasna" -version = "0.5.2" +name = "xattr" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" dependencies = [ - "time", + "libc", + "rustix", ] [[package]] @@ -5704,9 +8587,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "zeroize_derive", ] @@ -5757,20 +8640,19 @@ dependencies = [ [[package]] name = "zstd" -version = "0.11.2+zstd.1.5.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ - "libc", "zstd-sys", ] diff --git a/README.md b/README.md index 43164ef..5296b6c 100644 --- a/README.md +++ b/README.md @@ -1,126 +1,127 @@ # Doom NFT Program -Solanaブロックチェーン上で動作するNFT(Non-Fungible Token)プログラムです。Anchorフレームワークを使用して実装されています。 +This repository contains the Solana program for minting DOOM INDEX artworks as NFTs. It is built with Anchor and currently targets a Metaplex Core based mint flow with deterministic metadata URIs. -## 特徴 +## Features -- **NFTミント**: 新しいNFTを作成・発行 -- **トークン転送**: NFTの所有権移転 -- **SPLトークン互換**: Solanaの標準トークン規格に対応 -- **セキュリティ**: Anchorフレームワークのセキュリティ機能を使用 +- **Collection setup**: Initialize the DOOM INDEX collection on Metaplex Core +- **Token reservation**: Reserve a sequential `tokenId` before minting +- **NFT minting**: Mint a DOOM INDEX NFT from a valid reservation +- **Admin controls**: Manage base metadata URL, pause state, admin authority, and upgrade authority +- **Contract tests**: Run Rust integration tests against the real Core CPI path -## 技術スタック +## Tech Stack - **Blockchain**: Solana - **Framework**: Anchor - **Language**: Rust -- **Testing**: TypeScript, Mocha, Chai +- **NFT Standard**: Metaplex Core +- **Testing**: Rust `solana-program-test`, Bun - **Package Manager**: Bun -## 前提条件 +## Prerequisites - [Rust](https://rustup.rs/) -- [Solana CLI](https://docs.solana.com/cli/install-solana-cli-tools) +- [Solana CLI](https://docs.anza.xyz/cli/install) - [Anchor](https://www.anchor-lang.com/) -- [Bun](https://bun.sh/) または [Node.js](https://nodejs.org/) +- [Bun](https://bun.sh/) -## インストール +## Installation ```bash -# リポジトリをクローン -git clone https://github.com/posaune0423/doom-nft-program.git +# Clone the repository +git clone https://github.com/doom-protocol/doom-nft-program.git cd doom-nft-program -# 依存関係のインストール +# Install dependencies bun install -# Solana CLIの設定(devnetを使用する場合) +# Install git hooks +bun run prepare + +# Optional: point Solana CLI at devnet solana config set --url https://api.devnet.solana.com -# キーペアの生成(初回のみ) +# Optional: create a local keypair if you do not have one yet solana-keygen new ``` -## ビルド +## Build ```bash -# プログラムのビルド -anchor build +# Build the Rust workspace +cargo build --workspace -# IDLファイルの生成 -anchor idl parse -f programs/doom-nft-program/src/lib.rs -o target/idl/doom_nft_program.json +# Build the contract test SBF dependency artifact +bun run build:sbf:test ``` -## テスト +## Test ```bash -# テスト実行 -anchor test - -# ローカルバリデーターでのテスト -anchor localnet -``` +# Run Rust unit tests plus contract tests +bun run test -## デプロイ +# Run only the contract test suite +bun run test:contract -```bash -# プログラムのデプロイ -anchor deploy - -# プログラムIDの確認 -solana program show --programs +# Run the full local quality gate +bun run check ``` -## 使用方法 - -### NFTミント +## Development Scripts -```rust -// プログラム内でNFTを作成 -create_mint(ctx)?; - -// トークンをミント -mint_token(ctx)?; -``` +```bash +# Initialize global config on devnet +bun run devnet:init -### NFT転送 +# Reserve the next token id on devnet +bun run devnet:reserve -```rust -// NFTを転送 -transfer_token(ctx)?; +# Mint a DOOM INDEX NFT on devnet +bun run devnet:mint ``` -## プログラム構造 +## Repository Structure -``` +```text programs/doom-nft-program/ -├── src/lib.rs # メインのプログラムロジック -├── Cargo.toml # Rust依存関係 -└── Xargo.toml # クロスコンパイル設定 - -tests/ -├── src/lib.rs # テストファイル -└── Cargo.toml # テスト依存関係 - -migrations/ -├── src/main.rs # マイグレーションスクリプト -└── Cargo.toml # マイグレーション依存関係 +├── src/ +│ ├── instructions/ # Instruction handlers +│ ├── state/ # On-chain account state +│ ├── constants.rs # Program constants +│ ├── error.rs # Custom errors +│ ├── events.rs # Program events +│ ├── lib.rs # Program entrypoint +│ └── utils.rs # Shared helpers +├── Cargo.toml +└── Xargo.toml + +tests/src/ +├── instructions/ # Source-aligned contract tests +├── lib.rs # Test module entrypoint +└── test_context.rs # Shared test fixtures and helpers + +scripts/ +├── build-test-sbf.sh # Copies the pinned Core test fixture into target/test-sbf +├── test-contract-v1.sh # Runs the contract suite +└── devnet/ # Devnet helper scripts ``` -## コントリビューション +## Contributing -1. Forkしてください -2. Featureブランチを作成 (`git checkout -b feature/amazing-feature`) -3. 変更をコミット (`git commit -m 'Add amazing feature'`) -4. ブランチにPush (`git push origin feature/amazing-feature`) -5. Pull Requestを作成してください +1. Fork the repository. +2. Create a feature branch: `git checkout -b feature/amazing-feature` +3. Commit your changes: `git commit -m 'Add amazing feature'` +4. Push the branch: `git push origin feature/amazing-feature` +5. Open a pull request. -## ライセンス +## License -このプロジェクトはMITライセンスの下で公開されています。 +This project is released under the MIT License. -## 注意事項 +## Notes -- このプログラムは開発中です -- テストネットでのみ動作確認を行っています -- 本番環境での使用は自己責任でお願いします +- The program is still under active development. +- The contract test flow avoids a local SBF build of this program and runs it as a host builtin, while loading the pinned official Metaplex Core `release/core@0.9.10` fixture for the Core CPI path. +- Devnet deployment may still depend on Solana faucet availability. diff --git a/docs/DOOM_INDEX_NFT_MINT_REQUIREMENTS.md b/docs/DOOM_INDEX_NFT_MINT_REQUIREMENTS.md new file mode 100644 index 0000000..6035cf9 --- /dev/null +++ b/docs/DOOM_INDEX_NFT_MINT_REQUIREMENTS.md @@ -0,0 +1,509 @@ +# DOOM INDEX NFT Mint Contract V1 Requirements + +## 1. Purpose + +Enable artworks generated by DOOM INDEX at fixed intervals to be minted as NFTs on Solana. +Because the specification is still likely to change in the early phase, the target contract for this spec is defined as **`DOOM INDEX NFT Mint Contract V1`**. +Contract V1 assumes an **upgradeable program**, while metadata generation and delivery, which are expected to change frequently, remain off-chain. + +The primary goals of this feature are: + +- Users can acquire DOOM INDEX artworks as Solana NFTs. +- The application can issue a sequential custom `tokenId` for each NFT. +- The NFT metadata follows standard Solana NFT conventions and supports a 3D model in addition to a thumbnail image. +- The full flow can be validated on `devnet` as well as `localnet`. +- The design can accommodate future specification changes. + +## 2. Design Principles + +### 2.1 Standards and Chain + +- Use Metaplex Core as the NFT standard. +- Use the Solana / Metaplex Core `Asset Address` as the canonical on-chain asset identifier. +- Manage `tokenId` on-chain as an application-specific sequential identifier. +- Support both `localnet` and `devnet` as development and validation environments. +- Deploy Contract V1 as an upgradeable program. +- Keep state and instructions minimal so migration to Contract V2 and beyond remains straightforward. + +### 2.2 Core V1 Design + +- The metadata URI at mint time is determined deterministically by the program from `tokenId`, rather than being approved by the backend each time. +- The standard metadata URI format is `"{base_metadata_url}/{tokenId}.json"`. +- Adopt a reservation flow that finalizes `tokenId` before mint so metadata JSON can be uploaded in advance. +- Metadata content may be identical across assets generated within the same generation window. +- The URI itself must still be unique per `tokenId`. +- Do not store generation state on-chain. +- Users must not be allowed to provide arbitrary URIs. +- Separate business admin authority from program upgrade authority. +- Prefer a program-managed PDA over an EOA for collection authority. + +## 3. Scope + +### 3.1 In Scope + +- Metaplex Core collection initialization +- DOOM INDEX NFT minting +- Sequential `tokenId` issuance +- Deterministic metadata URI assignment +- Admin operating functions +- Devnet end-to-end validation flow +- Standard metadata plus 3D model support + +### 3.2 Out of Scope + +The following items are out of scope for V1: + +- Strict on-chain management of generation boundaries +- cNFT / compressed NFT +- Allowlist / WL mint +- Per-wallet mint limits +- Mint price / treasury design +- Secondary market strategy +- Full royalty design +- Approval-gated minting beyond a permissionless flow +- On-chain storage of per-token metadata +- Automatic batch replacement of metadata for existing NFTs + +## 4. System Overview + +### 4.1 Overall Architecture + +This system manages artwork metadata off-chain and issues Metaplex Core assets using a URI computed by the program at mint time. + +- The on-chain program is responsible for `tokenId` issuance, URI selection, and asset creation under the collection. +- The off-chain backend is responsible for generating and hosting the thumbnail, 3D model, and metadata JSON. +- The frontend provides the mint UI and wallet-signing flow for users. + +### 4.2 Identifiers + +- `Asset Address`: The canonical NFT identifier on Solana / Metaplex Core +- `tokenId`: The DOOM INDEX application-specific sequential ID +- `Collection Address`: The identifier for the DOOM INDEX collection + +## 5. On-Chain Design + +### 5.1 GlobalConfig + +V1 persistent state consists of `GlobalConfig` and `MintReservation`. +The PDA seed for `GlobalConfig` is fixed as `["global_config"]`. + +Recommended fields: + +- `admin: Pubkey` +- `upgrade_authority: Pubkey` +- `next_token_id: u64` +- `mint_paused: bool` +- `base_metadata_url: String` +- `collection: Pubkey` +- `collection_update_authority: Pubkey` +- `bump: u8` + +`next_token_id` stores the next value to issue and starts at `1`. +Contract V1 uses a single counter and prioritizes implementation simplicity over highly parallel mint throughput. + +### 5.2 MintReservation + +`MintReservation` is temporary state used to finalize `tokenId` before minting so the metadata can be uploaded ahead of time without conflicts. +The standard PDA seed is `["reservation", token_id_le_bytes]`. + +Recommended fields: + +- `token_id: u64` +- `reserver: Pubkey` +- `minted: bool` +- `bump: u8` + +### 5.3 Anchor Instructions + +#### `initialize_global_config` + +- Executed by `admin` +- Initializes `GlobalConfig` +- Sets `admin` and `upgrade_authority` +- Sets `next_token_id = 1` +- Sets `mint_paused = false` +- Sets `base_metadata_url` + +#### `initialize_collection` + +- Executed by `admin` +- Creates the Metaplex Core collection +- Stores the created collection address in `GlobalConfig.collection` +- Prefers a program-managed PDA for the collection update authority + +#### `reserve_token_id` + +- Executed by the user +- Requires `mint_paused == false` +- Assigns `tokenId = next_token_id` +- Increments `next_token_id += 1` +- Creates `MintReservation` +- After reservation, the off-chain backend uploads `"{base_metadata_url}/{tokenId}.json"` +- V1 does not include reservation expiry; unused reservations may be handled later operationally or via migration + +#### `mint_doom_index_nft` + +- Executed by the user +- Requires `mint_paused == false` +- Requires the user's own `MintReservation` +- Requires `MintReservation.minted == false` +- Sets the asset name to `DOOM INDEX #` +- Sets the URI to `"{base_metadata_url}/{tokenId}.json"` +- Creates a Metaplex Core asset under the collection with the user as owner +- Sets `MintReservation.minted = true` on successful mint + +#### `update_base_metadata_url` + +- Executed by `admin` +- Updates `base_metadata_url` +- Applies only to future mints +- Does not change the on-chain URI of existing NFTs + +#### `set_mint_paused` + +- Executed by `admin` +- Toggles mint pause / unpause + +#### `transfer_admin` + +- Executed by the current `admin` +- Updates `admin` + +#### `set_upgrade_authority` + +- Executed by the current `upgrade_authority` +- Updates `upgrade_authority` +- Remains independent from business admin permissions + +## 6. Functional Requirements + +### 6.1 Mint + +- FR-01: The user can reserve a `tokenId` before minting via `reserve_token_id`. +- FR-02: The user can mint a DOOM INDEX NFT using a reserved `tokenId`. +- FR-03: The display name must be `DOOM INDEX #`. +- FR-04: Minting must assign a deterministic metadata URI. +- FR-05: The user must not be able to specify an arbitrary URI. +- FR-06: The NFT must be issued as a Metaplex Core asset. +- FR-07: The minted asset must belong to the DOOM INDEX collection. +- FR-08: Minting must fail for a `tokenId` without a reservation. +- FR-09: A reservation must not be reusable. + +### 6.2 Admin Functions + +- FR-10: The admin can initialize `GlobalConfig`. +- FR-11: The admin can initialize the collection. +- FR-12: The admin can update `base_metadata_url`. +- FR-13: The admin can pause and resume minting. +- FR-14: The admin can transfer admin authority. +- FR-15: Upgrade authority must be separated from admin authority. + +### 6.3 Devnet Validation + +- FR-16: The program can be deployed to devnet. +- FR-17: The full devnet flow covers collection initialization, reservation, metadata upload, minting, and state inspection. +- FR-18: NFTs issued on devnet reference a publicly accessible metadata URI. +- FR-19: Both `image` and `animation_url` can be fetched on devnet. + +## 7. Metadata Specification + +### 7.1 Basic Policy + +Follow the off-chain JSON schema used by Metaplex Core. +Core JSON metadata is close to the Token Metadata standard and requires `name`, `description`, `image`, and `category`, while allowing optional fields such as `animation_url`, `external_url`, `attributes`, and `properties.files`. + +For DOOM INDEX, V1 standardizes the following: + +- `image`: Public URI for the thumbnail image +- `animation_url`: Public URI for the 3D model +- `properties.files`: Must list both the image and the 3D model +- `external_url`: Public DOOM INDEX artwork detail page +- `attributes`: Minimum identifying information, visual parameters, and prompt data used for the artwork +- `doom_index`: DOOM INDEX-specific auxiliary field for machine-readable storage of long prompts or raw values + +### 7.2 Minimum Attribute Requirements + +In V1, each token metadata document should include at least the following information. +For viewer compatibility, values meant to be displayed should be placed in `attributes`. + +#### Basic Information + +- `Generated` +- `ID` +- `Seed` +- `Params Hash` +- `File Size` + +#### Visual Parameters + +- `fogDensity` +- `skyTint` +- `reflectivity` +- `blueBalance` +- `vegetationDensity` +- `organicPattern` +- `radiationGlow` +- `debrisIntensity` +- `mechanicalPattern` +- `metallicRatio` +- `fractalDensity` +- `bioluminescence` +- `shadowDepth` +- `redHighlight` +- `lightIntensity` +- `warmHue` + +#### Prompt Information + +- `Prompt` +- `Negative Prompt` + +Numeric values may remain as decimals. +`Generated` should use an ISO 8601 UTC timestamp. +`File Size` may be stored as a display-first string such as `"472.62 KB"`. + +Because `Prompt` and `Negative Prompt` can be long, the same values may also be duplicated in a top-level custom field in addition to `attributes`. + +### 7.3 Recommended JSON Shape + +```json +{ + "name": "DOOM INDEX #1", + "description": "AI-generated market artwork from DOOM INDEX.", + "image": "https://cdn.example.com/doom-index/1.png", + "animation_url": "https://cdn.example.com/doom-index/1.glb", + "external_url": "https://doomindex.fun/artworks/1", + "category": "vr", + "attributes": [ + { + "trait_type": "Generated", + "value": "2026-03-12T03:00:00Z" + }, + { + "trait_type": "ID", + "value": "DOOM_202603111800_c92dfdb3_0a44d00ee2c7" + }, + { + "trait_type": "Seed", + "value": "0a44d00ee2c7" + }, + { + "trait_type": "Params Hash", + "value": "c92dfdb3" + }, + { + "trait_type": "File Size", + "value": "472.62 KB" + }, + { + "trait_type": "fogDensity", + "value": 0.4745098039215686 + }, + { + "trait_type": "skyTint", + "value": 0.9254901960784314 + }, + { + "trait_type": "reflectivity", + "value": 0.1411764705882353 + }, + { + "trait_type": "blueBalance", + "value": 0.41568627450980394 + }, + { + "trait_type": "vegetationDensity", + "value": 0.4549019607843137 + }, + { + "trait_type": "organicPattern", + "value": 0.6549019607843137 + }, + { + "trait_type": "radiationGlow", + "value": 0.8470588235294118 + }, + { + "trait_type": "debrisIntensity", + "value": 0.6666666666666666 + }, + { + "trait_type": "mechanicalPattern", + "value": 0.9254901960784314 + }, + { + "trait_type": "metallicRatio", + "value": 0.8745098039215686 + }, + { + "trait_type": "fractalDensity", + "value": 1 + }, + { + "trait_type": "bioluminescence", + "value": 0.9764705882352941 + }, + { + "trait_type": "shadowDepth", + "value": 0.9725490196078431 + }, + { + "trait_type": "redHighlight", + "value": 0.6941176470588235 + }, + { + "trait_type": "lightIntensity", + "value": 0.3686274509803922 + }, + { + "trait_type": "warmHue", + "value": 0.6588235294117647 + }, + { + "trait_type": "Prompt", + "value": "Use the reference image as a mysterious ancient symbol reflected in the surface of a mystical pool at the foreground..." + }, + { + "trait_type": "Negative Prompt", + "value": "watermark, text, oversaturated colors, low detail hands, extra limbs" + } + ], + "doom_index": { + "generated_at": "2026-03-12T03:00:00Z", + "source_id": "DOOM_202603111800_c92dfdb3_0a44d00ee2c7", + "seed": "0a44d00ee2c7", + "params_hash": "c92dfdb3", + "file_size_kb": 472.62, + "prompt": "Use the reference image as a mysterious ancient symbol reflected in the surface of a mystical pool at the foreground. Ensure the token logo is subtly integrated into the classical oil painting composition without dominating the overall renaissance master style...", + "negative_prompt": "watermark, text, oversaturated colors, low detail hands, extra limbs", + "visual_parameters": { + "fogDensity": 0.4745098039215686, + "skyTint": 0.9254901960784314, + "reflectivity": 0.1411764705882353, + "blueBalance": 0.41568627450980394, + "vegetationDensity": 0.4549019607843137, + "organicPattern": 0.6549019607843137, + "radiationGlow": 0.8470588235294118, + "debrisIntensity": 0.6666666666666666, + "mechanicalPattern": 0.9254901960784314, + "metallicRatio": 0.8745098039215686, + "fractalDensity": 1, + "bioluminescence": 0.9764705882352941, + "shadowDepth": 0.9725490196078431, + "redHighlight": 0.6941176470588235, + "lightIntensity": 0.3686274509803922, + "warmHue": 0.6588235294117647 + } + }, + "properties": { + "files": [ + { + "uri": "https://cdn.example.com/doom-index/1.png", + "type": "image/png" + }, + { + "uri": "https://cdn.example.com/doom-index/1.glb", + "type": "model/gltf-binary" + } + ] + } +} +``` + +### 7.4 Media Requirements + +- Use PNG or JPEG as the standard format for thumbnails. +- Use GLB as the standard format for 3D models. +- If glTF is added later, use the MIME type `model/gltf+json`. +- The metadata URI, image URI, and `animation_url` URI must all be publicly accessible over HTTPS. +- Even during devnet validation, use URI formats that are appropriate for eventual mainnet use. + +### 7.5 Collection Metadata + +Collection metadata should also follow the standard JSON shape. +At minimum, it should include: + +- `name` +- `description` +- `image` +- `external_url` +- `category` + +## 8. Mint Flow + +1. An artwork generation worker produces a new artwork at a fixed interval. +2. The user sends a `reserve_token_id` transaction. +3. The on-chain program reads `next_token_id`, assigns a `tokenId`, and creates `MintReservation`. +4. The backend generates the thumbnail, 3D model, and metadata JSON for the reserved `tokenId` and uploads them to `{base_metadata_url}/{tokenId}.json`. +5. The user sends a `mint_doom_index_nft` transaction. +6. The program validates the reservation and determines the final name and URI. +7. The program mints a Metaplex Core asset under the collection. +8. The program marks the reservation as used. +9. The user receives the asset address and can confirm it in a wallet, explorer, or Metaplex Core viewer. + +## 9. Devnet Validation Requirements + +### 9.1 Required Checks + +- The upgradeable program can be deployed to devnet. +- `initialize_global_config` can be executed on devnet. +- `initialize_collection` can be executed on devnet. +- `reserve_token_id` can be executed on devnet. +- `mint_doom_index_nft` can be executed on devnet from a user wallet. +- After minting, the asset address, owner, collection, name, and URI can be retrieved. +- The metadata JSON can be fetched. +- Both the thumbnail and 3D model can be fetched. +- The same reservation cannot be used to mint twice. + +### 9.2 Recommended Validation Tools + +- Solana Explorer on devnet +- Metaplex Core viewer +- Fetch-based validation from scripts or the frontend + +### 9.3 Supporting Deliverables to Include in Implementation + +To make devnet validation easier, the implementation should include: + +- An initialization script for devnet +- A devnet mint script or UI +- A verification procedure for asset, collection, and metadata checks + +## 10. Non-Functional Requirements + +### 10.1 Extensibility + +- The generation interval can be changed from ten minutes in the future. +- Pricing, allowlists, and per-wallet limits can be added later. +- The metadata system can evolve while keeping per-token metadata distinct. +- Asset immutability policy can be tightened later. +- Migration from Contract V1 to Contract V2 and beyond remains possible. + +### 10.2 Maintainability + +- Keep on-chain state minimal. +- Keep metadata generation logic off-chain. +- Make future feature additions easy through program upgrades. +- Accept serialization through a single `next_token_id` counter; Contract V1 is not optimized for very high-frequency bulk minting. + +### 10.3 Compatibility + +- Use a metadata format that Solana wallets and standard NFT viewers can understand. +- Provide `image` as the primary preview while using `animation_url` for the 3D model. + +## 11. Open Items + +The following items remain undecided at the time Contract V1 is defined: + +1. Whether generation boundaries should follow UTC or JST +2. Which storage layer to use: IPFS, Arweave, Irys, or R2 + CDN +3. How strictly metadata URI immutability should be enforced +4. Whether the asset / collection update authority should eventually be set to `None` +5. How prominently `tokenId` should be shown in marketplace displays +6. Whether unused reservations should later be reclaimable or cleanable + +## 12. References + +- Metaplex Core creates assets using a `name` + `uri` model that references off-chain metadata. +- The Metaplex Core JSON schema supports GLB via `animation_url`. +- `properties.files` can list both the image and the 3D model with MIME types. diff --git a/docs/PRODUCT.md b/docs/PRODUCT.md index 6debaab..3d5e09f 100644 --- a/docs/PRODUCT.md +++ b/docs/PRODUCT.md @@ -1,7 +1,7 @@ # PRODUCT -DOOM INDEX は、CoinGecko から取得したトレンドトークンの市場データを基に、10分ごとにユニークなジェネラティブアートを生成・提示するビジュアライゼーションプロダクトです。AI がトークンの市場心理を芸術として可視化し、生成画像は Cloudflare R2 に保存され、Web UI と OGP に活用されます。 +DOOM INDEX is a visualization product that generates and presents unique generative artwork every ten minutes based on trending token market data from CoinGecko. AI turns token market sentiment into artwork, and the generated images are stored in Cloudflare R2 for use in the web UI and OGP assets. -このプロジェクトは doomindex.fun (https://github.com/doom-protocol/doom-index)でAI生成された絵画をNFT化するためのsolanaのprogramです +This repository contains the Solana program that turns AI-generated DOOM INDEX artworks from [doomindex.fun](https://github.com/doom-protocol/doom-index) into NFTs. -DOOM INDEXで生成したAI生成絵画をipfsなどの分散がストレージにuploadしそのmetadataを使いsolanaの規格に準拠したNFTをmintできるようにします。 \ No newline at end of file +The goal is to upload DOOM INDEX artworks to decentralized storage such as IPFS, use that metadata, and mint NFTs that comply with Solana ecosystem standards. diff --git a/package.json b/package.json index bc6b87b..94d0f49 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,20 @@ "format:ts": "prettier . --write --ignore-unknown", "format:ts:check": "prettier . --check --ignore-unknown", "lint": "cargo clippy --workspace --all-targets --all-features -- -D warnings", - "test": "cargo test --workspace", - "check": "bun run format:check && bun run lint && bun run test" + "build:sbf:test": "./scripts/build-test-sbf.sh", + "test:contract": "./scripts/test-contract-v1.sh", + "devnet:init": "bun run ./scripts/devnet/init.ts", + "devnet:reserve": "bun run ./scripts/devnet/reserve.ts", + "devnet:mint": "bun run ./scripts/devnet/mint.ts", + "typecheck": "tsc --noEmit -p tsconfig.json", + "test": "cargo test --workspace --exclude tests && bun run test:contract", + "check": "bun run format:check && bun run lint && bun run test && bun run typecheck" }, "dependencies": { "@coral-xyz/anchor": "^0.31.1" }, "devDependencies": { + "@types/node": "^24.0.0", "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", "@types/mocha": "^9.0.0", diff --git a/programs/doom-nft-program/Cargo.toml b/programs/doom-nft-program/Cargo.toml index b9bafad..b7edcc2 100644 --- a/programs/doom-nft-program/Cargo.toml +++ b/programs/doom-nft-program/Cargo.toml @@ -17,12 +17,13 @@ cpi = ["no-entrypoint"] no-entrypoint = [] no-idl = [] no-log-ix-name = [] -idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"] +idl-build = ["anchor-lang/idl-build"] [lints.rust] unexpected_cfgs = { level = "allow", check-cfg = ["cfg(target_os, values(\"solana\"))"] } [dependencies] -anchor-lang = "0.29.0" -anchor-spl = "0.29.0" -solana-program = "1.18.26" +anchor-lang = "0.31.1" +mpl-core = { version = "0.11.1", features = ["anchor"] } +solana-program = "2.2.1" +url = "2.5.4" diff --git a/programs/doom-nft-program/src/constants.rs b/programs/doom-nft-program/src/constants.rs new file mode 100644 index 0000000..173bd9e --- /dev/null +++ b/programs/doom-nft-program/src/constants.rs @@ -0,0 +1,4 @@ +pub const COLLECTION_NAME: &str = "DOOM INDEX"; +pub const GLOBAL_CONFIG_SEED: &[u8] = b"global_config"; +pub const RESERVATION_SEED: &[u8] = b"reservation"; +pub const COLLECTION_AUTHORITY_SEED: &[u8] = b"collection_authority"; diff --git a/programs/doom-nft-program/src/error.rs b/programs/doom-nft-program/src/error.rs new file mode 100644 index 0000000..5a3cce0 --- /dev/null +++ b/programs/doom-nft-program/src/error.rs @@ -0,0 +1,27 @@ +use anchor_lang::prelude::*; + +#[error_code] +pub enum DoomNftProgramError { + #[msg("The caller is not authorized to perform this action.")] + Unauthorized, + #[msg("Minting is currently paused.")] + MintPaused, + #[msg("The collection has not been initialized.")] + CollectionNotInitialized, + #[msg("The provided collection account does not match the configured collection.")] + CollectionMismatch, + #[msg("The collection has already been initialized.")] + CollectionAlreadyInitialized, + #[msg("The reservation has already been used to mint an asset.")] + ReservationAlreadyMinted, + #[msg("The reservation belongs to a different user.")] + ReservationOwnerMismatch, + #[msg("The reservation token id does not match the instruction token id.")] + ReservationTokenMismatch, + #[msg("The configured collection authority does not match the derived PDA.")] + CollectionAuthorityMismatch, + #[msg("The base metadata url is invalid.")] + BaseMetadataUrlInvalid, + #[msg("The token id counter overflowed.")] + TokenIdOverflow, +} diff --git a/programs/doom-nft-program/src/events.rs b/programs/doom-nft-program/src/events.rs new file mode 100644 index 0000000..d750549 --- /dev/null +++ b/programs/doom-nft-program/src/events.rs @@ -0,0 +1,27 @@ +use anchor_lang::prelude::*; + +#[event] +pub struct TokenReserved { + pub token_id: u64, + pub reserver: Pubkey, + pub reservation: Pubkey, +} + +#[event] +pub struct AssetMinted { + pub token_id: u64, + pub asset: Pubkey, + pub owner: Pubkey, +} + +#[event] +pub struct BaseMetadataUrlUpdated { + pub old_base_url: String, + pub new_base_url: String, +} + +#[event] +pub struct UpgradeAuthorityUpdated { + pub old_upgrade_authority: Pubkey, + pub new_upgrade_authority: Pubkey, +} diff --git a/programs/doom-nft-program/src/instructions/initialize_collection.rs b/programs/doom-nft-program/src/instructions/initialize_collection.rs new file mode 100644 index 0000000..c5f9159 --- /dev/null +++ b/programs/doom-nft-program/src/instructions/initialize_collection.rs @@ -0,0 +1,65 @@ +use anchor_lang::prelude::*; +use mpl_core::{instructions::CreateCollectionV2CpiBuilder, ID as MPL_CORE_ID}; + +use crate::{ + constants::{COLLECTION_AUTHORITY_SEED, COLLECTION_NAME, GLOBAL_CONFIG_SEED}, + error::DoomNftProgramError, + state::GlobalConfig, + utils::build_collection_uri, +}; + +#[derive(Accounts)] +pub struct InitializeCollection<'info> { + #[account( + mut, + seeds = [GLOBAL_CONFIG_SEED], + bump = global_config.bump, + has_one = admin @ DoomNftProgramError::Unauthorized + )] + pub global_config: Account<'info, GlobalConfig>, + + #[account(mut)] + pub admin: Signer<'info>, + + /// CHECK: Fresh signer for the new Core collection account. + #[account(mut)] + pub collection: Signer<'info>, + + /// CHECK: PDA used only as the Core collection update authority. + #[account( + seeds = [COLLECTION_AUTHORITY_SEED, global_config.key().as_ref()], + bump + )] + pub collection_update_authority: UncheckedAccount<'info>, + + /// CHECK: Verified against the canonical Metaplex Core program id. + #[account(address = MPL_CORE_ID)] + pub mpl_core_program: UncheckedAccount<'info>, + + pub system_program: Program<'info, System>, +} + +pub fn process_initialize_collection(ctx: Context) -> Result<()> { + let global_config = &mut ctx.accounts.global_config; + require!( + global_config.collection == Pubkey::default(), + DoomNftProgramError::CollectionAlreadyInitialized + ); + + let collection_uri = build_collection_uri(&global_config.base_metadata_url); + CreateCollectionV2CpiBuilder::new(&ctx.accounts.mpl_core_program.to_account_info()) + .collection(&ctx.accounts.collection.to_account_info()) + .update_authority(Some( + &ctx.accounts.collection_update_authority.to_account_info(), + )) + .payer(&ctx.accounts.admin.to_account_info()) + .system_program(&ctx.accounts.system_program.to_account_info()) + .name(COLLECTION_NAME.to_owned()) + .uri(collection_uri) + .invoke()?; + + global_config.collection = ctx.accounts.collection.key(); + global_config.collection_update_authority = ctx.accounts.collection_update_authority.key(); + + Ok(()) +} diff --git a/programs/doom-nft-program/src/instructions/initialize_global_config.rs b/programs/doom-nft-program/src/instructions/initialize_global_config.rs new file mode 100644 index 0000000..bbab6b4 --- /dev/null +++ b/programs/doom-nft-program/src/instructions/initialize_global_config.rs @@ -0,0 +1,42 @@ +use anchor_lang::prelude::*; + +use crate::{ + constants::GLOBAL_CONFIG_SEED, state::GlobalConfig, utils::validate_base_metadata_url, +}; + +#[derive(Accounts)] +pub struct InitializeGlobalConfig<'info> { + #[account( + init, + payer = admin, + space = 8 + GlobalConfig::INIT_SPACE, + seeds = [GLOBAL_CONFIG_SEED], + bump + )] + pub global_config: Account<'info, GlobalConfig>, + + #[account(mut)] + pub admin: Signer<'info>, + + pub system_program: Program<'info, System>, +} + +pub fn process_initialize_global_config( + ctx: Context, + base_metadata_url: String, + upgrade_authority: Pubkey, +) -> Result<()> { + validate_base_metadata_url(&base_metadata_url)?; + + let global_config = &mut ctx.accounts.global_config; + global_config.admin = ctx.accounts.admin.key(); + global_config.upgrade_authority = upgrade_authority; + global_config.next_token_id = 1; + global_config.mint_paused = false; + global_config.base_metadata_url = base_metadata_url; + global_config.collection = Pubkey::default(); + global_config.collection_update_authority = Pubkey::default(); + global_config.bump = ctx.bumps.global_config; + + Ok(()) +} diff --git a/programs/doom-nft-program/src/instructions/mint_doom_index_nft.rs b/programs/doom-nft-program/src/instructions/mint_doom_index_nft.rs new file mode 100644 index 0000000..ab295e1 --- /dev/null +++ b/programs/doom-nft-program/src/instructions/mint_doom_index_nft.rs @@ -0,0 +1,108 @@ +use anchor_lang::prelude::*; +use mpl_core::{instructions::CreateV2CpiBuilder, types::DataState, ID as MPL_CORE_ID}; + +use crate::{ + constants::{COLLECTION_AUTHORITY_SEED, GLOBAL_CONFIG_SEED, RESERVATION_SEED}, + error::DoomNftProgramError, + events::AssetMinted, + state::{GlobalConfig, MintReservation}, + utils::{build_asset_name, build_asset_uri}, +}; + +#[derive(Accounts)] +#[instruction(token_id: u64)] +pub struct MintDoomIndexNft<'info> { + #[account( + seeds = [GLOBAL_CONFIG_SEED], + bump = global_config.bump + )] + pub global_config: Account<'info, GlobalConfig>, + + #[account( + mut, + seeds = [RESERVATION_SEED, token_id.to_le_bytes().as_ref()], + bump = reservation.bump + )] + pub reservation: Account<'info, MintReservation>, + + #[account(mut)] + pub user: Signer<'info>, + + /// CHECK: Fresh signer for the new Core asset account. + #[account(mut)] + pub asset: Signer<'info>, + + /// CHECK: PDA signs the Core CPI as collection/asset authority. + #[account( + seeds = [COLLECTION_AUTHORITY_SEED, global_config.key().as_ref()], + bump, + address = global_config.collection_update_authority @ DoomNftProgramError::CollectionAuthorityMismatch + )] + pub collection_update_authority: UncheckedAccount<'info>, + + /// CHECK: Existing Core collection account. Address checked against config. + #[account( + mut, + address = global_config.collection @ DoomNftProgramError::CollectionMismatch + )] + pub collection: UncheckedAccount<'info>, + + /// CHECK: Verified against the canonical Metaplex Core program id. + #[account(address = MPL_CORE_ID)] + pub mpl_core_program: UncheckedAccount<'info>, + + pub system_program: Program<'info, System>, +} + +pub fn process_mint_doom_index_nft(ctx: Context, token_id: u64) -> Result<()> { + let global_config = &ctx.accounts.global_config; + require!(!global_config.mint_paused, DoomNftProgramError::MintPaused); + require!( + global_config.collection != Pubkey::default(), + DoomNftProgramError::CollectionNotInitialized + ); + + let reservation = &mut ctx.accounts.reservation; + require!( + reservation.token_id == token_id, + DoomNftProgramError::ReservationTokenMismatch + ); + require!( + reservation.reserver == ctx.accounts.user.key(), + DoomNftProgramError::ReservationOwnerMismatch + ); + require!( + !reservation.minted, + DoomNftProgramError::ReservationAlreadyMinted + ); + + let name = build_asset_name(token_id); + let uri = build_asset_uri(&global_config.base_metadata_url, token_id); + let global_config_key = ctx.accounts.global_config.key(); + let bump = [ctx.bumps.collection_update_authority]; + let signer_seeds: &[&[u8]] = &[COLLECTION_AUTHORITY_SEED, global_config_key.as_ref(), &bump]; + + CreateV2CpiBuilder::new(&ctx.accounts.mpl_core_program.to_account_info()) + .asset(&ctx.accounts.asset.to_account_info()) + .collection(Some(&ctx.accounts.collection.to_account_info())) + .authority(Some( + &ctx.accounts.collection_update_authority.to_account_info(), + )) + .payer(&ctx.accounts.user.to_account_info()) + .owner(Some(&ctx.accounts.user.to_account_info())) + .system_program(&ctx.accounts.system_program.to_account_info()) + .data_state(DataState::AccountState) + .name(name) + .uri(uri) + .invoke_signed(&[signer_seeds])?; + + reservation.minted = true; + + emit!(AssetMinted { + token_id, + asset: ctx.accounts.asset.key(), + owner: ctx.accounts.user.key(), + }); + + Ok(()) +} diff --git a/programs/doom-nft-program/src/instructions/mod.rs b/programs/doom-nft-program/src/instructions/mod.rs new file mode 100644 index 0000000..404622a --- /dev/null +++ b/programs/doom-nft-program/src/instructions/mod.rs @@ -0,0 +1,17 @@ +pub mod initialize_collection; +pub mod initialize_global_config; +pub mod mint_doom_index_nft; +pub mod reserve_token_id; +pub mod set_mint_paused; +pub mod set_upgrade_authority; +pub mod transfer_admin; +pub mod update_base_metadata_url; + +pub use initialize_collection::*; +pub use initialize_global_config::*; +pub use mint_doom_index_nft::*; +pub use reserve_token_id::*; +pub use set_mint_paused::*; +pub use set_upgrade_authority::*; +pub use transfer_admin::*; +pub use update_base_metadata_url::*; diff --git a/programs/doom-nft-program/src/instructions/reserve_token_id.rs b/programs/doom-nft-program/src/instructions/reserve_token_id.rs new file mode 100644 index 0000000..22e874f --- /dev/null +++ b/programs/doom-nft-program/src/instructions/reserve_token_id.rs @@ -0,0 +1,57 @@ +use anchor_lang::prelude::*; + +use crate::{ + constants::{GLOBAL_CONFIG_SEED, RESERVATION_SEED}, + error::DoomNftProgramError, + events::TokenReserved, + state::{GlobalConfig, MintReservation}, +}; + +#[derive(Accounts)] +pub struct ReserveTokenId<'info> { + #[account( + mut, + seeds = [GLOBAL_CONFIG_SEED], + bump = global_config.bump + )] + pub global_config: Account<'info, GlobalConfig>, + + #[account( + init, + payer = user, + space = 8 + MintReservation::INIT_SPACE, + seeds = [RESERVATION_SEED, global_config.next_token_id.to_le_bytes().as_ref()], + bump + )] + pub reservation: Account<'info, MintReservation>, + + #[account(mut)] + pub user: Signer<'info>, + + pub system_program: Program<'info, System>, +} + +pub fn process_reserve_token_id(ctx: Context) -> Result<()> { + let global_config = &mut ctx.accounts.global_config; + require!(!global_config.mint_paused, DoomNftProgramError::MintPaused); + + let token_id = global_config.next_token_id; + global_config.next_token_id = global_config + .next_token_id + .checked_add(1) + .ok_or(DoomNftProgramError::TokenIdOverflow)?; + + let reservation = &mut ctx.accounts.reservation; + reservation.token_id = token_id; + reservation.reserver = ctx.accounts.user.key(); + reservation.minted = false; + reservation.bump = ctx.bumps.reservation; + + emit!(TokenReserved { + token_id, + reserver: reservation.reserver, + reservation: ctx.accounts.reservation.key(), + }); + + Ok(()) +} diff --git a/programs/doom-nft-program/src/instructions/set_mint_paused.rs b/programs/doom-nft-program/src/instructions/set_mint_paused.rs new file mode 100644 index 0000000..ea62812 --- /dev/null +++ b/programs/doom-nft-program/src/instructions/set_mint_paused.rs @@ -0,0 +1,21 @@ +use anchor_lang::prelude::*; + +use crate::{constants::GLOBAL_CONFIG_SEED, error::DoomNftProgramError, state::GlobalConfig}; + +#[derive(Accounts)] +pub struct SetMintPaused<'info> { + #[account( + mut, + seeds = [GLOBAL_CONFIG_SEED], + bump = global_config.bump, + has_one = admin @ DoomNftProgramError::Unauthorized + )] + pub global_config: Account<'info, GlobalConfig>, + + pub admin: Signer<'info>, +} + +pub fn process_set_mint_paused(ctx: Context, paused: bool) -> Result<()> { + ctx.accounts.global_config.mint_paused = paused; + Ok(()) +} diff --git a/programs/doom-nft-program/src/instructions/set_upgrade_authority.rs b/programs/doom-nft-program/src/instructions/set_upgrade_authority.rs new file mode 100644 index 0000000..34c2697 --- /dev/null +++ b/programs/doom-nft-program/src/instructions/set_upgrade_authority.rs @@ -0,0 +1,35 @@ +use anchor_lang::prelude::*; + +use crate::{ + constants::GLOBAL_CONFIG_SEED, error::DoomNftProgramError, events::UpgradeAuthorityUpdated, + state::GlobalConfig, +}; + +#[derive(Accounts)] +pub struct SetUpgradeAuthority<'info> { + #[account( + mut, + seeds = [GLOBAL_CONFIG_SEED], + bump = global_config.bump, + has_one = upgrade_authority @ DoomNftProgramError::Unauthorized + )] + pub global_config: Account<'info, GlobalConfig>, + + pub upgrade_authority: Signer<'info>, +} + +pub fn process_set_upgrade_authority( + ctx: Context, + new_upgrade_authority: Pubkey, +) -> Result<()> { + let global_config = &mut ctx.accounts.global_config; + let old_upgrade_authority = global_config.upgrade_authority; + global_config.upgrade_authority = new_upgrade_authority; + + emit!(UpgradeAuthorityUpdated { + old_upgrade_authority, + new_upgrade_authority, + }); + + Ok(()) +} diff --git a/programs/doom-nft-program/src/instructions/transfer_admin.rs b/programs/doom-nft-program/src/instructions/transfer_admin.rs new file mode 100644 index 0000000..6cc495c --- /dev/null +++ b/programs/doom-nft-program/src/instructions/transfer_admin.rs @@ -0,0 +1,24 @@ +use anchor_lang::prelude::*; + +use crate::{constants::GLOBAL_CONFIG_SEED, error::DoomNftProgramError, state::GlobalConfig}; + +#[derive(Accounts)] +pub struct TransferAdmin<'info> { + #[account( + mut, + seeds = [GLOBAL_CONFIG_SEED], + bump = global_config.bump, + has_one = admin @ DoomNftProgramError::Unauthorized, + has_one = upgrade_authority @ DoomNftProgramError::Unauthorized + )] + pub global_config: Account<'info, GlobalConfig>, + + pub admin: Signer<'info>, + pub upgrade_authority: Signer<'info>, + pub new_admin: Signer<'info>, +} + +pub fn process_transfer_admin(ctx: Context) -> Result<()> { + ctx.accounts.global_config.admin = ctx.accounts.new_admin.key(); + Ok(()) +} diff --git a/programs/doom-nft-program/src/instructions/update_base_metadata_url.rs b/programs/doom-nft-program/src/instructions/update_base_metadata_url.rs new file mode 100644 index 0000000..925421c --- /dev/null +++ b/programs/doom-nft-program/src/instructions/update_base_metadata_url.rs @@ -0,0 +1,37 @@ +use anchor_lang::prelude::*; + +use crate::{ + constants::GLOBAL_CONFIG_SEED, error::DoomNftProgramError, events::BaseMetadataUrlUpdated, + state::GlobalConfig, utils::validate_base_metadata_url, +}; + +#[derive(Accounts)] +pub struct UpdateBaseMetadataUrl<'info> { + #[account( + mut, + seeds = [GLOBAL_CONFIG_SEED], + bump = global_config.bump, + has_one = admin @ DoomNftProgramError::Unauthorized + )] + pub global_config: Account<'info, GlobalConfig>, + + pub admin: Signer<'info>, +} + +pub fn process_update_base_metadata_url( + ctx: Context, + base_metadata_url: String, +) -> Result<()> { + validate_base_metadata_url(&base_metadata_url)?; + + let global_config = &mut ctx.accounts.global_config; + let old_base_url = global_config.base_metadata_url.clone(); + global_config.base_metadata_url = base_metadata_url.clone(); + + emit!(BaseMetadataUrlUpdated { + old_base_url, + new_base_url: base_metadata_url, + }); + + Ok(()) +} diff --git a/programs/doom-nft-program/src/lib.rs b/programs/doom-nft-program/src/lib.rs index 7b8dcf4..1f07907 100644 --- a/programs/doom-nft-program/src/lib.rs +++ b/programs/doom-nft-program/src/lib.rs @@ -1,143 +1,81 @@ -use anchor_lang::prelude::*; -use anchor_spl::{ - associated_token::AssociatedToken, - token::{self, Mint, Token, TokenAccount, Transfer}, -}; - -declare_id!("AavECgzCbVhHeBGAfcUgT1tYEC4N4B96E8XtF9H1fMGt"); - -#[program] -pub mod doom_nft_program { - use super::*; +pub mod constants; +pub mod error; +pub mod events; +pub mod instructions; +pub mod state; +pub mod utils; - pub fn create_mint(ctx: Context) -> Result<()> { - msg!("Creating NFT mint: {}", ctx.accounts.mint.key()); - Ok(()) - } - - pub fn mint_token(ctx: Context) -> Result<()> { - msg!("Minting NFT token to: {}", ctx.accounts.token_account.key()); +use anchor_lang::prelude::*; - // Mint exactly 1 token (NFT) - token::mint_to( - CpiContext::new( - ctx.accounts.token_program.to_account_info(), - token::MintTo { - mint: ctx.accounts.mint.to_account_info(), - to: ctx.accounts.token_account.to_account_info(), - authority: ctx.accounts.mint_authority.to_account_info(), - }, - ), - 1, // NFTなので1個のみ - )?; +pub use constants::*; +pub use error::*; +pub use events::*; +pub use instructions::*; +pub use state::*; - msg!("NFT token minted successfully!"); - Ok(()) - } +declare_id!("u929SRVcCFcGM2iyYkMykDRq7xW4N9ozEMU3Vo1hgfP"); - pub fn transfer_token(ctx: Context) -> Result<()> { - msg!( - "Transferring NFT from {} to {}", - ctx.accounts.from.key(), - ctx.accounts.to.key() - ); +mod anchor_api { + #![allow(deprecated)] // Anchor 0.31 expands #[program] through deprecated AccountInfo::realloc generated code. - // Transfer exactly 1 token (NFT) - token::transfer( - CpiContext::new( - ctx.accounts.token_program.to_account_info(), - Transfer { - from: ctx.accounts.from_token_account.to_account_info(), - to: ctx.accounts.to_token_account.to_account_info(), - authority: ctx.accounts.from.to_account_info(), - }, - ), - 1, // NFTなので1個 - )?; + use super::*; - msg!("NFT transferred successfully!"); - Ok(()) + #[program] + pub mod doom_nft_program { + use super::*; + + pub fn initialize_global_config( + ctx: Context, + base_metadata_url: String, + upgrade_authority: Pubkey, + ) -> Result<()> { + instructions::initialize_global_config::process_initialize_global_config( + ctx, + base_metadata_url, + upgrade_authority, + ) + } + + pub fn initialize_collection(ctx: Context) -> Result<()> { + instructions::initialize_collection::process_initialize_collection(ctx) + } + + pub fn reserve_token_id(ctx: Context) -> Result<()> { + instructions::reserve_token_id::process_reserve_token_id(ctx) + } + + pub fn mint_doom_index_nft(ctx: Context, token_id: u64) -> Result<()> { + instructions::mint_doom_index_nft::process_mint_doom_index_nft(ctx, token_id) + } + + pub fn update_base_metadata_url( + ctx: Context, + base_metadata_url: String, + ) -> Result<()> { + instructions::update_base_metadata_url::process_update_base_metadata_url( + ctx, + base_metadata_url, + ) + } + + pub fn set_mint_paused(ctx: Context, paused: bool) -> Result<()> { + instructions::set_mint_paused::process_set_mint_paused(ctx, paused) + } + + pub fn transfer_admin(ctx: Context) -> Result<()> { + instructions::transfer_admin::process_transfer_admin(ctx) + } + + pub fn set_upgrade_authority( + ctx: Context, + new_upgrade_authority: Pubkey, + ) -> Result<()> { + instructions::set_upgrade_authority::process_set_upgrade_authority( + ctx, + new_upgrade_authority, + ) + } } } -#[derive(Accounts)] -pub struct CreateMint<'info> { - #[account( - init, - payer = payer, - mint::decimals = 0, // NFTなので小数点以下なし - mint::authority = mint_authority, - mint::freeze_authority = mint_authority, - )] - pub mint: Account<'info, Mint>, - - #[account(mut)] - pub payer: Signer<'info>, - - /// CHECK: The mint authority - pub mint_authority: Signer<'info>, - - pub token_program: Program<'info, Token>, - pub system_program: Program<'info, System>, - pub rent: Sysvar<'info, Rent>, -} - -#[derive(Accounts)] -pub struct MintToken<'info> { - #[account( - mut, - mint::authority = mint_authority, - mint::freeze_authority = mint_authority, - )] - pub mint: Account<'info, Mint>, - - #[account( - init, - payer = payer, - associated_token::mint = mint, - associated_token::authority = recipient, - )] - pub token_account: Account<'info, TokenAccount>, - - #[account(mut)] - pub payer: Signer<'info>, - - /// CHECK: The mint authority - pub mint_authority: Signer<'info>, - - /// CHECK: The recipient of the NFT - pub recipient: AccountInfo<'info>, - - pub token_program: Program<'info, Token>, - pub associated_token_program: Program<'info, AssociatedToken>, - pub system_program: Program<'info, System>, - pub rent: Sysvar<'info, Rent>, -} - -#[derive(Accounts)] -pub struct TransferToken<'info> { - #[account(mut)] - pub mint: Account<'info, Mint>, - - #[account( - mut, - associated_token::mint = mint, - associated_token::authority = from, - )] - pub from_token_account: Account<'info, TokenAccount>, - - #[account( - mut, - associated_token::mint = mint, - associated_token::authority = to, - )] - pub to_token_account: Account<'info, TokenAccount>, - - #[account(mut)] - pub from: Signer<'info>, - - /// CHECK: The recipient of the NFT - pub to: AccountInfo<'info>, - - pub token_program: Program<'info, Token>, -} +pub use anchor_api::*; diff --git a/programs/doom-nft-program/src/state/global_config.rs b/programs/doom-nft-program/src/state/global_config.rs new file mode 100644 index 0000000..48e08e3 --- /dev/null +++ b/programs/doom-nft-program/src/state/global_config.rs @@ -0,0 +1,15 @@ +use anchor_lang::prelude::*; + +#[account] +#[derive(InitSpace)] +pub struct GlobalConfig { + pub admin: Pubkey, + pub upgrade_authority: Pubkey, + pub next_token_id: u64, + pub mint_paused: bool, + #[max_len(256)] + pub base_metadata_url: String, + pub collection: Pubkey, + pub collection_update_authority: Pubkey, + pub bump: u8, +} diff --git a/programs/doom-nft-program/src/state/mint_reservation.rs b/programs/doom-nft-program/src/state/mint_reservation.rs new file mode 100644 index 0000000..c689a77 --- /dev/null +++ b/programs/doom-nft-program/src/state/mint_reservation.rs @@ -0,0 +1,10 @@ +use anchor_lang::prelude::*; + +#[account] +#[derive(InitSpace)] +pub struct MintReservation { + pub token_id: u64, + pub reserver: Pubkey, + pub minted: bool, + pub bump: u8, +} diff --git a/programs/doom-nft-program/src/state/mod.rs b/programs/doom-nft-program/src/state/mod.rs new file mode 100644 index 0000000..bed9a30 --- /dev/null +++ b/programs/doom-nft-program/src/state/mod.rs @@ -0,0 +1,5 @@ +pub mod global_config; +pub mod mint_reservation; + +pub use global_config::*; +pub use mint_reservation::*; diff --git a/programs/doom-nft-program/src/utils.rs b/programs/doom-nft-program/src/utils.rs new file mode 100644 index 0000000..a43c25e --- /dev/null +++ b/programs/doom-nft-program/src/utils.rs @@ -0,0 +1,61 @@ +use anchor_lang::prelude::*; +use url::Url; + +use crate::{constants::COLLECTION_NAME, error::DoomNftProgramError}; + +pub fn validate_base_metadata_url(base_metadata_url: &str) -> Result<()> { + let trimmed = base_metadata_url.trim(); + require!( + !trimmed.is_empty() + && trimmed == base_metadata_url + && trimmed.len() <= 256 + && !trimmed.ends_with('/') + && matches!(Url::parse(trimmed), Ok(url) if url.scheme() == "https"), + DoomNftProgramError::BaseMetadataUrlInvalid + ); + + Ok(()) +} + +pub fn build_collection_uri(base_metadata_url: &str) -> String { + format!("{base_metadata_url}/collection.json") +} + +pub fn build_asset_name(token_id: u64) -> String { + format!("{COLLECTION_NAME} #{token_id}") +} + +pub fn build_asset_uri(base_metadata_url: &str, token_id: u64) -> String { + format!("{base_metadata_url}/{token_id}.json") +} + +#[cfg(test)] +mod tests { + use super::validate_base_metadata_url; + + #[test] + fn accepts_https_url_without_trailing_slash() { + assert!(validate_base_metadata_url("https://example.com/base").is_ok()); + } + + #[test] + fn rejects_non_https_url() { + assert!(validate_base_metadata_url("http://example.com/base").is_err()); + } + + #[test] + fn rejects_whitespace_padded_url() { + assert!(validate_base_metadata_url(" https://example.com/base ").is_err()); + } + + #[test] + fn rejects_trailing_slash() { + assert!(validate_base_metadata_url("https://example.com/base/").is_err()); + } + + #[test] + fn rejects_overlong_url() { + let overlong = format!("https://example.com/{}", "a".repeat(300)); + assert!(validate_base_metadata_url(&overlong).is_err()); + } +} diff --git a/scripts/build-test-sbf.sh b/scripts/build-test-sbf.sh new file mode 100755 index 0000000..3f0743b --- /dev/null +++ b/scripts/build-test-sbf.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +OUT_DIR="$ROOT_DIR/target/test-sbf" +FIXTURE_DIR="$ROOT_DIR/tests/fixtures" +PINNED_MPL_CORE_SO="$FIXTURE_DIR/mpl_core_program.so" +PINNED_MPL_CORE_SHA="$FIXTURE_DIR/mpl_core_program.so.sha256" + +mkdir -p "$OUT_DIR" + +if [[ ! -f "$PINNED_MPL_CORE_SO" ]]; then + echo "Missing pinned Metaplex Core fixture at $PINNED_MPL_CORE_SO" >&2 + exit 1 +fi + +if [[ -f "$PINNED_MPL_CORE_SHA" ]]; then + ( + cd "$FIXTURE_DIR" + shasum -a 256 -c "$(basename "$PINNED_MPL_CORE_SHA")" + ) +fi + +cp "$PINNED_MPL_CORE_SO" "$OUT_DIR/mpl_core_program.so" diff --git a/scripts/devnet/common.test.ts b/scripts/devnet/common.test.ts new file mode 100644 index 0000000..75edee3 --- /dev/null +++ b/scripts/devnet/common.test.ts @@ -0,0 +1,129 @@ +import assert from "node:assert/strict"; +import { mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { afterEach, describe, test } from "node:test"; + +import { BN, web3 } from "@coral-xyz/anchor"; + +import { loadOrCreateKeypair, resolveWalletPath, reserveTokenId } from "./common"; + +const originalAnchorWallet = process.env.ANCHOR_WALLET; +const originalHome = process.env.HOME; + +afterEach(() => { + if (originalAnchorWallet === undefined) { + delete process.env.ANCHOR_WALLET; + } else { + process.env.ANCHOR_WALLET = originalAnchorWallet; + } + + if (originalHome === undefined) { + delete process.env.HOME; + } else { + process.env.HOME = originalHome; + } +}); + +describe("resolveWalletPath", () => { + test("prefers ANCHOR_WALLET when it is set", () => { + process.env.ANCHOR_WALLET = "/tmp/custom-wallet.json"; + + assert.equal(resolveWalletPath("/tmp/unused/Anchor.toml"), "/tmp/custom-wallet.json"); + }); + + test("uses provider.wallet from Anchor.toml when ANCHOR_WALLET is unset", () => { + delete process.env.ANCHOR_WALLET; + + const tempDir = mkdtempSync(join(tmpdir(), "doom-anchor-wallet-")); + const anchorTomlPath = join(tempDir, "Anchor.toml"); + + try { + writeFileSync( + anchorTomlPath, + ["[provider]", 'cluster = "devnet"', 'wallet = "target/devnet/deployer.json"', ""].join("\n"), + "utf8", + ); + + assert.equal(resolveWalletPath(anchorTomlPath), join(tempDir, "target/devnet/deployer.json")); + } finally { + rmSync(tempDir, { recursive: true, force: true }); + } + }); + + test("falls back to the stable default wallet when provider.wallet is missing", () => { + delete process.env.ANCHOR_WALLET; + process.env.HOME = "/tmp/home-dir"; + + const tempDir = mkdtempSync(join(tmpdir(), "doom-anchor-wallet-")); + const anchorTomlPath = join(tempDir, "Anchor.toml"); + + try { + writeFileSync(anchorTomlPath, ["[provider]", 'cluster = "localnet"', ""].join("\n"), "utf8"); + + assert.equal(resolveWalletPath(anchorTomlPath), "/tmp/home-dir/.config/solana/id.json"); + } finally { + rmSync(tempDir, { recursive: true, force: true }); + } + }); +}); + +describe("loadOrCreateKeypair", () => { + test("creates a new keypair file with owner-only permissions", () => { + const tempDir = mkdtempSync(join(tmpdir(), "doom-keypair-")); + const keypairPath = join(tempDir, "keypair.json"); + + try { + const keypair = loadOrCreateKeypair(keypairPath); + const storedSecret = JSON.parse(readFileSync(keypairPath, "utf8")) as number[]; + + assert.deepEqual(storedSecret, Array.from(keypair.secretKey)); + assert.equal(statSync(keypairPath).mode & 0o777, 0o600); + } finally { + rmSync(tempDir, { recursive: true, force: true }); + } + }); +}); + +describe("reserveTokenId", () => { + test("retries after a reservation contention error and recomputes the reservation PDA", async () => { + const payer = web3.Keypair.generate(); + const seenReservations: string[] = []; + let fetchCount = 0; + let sendCount = 0; + + const result = await reserveTokenId({} as web3.Connection, payer, undefined, { + fetchGlobalConfig: async () => { + fetchCount += 1; + const nextTokenId = fetchCount === 1 ? new BN(1) : new BN(2); + return { + admin: payer.publicKey, + upgradeAuthority: payer.publicKey, + nextTokenId, + mintPaused: false, + baseMetadataUrl: "https://example.com/base", + collection: payer.publicKey, + collectionUpdateAuthority: payer.publicKey, + bump: 255, + }; + }, + sendInstructions: async (_connection, _payer, instructions) => { + sendCount += 1; + seenReservations.push(instructions[0].keys[1].pubkey.toBase58()); + if (sendCount === 1) { + throw new Error("Allocate: account Address already in use"); + } + + return "retry-signature"; + }, + backoffMs: 0, + }); + + assert.equal(result.signature, "retry-signature"); + assert.equal(result.tokenId.toString(), "2"); + assert.equal(seenReservations.length, 2); + assert.notEqual(seenReservations[0], seenReservations[1]); + assert.equal(result.reservation.toBase58(), seenReservations[1]); + assert.equal(result.globalConfig.nextTokenId.toString(), "2"); + }); +}); diff --git a/scripts/devnet/common.ts b/scripts/devnet/common.ts new file mode 100644 index 0000000..4ef0a6b --- /dev/null +++ b/scripts/devnet/common.ts @@ -0,0 +1,375 @@ +import { BN, web3 } from "@coral-xyz/anchor"; +import * as borsh from "@coral-xyz/borsh"; +import { createHash } from "node:crypto"; +import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; +import { dirname, isAbsolute, resolve } from "node:path"; + +const { + Connection, + Keypair, + PublicKey, + SystemProgram, + Transaction, + TransactionInstruction, + sendAndConfirmTransaction, +} = web3; + +export { Keypair, PublicKey, SystemProgram, TransactionInstruction }; + +export const DEFAULT_PROGRAM_ID = new PublicKey( + process.env.PROGRAM_ID ?? "u929SRVcCFcGM2iyYkMykDRq7xW4N9ozEMU3Vo1hgfP", +); +export const MPL_CORE_PROGRAM_ID = new PublicKey("CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d"); +const DEFAULT_PROVIDER_WALLET = "~/.config/solana/id.json"; +const SCRIPT_DIR = __dirname; +const DEFAULT_ANCHOR_TOML_PATH = resolve(SCRIPT_DIR, "..", "..", "Anchor.toml"); + +const GLOBAL_CONFIG_SEED = Buffer.from("global_config"); +const RESERVATION_SEED = Buffer.from("reservation"); +const COLLECTION_AUTHORITY_SEED = Buffer.from("collection_authority"); +const GLOBAL_CONFIG_DISCRIMINATOR = accountDiscriminator("GlobalConfig"); + +const GLOBAL_CONFIG_LAYOUT = borsh.struct([ + borsh.publicKey("admin"), + borsh.publicKey("upgradeAuthority"), + borsh.u64("nextTokenId"), + borsh.bool("mintPaused"), + borsh.str("baseMetadataUrl"), + borsh.publicKey("collection"), + borsh.publicKey("collectionUpdateAuthority"), + borsh.u8("bump"), +]); + +export type GlobalConfigAccount = { + admin: web3.PublicKey; + upgradeAuthority: web3.PublicKey; + nextTokenId: BN; + mintPaused: boolean; + baseMetadataUrl: string; + collection: web3.PublicKey; + collectionUpdateAuthority: web3.PublicKey; + bump: number; +}; + +type ReserveTokenIdOptions = { + fetchGlobalConfig?: typeof fetchGlobalConfig; + sendInstructions?: typeof sendInstructions; + maxAttempts?: number; + backoffMs?: number; +}; + +export function getConnection(): web3.Connection { + return new Connection(process.env.ANCHOR_PROVIDER_URL ?? "https://api.devnet.solana.com", "confirmed"); +} + +export function loadWallet(): web3.Keypair { + return loadKeypair(resolveWalletPath()); +} + +export function resolveWalletPath(anchorTomlPath: string = DEFAULT_ANCHOR_TOML_PATH): string { + const walletPath = process.env.ANCHOR_WALLET ?? readProviderWalletPath(anchorTomlPath) ?? DEFAULT_PROVIDER_WALLET; + return resolveConfiguredPath(walletPath, anchorTomlPath); +} + +export function loadKeypair(filePath: string): web3.Keypair { + const secretKey = Uint8Array.from(JSON.parse(readFileSync(resolve(filePath), "utf8")) as number[]); + return Keypair.fromSecretKey(secretKey); +} + +export function loadOrCreateKeypair(filePath: string): web3.Keypair { + const absolutePath = resolve(filePath); + try { + return loadKeypair(absolutePath); + } catch (error) { + if ((error as NodeJS.ErrnoException).code !== "ENOENT") { + throw error; + } + } + + mkdirSync(dirname(absolutePath), { recursive: true }); + const keypair = Keypair.generate(); + try { + writeFileSync(absolutePath, JSON.stringify(Array.from(keypair.secretKey)), { + encoding: "utf8", + flag: "wx", + mode: 0o600, + }); + return keypair; + } catch (error) { + if ((error as NodeJS.ErrnoException).code === "EEXIST") { + return loadKeypair(absolutePath); + } + + throw error; + } +} + +export function writeJson(filePath: string, payload: unknown): void { + const absolutePath = resolve(filePath); + mkdirSync(dirname(absolutePath), { recursive: true }); + writeFileSync(absolutePath, JSON.stringify(payload, null, 2), "utf8"); +} + +export function readJson(filePath: string): T { + return JSON.parse(readFileSync(resolve(filePath), "utf8")) as T; +} + +export function globalConfigPda(programId: web3.PublicKey = DEFAULT_PROGRAM_ID): [web3.PublicKey, number] { + return PublicKey.findProgramAddressSync([GLOBAL_CONFIG_SEED], programId); +} + +export function collectionAuthorityPda( + globalConfig: web3.PublicKey, + programId: web3.PublicKey = DEFAULT_PROGRAM_ID, +): [web3.PublicKey, number] { + return PublicKey.findProgramAddressSync([COLLECTION_AUTHORITY_SEED, globalConfig.toBuffer()], programId); +} + +export function reservationPda( + tokenId: bigint, + programId: web3.PublicKey = DEFAULT_PROGRAM_ID, +): [web3.PublicKey, number] { + const tokenIdBuffer = Buffer.alloc(8); + tokenIdBuffer.writeBigUInt64LE(tokenId); + return PublicKey.findProgramAddressSync([RESERVATION_SEED, tokenIdBuffer], programId); +} + +export async function fetchGlobalConfig( + connection: web3.Connection, + programId: web3.PublicKey = DEFAULT_PROGRAM_ID, +): Promise { + const [config] = globalConfigPda(programId); + const account = await connection.getAccountInfo(config, "confirmed"); + if (!account) { + throw new Error(`GlobalConfig not found at ${config.toBase58()}`); + } + + const discriminator = account.data.subarray(0, 8); + if (!discriminator.equals(GLOBAL_CONFIG_DISCRIMINATOR)) { + throw new Error("GlobalConfig discriminator mismatch"); + } + + return GLOBAL_CONFIG_LAYOUT.decode(account.data.subarray(8)) as GlobalConfigAccount; +} + +export function buildMetadataUri(baseMetadataUrl: string, tokenId: bigint): string { + return `${baseMetadataUrl}/${tokenId.toString()}.json`; +} + +export function createInstruction( + name: string, + argsLayout: borsh.Layout, + args: Record, + keys: web3.AccountMeta[], + programId: web3.PublicKey = DEFAULT_PROGRAM_ID, +): web3.TransactionInstruction { + const discriminator = instructionDiscriminator(name); + const argsBuffer = Buffer.alloc(1024); + const encodedLength = argsLayout.encode(args, argsBuffer); + const data = Buffer.concat([discriminator, argsBuffer.subarray(0, encodedLength)]); + + return new TransactionInstruction({ programId, keys, data }); +} + +export async function sendInstructions( + connection: web3.Connection, + payer: web3.Keypair, + instructions: web3.TransactionInstruction[], + signers: web3.Keypair[] = [], +): Promise { + const transaction = new Transaction().add(...instructions); + const signature = await sendAndConfirmTransaction(connection, transaction, [payer, ...signers], { + commitment: "confirmed", + }); + + return signature; +} + +export function initializeGlobalConfigInstruction( + admin: web3.PublicKey, + baseMetadataUrl: string, + upgradeAuthority: web3.PublicKey, + programId: web3.PublicKey = DEFAULT_PROGRAM_ID, +): web3.TransactionInstruction { + const [globalConfig] = globalConfigPda(programId); + return createInstruction( + "initialize_global_config", + borsh.struct([borsh.str("baseMetadataUrl"), borsh.publicKey("upgradeAuthority")]), + { baseMetadataUrl, upgradeAuthority }, + [ + { pubkey: globalConfig, isSigner: false, isWritable: true }, + { pubkey: admin, isSigner: true, isWritable: true }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + programId, + ); +} + +export function initializeCollectionInstruction( + admin: web3.PublicKey, + collection: web3.PublicKey, + programId: web3.PublicKey = DEFAULT_PROGRAM_ID, +): web3.TransactionInstruction { + const [globalConfig] = globalConfigPda(programId); + const [collectionAuthority] = collectionAuthorityPda(globalConfig, programId); + return createInstruction( + "initialize_collection", + borsh.struct([]), + {}, + [ + { pubkey: globalConfig, isSigner: false, isWritable: true }, + { pubkey: admin, isSigner: true, isWritable: true }, + { pubkey: collection, isSigner: true, isWritable: true }, + { pubkey: collectionAuthority, isSigner: false, isWritable: false }, + { pubkey: MPL_CORE_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + programId, + ); +} + +export async function reserveTokenId( + connection: web3.Connection, + payer: web3.Keypair, + programId: web3.PublicKey = DEFAULT_PROGRAM_ID, + options: ReserveTokenIdOptions = {}, +): Promise<{ + signature: string; + tokenId: bigint; + reservation: web3.PublicKey; + globalConfig: GlobalConfigAccount; +}> { + const fetchGlobalConfigImpl = options.fetchGlobalConfig ?? fetchGlobalConfig; + const sendInstructionsImpl = options.sendInstructions ?? sendInstructions; + const maxAttempts = options.maxAttempts ?? 4; + const backoffMs = options.backoffMs ?? 200; + + for (let attempt = 1; attempt <= maxAttempts; attempt += 1) { + const before = await fetchGlobalConfigImpl(connection, programId); + const tokenId = BigInt(before.nextTokenId.toString()); + const [globalConfig] = globalConfigPda(programId); + const [reservation] = reservationPda(tokenId, programId); + + const instruction = createInstruction( + "reserve_token_id", + borsh.struct([]), + {}, + [ + { pubkey: globalConfig, isSigner: false, isWritable: true }, + { pubkey: reservation, isSigner: false, isWritable: true }, + { pubkey: payer.publicKey, isSigner: true, isWritable: true }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + programId, + ); + + try { + const signature = await sendInstructionsImpl(connection, payer, [instruction]); + const after = await fetchGlobalConfigImpl(connection, programId); + return { signature, tokenId, reservation, globalConfig: after }; + } catch (error) { + if (attempt === maxAttempts || !isReservationContentionError(error)) { + throw error; + } + + if (backoffMs > 0) { + await sleep(backoffMs); + } + } + } + + throw new Error("reserveTokenId exhausted retries without a terminal error"); +} + +export function mintDoomIndexNftInstruction( + user: web3.PublicKey, + tokenId: bigint, + asset: web3.PublicKey, + collection: web3.PublicKey, + programId: web3.PublicKey = DEFAULT_PROGRAM_ID, +): web3.TransactionInstruction { + const [globalConfig] = globalConfigPda(programId); + const [reservation] = reservationPda(tokenId, programId); + const [collectionAuthority] = collectionAuthorityPda(globalConfig, programId); + + return createInstruction( + "mint_doom_index_nft", + borsh.struct([borsh.u64("tokenId")]), + { tokenId: new BN(tokenId.toString()) }, + [ + { pubkey: globalConfig, isSigner: false, isWritable: false }, + { pubkey: reservation, isSigner: false, isWritable: true }, + { pubkey: user, isSigner: true, isWritable: true }, + { pubkey: asset, isSigner: true, isWritable: true }, + { pubkey: collectionAuthority, isSigner: false, isWritable: false }, + { pubkey: collection, isSigner: false, isWritable: true }, + { pubkey: MPL_CORE_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + programId, + ); +} + +function instructionDiscriminator(name: string): Buffer { + return createHash("sha256").update(`global:${name}`).digest().subarray(0, 8); +} + +function isReservationContentionError(error: unknown): boolean { + const text = [ + error instanceof Error ? error.message : "", + error instanceof Error ? error.toString() : String(error), + typeof error === "object" && error !== null && "logs" in error && Array.isArray((error as { logs?: unknown }).logs) + ? ((error as { logs: string[] }).logs ?? []).join("\n") + : "", + ] + .join("\n") + .toLowerCase(); + + return text.includes("already in use"); +} + +async function sleep(milliseconds: number): Promise { + await new Promise((resolvePromise) => setTimeout(resolvePromise, milliseconds)); +} + +function accountDiscriminator(name: string): Buffer { + return createHash("sha256").update(`account:${name}`).digest().subarray(0, 8); +} + +function readProviderWalletPath(anchorTomlPath: string): string | null { + if (!existsSync(anchorTomlPath)) { + return null; + } + + const lines = readFileSync(anchorTomlPath, "utf8").split(/\r?\n/); + let inProviderSection = false; + + for (const line of lines) { + const trimmedLine = line.trim(); + + if (trimmedLine.startsWith("[") && trimmedLine.endsWith("]")) { + inProviderSection = trimmedLine === "[provider]"; + continue; + } + + if (!inProviderSection || trimmedLine.startsWith("#")) { + continue; + } + + const walletMatch = trimmedLine.match(/^wallet\s*=\s*"([^"]+)"$/); + if (walletMatch) { + return walletMatch[1]; + } + } + + return null; +} + +function resolveConfiguredPath(filePath: string, anchorTomlPath: string): string { + const expandedPath = filePath.replace(/^~(?=$|\/|\\)/, process.env.HOME ?? ""); + if (isAbsolute(expandedPath)) { + return expandedPath; + } + + return resolve(dirname(anchorTomlPath), expandedPath); +} diff --git a/scripts/devnet/init.ts b/scripts/devnet/init.ts new file mode 100644 index 0000000..016ecae --- /dev/null +++ b/scripts/devnet/init.ts @@ -0,0 +1,77 @@ +import { + DEFAULT_PROGRAM_ID, + fetchGlobalConfig, + getConnection, + initializeCollectionInstruction, + initializeGlobalConfigInstruction, + loadOrCreateKeypair, + loadWallet, + sendInstructions, + writeJson, +} from "./common"; + +async function main(): Promise { + const baseMetadataUrl = process.env.BASE_METADATA_URL; + if (!baseMetadataUrl) { + throw new Error("BASE_METADATA_URL is required"); + } + if (baseMetadataUrl.trim() !== baseMetadataUrl) { + throw new Error("BASE_METADATA_URL must not contain leading or trailing whitespace"); + } + if (!baseMetadataUrl.startsWith("https://")) { + throw new Error("BASE_METADATA_URL must use https"); + } + try { + new URL(baseMetadataUrl); + } catch { + throw new Error("BASE_METADATA_URL must be a valid URL"); + } + if (baseMetadataUrl.endsWith("/")) { + throw new Error("BASE_METADATA_URL must not end with a trailing slash"); + } + if (Buffer.byteLength(baseMetadataUrl, "utf8") > 256) { + throw new Error("BASE_METADATA_URL must be 256 bytes or fewer"); + } + + const connection = getConnection(); + const payer = loadWallet(); + const upgradeAuthority = loadOrCreateKeypair( + process.env.UPGRADE_AUTHORITY_KEYPAIR ?? "target/devnet/upgrade-authority.json", + ); + const collection = loadOrCreateKeypair(process.env.COLLECTION_KEYPAIR ?? "target/devnet/collection.json"); + + const initializeConfigIx = initializeGlobalConfigInstruction( + payer.publicKey, + baseMetadataUrl, + upgradeAuthority.publicKey, + DEFAULT_PROGRAM_ID, + ); + const initializeCollectionIx = initializeCollectionInstruction( + payer.publicKey, + collection.publicKey, + DEFAULT_PROGRAM_ID, + ); + + const configSignature = await sendInstructions(connection, payer, [initializeConfigIx]); + const collectionSignature = await sendInstructions(connection, payer, [initializeCollectionIx], [collection]); + + const globalConfig = await fetchGlobalConfig(connection); + const output = { + programId: DEFAULT_PROGRAM_ID.toBase58(), + configSignature, + collectionSignature, + admin: payer.publicKey.toBase58(), + upgradeAuthority: upgradeAuthority.publicKey.toBase58(), + collection: collection.publicKey.toBase58(), + baseMetadataUrl: globalConfig.baseMetadataUrl, + collectionUpdateAuthority: globalConfig.collectionUpdateAuthority.toBase58(), + }; + + writeJson("target/devnet/init.json", output); + console.log(JSON.stringify(output, null, 2)); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/devnet/mint.test.ts b/scripts/devnet/mint.test.ts new file mode 100644 index 0000000..b4befe2 --- /dev/null +++ b/scripts/devnet/mint.test.ts @@ -0,0 +1,61 @@ +import assert from "node:assert/strict"; +import { describe, test } from "node:test"; + +import { assertUrlReachable, decodeAssetUri } from "./mint"; + +describe("decodeAssetUri", () => { + test("returns the URI stored in the on-chain asset data", () => { + const accountData = Buffer.concat([ + Buffer.from([1]), + Buffer.alloc(32, 7), + Buffer.from([2]), + Buffer.alloc(32, 8), + encodeBorshString("DOOM INDEX #1"), + encodeBorshString("https://example.com/base/1.json"), + Buffer.from([0]), + Buffer.from([9, 9, 9]), + ]); + + assert.equal(decodeAssetUri(accountData), "https://example.com/base/1.json"); + }); +}); + +describe("assertUrlReachable", () => { + test("falls back to GET when HEAD is not supported", async () => { + const calls: Array<{ url: string; method: string }> = []; + await assertUrlReachable("https://example.com/asset.png", "Image", async (url, init) => { + calls.push({ url: String(url), method: init?.method ?? "GET" }); + if (init?.method === "HEAD") { + return new Response(null, { status: 405, statusText: "Method Not Allowed" }); + } + + return new Response("ok", { status: 200, statusText: "OK" }); + }); + + assert.deepEqual(calls, [ + { url: "https://example.com/asset.png", method: "HEAD" }, + { url: "https://example.com/asset.png", method: "GET" }, + ]); + }); + + test("throws when both HEAD and GET fail", async () => { + await assert.rejects( + () => + assertUrlReachable("https://example.com/asset.png", "Image", async (_url, init) => { + if (init?.method === "HEAD") { + return new Response(null, { status: 403, statusText: "Forbidden" }); + } + + return new Response(null, { status: 404, statusText: "Not Found" }); + }), + /Image fetch failed: 404 Not Found/, + ); + }); +}); + +function encodeBorshString(value: string): Buffer { + const text = Buffer.from(value, "utf8"); + const length = Buffer.alloc(4); + length.writeUInt32LE(text.length, 0); + return Buffer.concat([length, text]); +} diff --git a/scripts/devnet/mint.ts b/scripts/devnet/mint.ts new file mode 100644 index 0000000..42e7fd5 --- /dev/null +++ b/scripts/devnet/mint.ts @@ -0,0 +1,124 @@ +import { + fetchGlobalConfig, + getConnection, + Keypair, + MPL_CORE_PROGRAM_ID, + loadWallet, + mintDoomIndexNftInstruction, + readJson, + sendInstructions, + writeJson, +} from "./common"; + +type ReservationOutput = { + tokenId: string; +}; + +type FetchLike = typeof fetch; + +export function decodeAssetUri(accountData: Buffer | Uint8Array): string { + const data = Buffer.from(accountData); + let offset = 0; + + const key = data.readUInt8(offset); + offset += 1; + if (key !== 1) { + throw new Error(`Expected Metaplex Core AssetV1 account data, got key ${key}`); + } + + offset += 32; + + const updateAuthorityKind = data.readUInt8(offset); + offset += 1; + if (updateAuthorityKind === 1 || updateAuthorityKind === 2) { + offset += 32; + } else if (updateAuthorityKind !== 0) { + throw new Error(`Unknown Metaplex Core update authority kind ${updateAuthorityKind}`); + } + + const [, afterName] = readBorshString(data, offset); + const [uri] = readBorshString(data, afterName); + return uri; +} + +export async function assertUrlReachable(url: string, label: string, fetchImpl: FetchLike = fetch): Promise { + const headResponse = await fetchImpl(url, { method: "HEAD" }); + if (headResponse.ok) { + return; + } + + const getResponse = await fetchImpl(url, { method: "GET" }); + if (!getResponse.ok) { + throw new Error(`${label} fetch failed: ${getResponse.status} ${getResponse.statusText}`); + } +} + +async function main(): Promise { + const connection = getConnection(); + const payer = loadWallet(); + const globalConfig = await fetchGlobalConfig(connection); + const reservation = + process.env.TOKEN_ID !== undefined + ? { tokenId: process.env.TOKEN_ID } + : readJson("target/devnet/latest-reservation.json"); + const tokenId = BigInt(reservation.tokenId); + const asset = Keypair.generate(); + + const mintInstruction = mintDoomIndexNftInstruction( + payer.publicKey, + tokenId, + asset.publicKey, + globalConfig.collection, + ); + const signature = await sendInstructions(connection, payer, [mintInstruction], [asset]); + + const assetAccount = await connection.getAccountInfo(asset.publicKey, "confirmed"); + if (!assetAccount) { + throw new Error(`Asset account not found at ${asset.publicKey.toBase58()}`); + } + if (!assetAccount.owner.equals(MPL_CORE_PROGRAM_ID)) { + throw new Error(`Asset account ${asset.publicKey.toBase58()} is not owned by Metaplex Core`); + } + + const metadataUri = decodeAssetUri(assetAccount.data); + const metadataResponse = await fetch(metadataUri); + if (!metadataResponse.ok) { + throw new Error(`Metadata fetch failed: ${metadataResponse.status} ${metadataResponse.statusText}`); + } + const metadata = (await metadataResponse.json()) as { + image?: string; + animation_url?: string; + }; + if (!metadata.image || !metadata.animation_url) { + throw new Error("Metadata must include both image and animation_url"); + } + + await assertUrlReachable(metadata.image, "Image"); + await assertUrlReachable(metadata.animation_url, "animation_url"); + + const output = { + signature, + tokenId: tokenId.toString(), + asset: asset.publicKey.toBase58(), + metadataUri, + image: metadata.image, + animationUrl: metadata.animation_url, + }; + + writeJson("target/devnet/latest-mint.json", output); + console.log(JSON.stringify(output, null, 2)); +} + +function readBorshString(data: Buffer, offset: number): [string, number] { + const length = data.readUInt32LE(offset); + const start = offset + 4; + const end = start + length; + return [data.subarray(start, end).toString("utf8"), end]; +} + +if (require.main === module) { + main().catch((error) => { + console.error(error); + process.exitCode = 1; + }); +} diff --git a/scripts/devnet/reserve.ts b/scripts/devnet/reserve.ts new file mode 100644 index 0000000..0966a18 --- /dev/null +++ b/scripts/devnet/reserve.ts @@ -0,0 +1,23 @@ +import { buildMetadataUri, getConnection, loadWallet, reserveTokenId, writeJson } from "./common"; + +async function main(): Promise { + const connection = getConnection(); + const payer = loadWallet(); + const { signature, tokenId, reservation, globalConfig } = await reserveTokenId(connection, payer); + + const output = { + signature, + user: payer.publicKey.toBase58(), + tokenId: tokenId.toString(), + reservation: reservation.toBase58(), + metadataUri: buildMetadataUri(globalConfig.baseMetadataUrl, tokenId), + }; + + writeJson("target/devnet/latest-reservation.json", output); + console.log(JSON.stringify(output, null, 2)); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/test-contract-v1.sh b/scripts/test-contract-v1.sh new file mode 100755 index 0000000..ba9e342 --- /dev/null +++ b/scripts/test-contract-v1.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +"$ROOT_DIR/scripts/build-test-sbf.sh" +(cd "$ROOT_DIR" && BPF_OUT_DIR="$ROOT_DIR/target/test-sbf" cargo test -p tests --lib -- --test-threads=1) diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 09f220c..bac04bf 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -5,5 +5,9 @@ description = "Created with Anchor" edition = "2021" [dependencies] -anchor-client = "0.29.0" +anchor-lang = "0.31.1" doom-nft-program = { version = "0.1.0", path = "../programs/doom-nft-program" } +mpl-core = { version = "0.11.1", features = ["anchor"] } +solana-program-test = "2.2.1" +solana-sdk = "2.2.1" +tokio = { version = "1.43.0", features = ["macros"] } diff --git a/tests/fixtures/README.md b/tests/fixtures/README.md new file mode 100644 index 0000000..07fd854 --- /dev/null +++ b/tests/fixtures/README.md @@ -0,0 +1,8 @@ +# Test Fixtures + +`mpl_core_program.so` is the pinned Metaplex Core fixture used by the contract tests. + +- Source release: `release/core@0.9.10` +- Source asset: `https://github.com/metaplex-foundation/mpl-core/releases/download/release/core%400.9.10/mpl_core_program.so` +- Expected checksum: see [`mpl_core_program.so.sha256`](./mpl_core_program.so.sha256) +- Purpose: keep `ProgramTest` deterministic without dumping the live upgradeable Core program from the network diff --git a/tests/fixtures/mpl_core_program.so b/tests/fixtures/mpl_core_program.so new file mode 100755 index 0000000..2bcf263 Binary files /dev/null and b/tests/fixtures/mpl_core_program.so differ diff --git a/tests/fixtures/mpl_core_program.so.sha256 b/tests/fixtures/mpl_core_program.so.sha256 new file mode 100644 index 0000000..64be447 --- /dev/null +++ b/tests/fixtures/mpl_core_program.so.sha256 @@ -0,0 +1 @@ +604d401ea0c6c7b530c42274deeb903c953c1ef930bc5468497f60f3128493cc mpl_core_program.so diff --git a/tests/src/instructions/initialize_collection.rs b/tests/src/instructions/initialize_collection.rs new file mode 100644 index 0000000..7305548 --- /dev/null +++ b/tests/src/instructions/initialize_collection.rs @@ -0,0 +1,42 @@ +use solana_sdk::{signature::Keypair, signer::Signer}; + +use crate::test_context::{ + collection_authority_pda, fetch_collection, fetch_global_config, global_config_pda, + initialize_collection_ix, initialize_global_config_ix, process_instruction, start_context, +}; + +#[tokio::test] +async fn initialize_collection_persists_collection_and_authority() { + let mut context = start_context().await; + let payer = context.payer.pubkey(); + let upgrade_authority = Keypair::new(); + process_instruction( + &mut context, + initialize_global_config_ix( + payer, + upgrade_authority.pubkey(), + "https://example.com/base", + ), + &[], + ) + .await + .expect("initialize global config"); + + let collection = Keypair::new(); + process_instruction( + &mut context, + initialize_collection_ix(payer, collection.pubkey()), + &[&collection], + ) + .await + .expect("initialize collection"); + + let config = fetch_global_config(&mut context).await; + let (collection_authority, _) = collection_authority_pda(global_config_pda().0); + assert_eq!(config.collection, collection.pubkey()); + assert_eq!(config.collection_update_authority, collection_authority); + + let collection = fetch_collection(&mut context, collection.pubkey()).await; + assert_eq!(collection.base.name, "DOOM INDEX"); + assert_eq!(collection.base.update_authority, collection_authority); +} diff --git a/tests/src/instructions/initialize_global_config.rs b/tests/src/instructions/initialize_global_config.rs new file mode 100644 index 0000000..fbaa5e8 --- /dev/null +++ b/tests/src/instructions/initialize_global_config.rs @@ -0,0 +1,30 @@ +use solana_sdk::{signature::Keypair, signature::Signature, signer::Signer}; + +use crate::test_context::{ + fetch_global_config, initialize_global_config_ix, process_instruction, start_context, +}; + +#[tokio::test] +async fn initialize_global_config_sets_defaults() { + let mut context = start_context().await; + let payer = context.payer.pubkey(); + let upgrade_authority = Keypair::new(); + let base_metadata_url = "https://example.com/doom-index"; + + let signature = process_instruction( + &mut context, + initialize_global_config_ix(payer, upgrade_authority.pubkey(), base_metadata_url), + &[], + ) + .await + .expect("initialize global config"); + + assert_ne!(signature, Signature::default()); + + let config = fetch_global_config(&mut context).await; + assert_eq!(config.admin, context.payer.pubkey()); + assert_eq!(config.upgrade_authority, upgrade_authority.pubkey()); + assert_eq!(config.next_token_id, 1); + assert!(!config.mint_paused); + assert_eq!(config.base_metadata_url, base_metadata_url); +} diff --git a/tests/src/instructions/mint_doom_index_nft.rs b/tests/src/instructions/mint_doom_index_nft.rs new file mode 100644 index 0000000..fcee00b --- /dev/null +++ b/tests/src/instructions/mint_doom_index_nft.rs @@ -0,0 +1,195 @@ +use solana_program_test::BanksClientError; +use solana_sdk::{signature::Keypair, signer::Signer}; + +use crate::test_context::{ + fetch_asset, fetch_reservation, initialize_collection_ix, initialize_global_config_ix, + mint_doom_index_nft_ix, process_instruction, reserve_token_id_ix, start_context, +}; + +#[tokio::test] +async fn mint_with_valid_reservation_creates_core_asset() { + let mut context = start_context().await; + let payer = context.payer.pubkey(); + let upgrade_authority = Keypair::new(); + process_instruction( + &mut context, + initialize_global_config_ix( + payer, + upgrade_authority.pubkey(), + "https://example.com/base", + ), + &[], + ) + .await + .expect("initialize global config"); + + let collection = Keypair::new(); + process_instruction( + &mut context, + initialize_collection_ix(payer, collection.pubkey()), + &[&collection], + ) + .await + .expect("initialize collection"); + + process_instruction(&mut context, reserve_token_id_ix(payer, 1), &[]) + .await + .expect("reserve token id"); + + let asset = Keypair::new(); + process_instruction( + &mut context, + mint_doom_index_nft_ix(payer, 1, asset.pubkey(), collection.pubkey()), + &[&asset], + ) + .await + .expect("mint doom index nft"); + + let reservation = fetch_reservation(&mut context, 1).await; + assert!(reservation.minted); + + let asset = fetch_asset(&mut context, asset.pubkey()).await; + assert_eq!(asset.base.name, "DOOM INDEX #1"); + assert_eq!(asset.base.uri, "https://example.com/base/1.json"); + assert_eq!(asset.base.owner, context.payer.pubkey()); +} + +#[tokio::test] +async fn mint_without_reservation_fails() { + let mut context = start_context().await; + let payer = context.payer.pubkey(); + let upgrade_authority = Keypair::new(); + process_instruction( + &mut context, + initialize_global_config_ix( + payer, + upgrade_authority.pubkey(), + "https://example.com/base", + ), + &[], + ) + .await + .expect("initialize global config"); + + let collection = Keypair::new(); + process_instruction( + &mut context, + initialize_collection_ix(payer, collection.pubkey()), + &[&collection], + ) + .await + .expect("initialize collection"); + + let asset = Keypair::new(); + let error = process_instruction( + &mut context, + mint_doom_index_nft_ix(payer, 1, asset.pubkey(), collection.pubkey()), + &[&asset], + ) + .await + .expect_err("mint should fail without reservation"); + + assert!(matches!(error, BanksClientError::TransactionError(_))); +} + +#[tokio::test] +async fn mint_with_other_users_reservation_fails() { + let mut context = start_context().await; + let payer = context.payer.pubkey(); + let other_user = Keypair::new(); + let upgrade_authority = Keypair::new(); + process_instruction( + &mut context, + initialize_global_config_ix( + payer, + upgrade_authority.pubkey(), + "https://example.com/base", + ), + &[], + ) + .await + .expect("initialize global config"); + + let collection = Keypair::new(); + process_instruction( + &mut context, + initialize_collection_ix(payer, collection.pubkey()), + &[&collection], + ) + .await + .expect("initialize collection"); + + process_instruction(&mut context, reserve_token_id_ix(payer, 1), &[]) + .await + .expect("reserve token id"); + + process_instruction( + &mut context, + solana_sdk::system_instruction::transfer(&payer, &other_user.pubkey(), 1_000_000_000), + &[], + ) + .await + .expect("fund other user"); + + let asset = Keypair::new(); + let error = process_instruction( + &mut context, + mint_doom_index_nft_ix(other_user.pubkey(), 1, asset.pubkey(), collection.pubkey()), + &[&other_user, &asset], + ) + .await + .expect_err("mint should fail for a different reservation owner"); + + assert!(matches!(error, BanksClientError::TransactionError(_))); +} + +#[tokio::test] +async fn mint_cannot_reuse_reservation_after_success() { + let mut context = start_context().await; + let payer = context.payer.pubkey(); + let upgrade_authority = Keypair::new(); + process_instruction( + &mut context, + initialize_global_config_ix( + payer, + upgrade_authority.pubkey(), + "https://example.com/base", + ), + &[], + ) + .await + .expect("initialize global config"); + + let collection = Keypair::new(); + process_instruction( + &mut context, + initialize_collection_ix(payer, collection.pubkey()), + &[&collection], + ) + .await + .expect("initialize collection"); + + process_instruction(&mut context, reserve_token_id_ix(payer, 1), &[]) + .await + .expect("reserve token id"); + + let first_asset = Keypair::new(); + process_instruction( + &mut context, + mint_doom_index_nft_ix(payer, 1, first_asset.pubkey(), collection.pubkey()), + &[&first_asset], + ) + .await + .expect("first mint succeeds"); + + let second_asset = Keypair::new(); + let error = process_instruction( + &mut context, + mint_doom_index_nft_ix(payer, 1, second_asset.pubkey(), collection.pubkey()), + &[&second_asset], + ) + .await + .expect_err("second mint should fail"); + + assert!(matches!(error, BanksClientError::TransactionError(_))); +} diff --git a/tests/src/instructions/mod.rs b/tests/src/instructions/mod.rs new file mode 100644 index 0000000..0102f97 --- /dev/null +++ b/tests/src/instructions/mod.rs @@ -0,0 +1,8 @@ +mod initialize_collection; +mod initialize_global_config; +mod mint_doom_index_nft; +mod reserve_token_id; +mod set_mint_paused; +mod set_upgrade_authority; +mod transfer_admin; +mod update_base_metadata_url; diff --git a/tests/src/instructions/reserve_token_id.rs b/tests/src/instructions/reserve_token_id.rs new file mode 100644 index 0000000..d6acf71 --- /dev/null +++ b/tests/src/instructions/reserve_token_id.rs @@ -0,0 +1,36 @@ +use solana_sdk::{signature::Keypair, signer::Signer}; + +use crate::test_context::{ + fetch_global_config, fetch_reservation, initialize_global_config_ix, process_instruction, + reserve_token_id_ix, start_context, +}; + +#[tokio::test] +async fn reserve_token_id_creates_reservation_and_increments_counter() { + let mut context = start_context().await; + let payer = context.payer.pubkey(); + let upgrade_authority = Keypair::new(); + process_instruction( + &mut context, + initialize_global_config_ix( + payer, + upgrade_authority.pubkey(), + "https://example.com/base", + ), + &[], + ) + .await + .expect("initialize global config"); + + process_instruction(&mut context, reserve_token_id_ix(payer, 1), &[]) + .await + .expect("reserve token id"); + + let reservation = fetch_reservation(&mut context, 1).await; + assert_eq!(reservation.token_id, 1); + assert_eq!(reservation.reserver, context.payer.pubkey()); + assert!(!reservation.minted); + + let config = fetch_global_config(&mut context).await; + assert_eq!(config.next_token_id, 2); +} diff --git a/tests/src/instructions/set_mint_paused.rs b/tests/src/instructions/set_mint_paused.rs new file mode 100644 index 0000000..9bb8524 --- /dev/null +++ b/tests/src/instructions/set_mint_paused.rs @@ -0,0 +1,60 @@ +use solana_program_test::BanksClientError; +use solana_sdk::{signature::Keypair, signer::Signer}; + +use crate::test_context::{ + initialize_collection_ix, initialize_global_config_ix, mint_doom_index_nft_ix, + process_instruction, reserve_token_id_ix, set_mint_paused_ix, start_context, +}; + +#[tokio::test] +async fn pause_blocks_reserve_and_mint() { + let mut context = start_context().await; + let payer = context.payer.pubkey(); + let upgrade_authority = Keypair::new(); + process_instruction( + &mut context, + initialize_global_config_ix( + payer, + upgrade_authority.pubkey(), + "https://example.com/base", + ), + &[], + ) + .await + .expect("initialize global config"); + + let collection = Keypair::new(); + process_instruction( + &mut context, + initialize_collection_ix(payer, collection.pubkey()), + &[&collection], + ) + .await + .expect("initialize collection"); + + process_instruction(&mut context, reserve_token_id_ix(payer, 1), &[]) + .await + .expect("reserve token id"); + + process_instruction(&mut context, set_mint_paused_ix(payer, true), &[]) + .await + .expect("pause mint"); + + let reserve_error = process_instruction(&mut context, reserve_token_id_ix(payer, 2), &[]) + .await + .expect_err("reserve should fail when paused"); + assert!(matches!( + reserve_error, + BanksClientError::TransactionError(_) + )); + + let asset = Keypair::new(); + let mint_error = process_instruction( + &mut context, + mint_doom_index_nft_ix(payer, 1, asset.pubkey(), collection.pubkey()), + &[&asset], + ) + .await + .expect_err("mint should fail when paused"); + assert!(matches!(mint_error, BanksClientError::TransactionError(_))); +} diff --git a/tests/src/instructions/set_upgrade_authority.rs b/tests/src/instructions/set_upgrade_authority.rs new file mode 100644 index 0000000..7d625d6 --- /dev/null +++ b/tests/src/instructions/set_upgrade_authority.rs @@ -0,0 +1,37 @@ +use solana_sdk::{signature::Keypair, signer::Signer}; + +use crate::test_context::{ + fetch_global_config, initialize_global_config_ix, process_instruction, + set_upgrade_authority_ix, start_context, +}; + +#[tokio::test] +async fn upgrade_authority_is_independent_from_admin() { + let mut context = start_context().await; + let payer = context.payer.pubkey(); + let upgrade_authority = Keypair::new(); + process_instruction( + &mut context, + initialize_global_config_ix( + payer, + upgrade_authority.pubkey(), + "https://example.com/base", + ), + &[], + ) + .await + .expect("initialize global config"); + + let next_upgrade_authority = Keypair::new(); + process_instruction( + &mut context, + set_upgrade_authority_ix(upgrade_authority.pubkey(), next_upgrade_authority.pubkey()), + &[&upgrade_authority], + ) + .await + .expect("set upgrade authority"); + + let config = fetch_global_config(&mut context).await; + assert_eq!(config.admin, payer); + assert_eq!(config.upgrade_authority, next_upgrade_authority.pubkey()); +} diff --git a/tests/src/instructions/transfer_admin.rs b/tests/src/instructions/transfer_admin.rs new file mode 100644 index 0000000..03d5031 --- /dev/null +++ b/tests/src/instructions/transfer_admin.rs @@ -0,0 +1,38 @@ +use solana_sdk::{signature::Keypair, signer::Signer}; + +use crate::test_context::{ + fetch_global_config, initialize_global_config_ix, process_instruction, start_context, + transfer_admin_ix, +}; + +#[tokio::test] +async fn transfer_admin_updates_admin_authority() { + let mut context = start_context().await; + let payer = context.payer.pubkey(); + let upgrade_authority = Keypair::new(); + process_instruction( + &mut context, + initialize_global_config_ix( + payer, + upgrade_authority.pubkey(), + "https://example.com/base", + ), + &[], + ) + .await + .expect("initialize global config"); + + let next_admin = Keypair::new(); + process_instruction( + &mut context, + transfer_admin_ix(payer, upgrade_authority.pubkey(), next_admin.pubkey()), + &[&upgrade_authority, &next_admin], + ) + .await + .expect("transfer admin"); + + assert_eq!( + fetch_global_config(&mut context).await.admin, + next_admin.pubkey() + ); +} diff --git a/tests/src/instructions/update_base_metadata_url.rs b/tests/src/instructions/update_base_metadata_url.rs new file mode 100644 index 0000000..678de55 --- /dev/null +++ b/tests/src/instructions/update_base_metadata_url.rs @@ -0,0 +1,37 @@ +use solana_sdk::{signature::Keypair, signer::Signer}; + +use crate::test_context::{ + fetch_global_config, initialize_global_config_ix, process_instruction, start_context, + update_base_metadata_url_ix, +}; + +#[tokio::test] +async fn update_base_metadata_url_updates_config() { + let mut context = start_context().await; + let payer = context.payer.pubkey(); + let upgrade_authority = Keypair::new(); + process_instruction( + &mut context, + initialize_global_config_ix( + payer, + upgrade_authority.pubkey(), + "https://example.com/base", + ), + &[], + ) + .await + .expect("initialize global config"); + + process_instruction( + &mut context, + update_base_metadata_url_ix(payer, "https://example.com/next"), + &[], + ) + .await + .expect("update base metadata url"); + + assert_eq!( + fetch_global_config(&mut context).await.base_metadata_url, + "https://example.com/next" + ); +} diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 1bd3931..5711ec3 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -1,4 +1,4 @@ -#[cfg(test)] -mod tests { - // Add your tests here -} +#![cfg(test)] + +mod instructions; +mod test_context; diff --git a/tests/src/test_context.rs b/tests/src/test_context.rs new file mode 100644 index 0000000..26a3e70 --- /dev/null +++ b/tests/src/test_context.rs @@ -0,0 +1,291 @@ +use anchor_lang::{ + prelude::AccountDeserialize, + solana_program::{account_info::AccountInfo, entrypoint::ProgramResult}, + system_program::ID as SYSTEM_PROGRAM_ID, + InstructionData, ToAccountMetas, +}; +use doom_nft_program::{ + accounts::{ + InitializeCollection, InitializeGlobalConfig, MintDoomIndexNft, ReserveTokenId, + SetMintPaused, SetUpgradeAuthority, TransferAdmin, UpdateBaseMetadataUrl, + }, + instruction, GlobalConfig, MintReservation, +}; +use mpl_core::{Asset, Collection}; +use solana_program_test::{processor, BanksClientError, ProgramTest, ProgramTestContext}; +use solana_sdk::{ + instruction::Instruction, + pubkey::Pubkey, + signature::{Keypair, Signature}, + signer::Signer, + transaction::Transaction, +}; + +pub fn program_test() -> ProgramTest { + let manifest_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let bpf_out_dir = manifest_dir.join("..").join("target").join("test-sbf"); + std::env::set_var("BPF_OUT_DIR", &bpf_out_dir); + + let mut test = ProgramTest::default(); + test.prefer_bpf(false); + test.add_program( + "doom_nft_program", + doom_nft_program::id(), + processor!(doom_nft_program_test_processor), + ); + test.add_upgradeable_program_to_genesis("mpl_core_program", &mpl_core::ID); + test +} + +pub async fn start_context() -> ProgramTestContext { + program_test().start_with_context().await +} + +fn doom_nft_program_test_processor<'a, 'b, 'c, 'd>( + program_id: &'a Pubkey, + accounts: &'b [AccountInfo<'c>], + instruction_data: &'d [u8], +) -> ProgramResult { + // SAFETY: This only narrows the outer slice lifetime from `&'b [AccountInfo<'c>]` to + // `&'c [AccountInfo<'c>]` without changing the slice layout or the contained `AccountInfo` + // values. `accounts` already points to `AccountInfo<'c>` elements, and callers uphold that + // the slice lives for the full duration of `doom_nft_program::entry(program_id, accounts, + // instruction_data)`, so this cast does not extend any inner borrow past its original + // lifetime. + let accounts: &'c [AccountInfo<'c>] = unsafe { std::mem::transmute(accounts) }; + doom_nft_program::entry(program_id, accounts, instruction_data) +} + +pub fn global_config_pda() -> (Pubkey, u8) { + Pubkey::find_program_address(&[b"global_config"], &doom_nft_program::id()) +} + +pub fn collection_authority_pda(global_config: Pubkey) -> (Pubkey, u8) { + Pubkey::find_program_address( + &[b"collection_authority", global_config.as_ref()], + &doom_nft_program::id(), + ) +} + +pub fn reservation_pda(token_id: u64) -> (Pubkey, u8) { + Pubkey::find_program_address( + &[b"reservation", &token_id.to_le_bytes()], + &doom_nft_program::id(), + ) +} + +pub async fn process_instruction( + context: &mut ProgramTestContext, + instruction: Instruction, + extra_signers: &[&Keypair], +) -> Result { + let mut signers = vec![&context.payer]; + signers.extend_from_slice(extra_signers); + + let tx = Transaction::new_signed_with_payer( + &[instruction], + Some(&context.payer.pubkey()), + &signers, + context.last_blockhash, + ); + let signature = tx.signatures[0]; + context.banks_client.process_transaction(tx).await?; + Ok(signature) +} + +pub async fn fetch_global_config(context: &mut ProgramTestContext) -> GlobalConfig { + let (config, _) = global_config_pda(); + let account = context + .banks_client + .get_account(config) + .await + .expect("get config account") + .expect("config account exists"); + + let mut bytes = account.data.as_slice(); + GlobalConfig::try_deserialize(&mut bytes).expect("deserialize global config") +} + +pub async fn fetch_reservation(context: &mut ProgramTestContext, token_id: u64) -> MintReservation { + let (reservation, _) = reservation_pda(token_id); + let account = context + .banks_client + .get_account(reservation) + .await + .expect("get reservation account") + .expect("reservation account exists"); + + let mut bytes = account.data.as_slice(); + MintReservation::try_deserialize(&mut bytes).expect("deserialize reservation") +} + +pub async fn fetch_collection(context: &mut ProgramTestContext, collection: Pubkey) -> Collection { + let account = context + .banks_client + .get_account(collection) + .await + .expect("get collection account") + .expect("collection account exists"); + + *Collection::from_bytes(&account.data).expect("decode collection") +} + +pub async fn fetch_asset(context: &mut ProgramTestContext, asset: Pubkey) -> Asset { + let account = context + .banks_client + .get_account(asset) + .await + .expect("get asset account") + .expect("asset account exists"); + + *Asset::from_bytes(&account.data).expect("decode asset") +} + +pub fn initialize_global_config_ix( + admin: Pubkey, + upgrade_authority: Pubkey, + base_metadata_url: &str, +) -> Instruction { + let (global_config, _) = global_config_pda(); + + Instruction { + program_id: doom_nft_program::id(), + accounts: InitializeGlobalConfig { + global_config, + admin, + system_program: SYSTEM_PROGRAM_ID, + } + .to_account_metas(None), + data: instruction::InitializeGlobalConfig { + base_metadata_url: base_metadata_url.to_owned(), + upgrade_authority, + } + .data(), + } +} + +pub fn initialize_collection_ix(admin: Pubkey, collection: Pubkey) -> Instruction { + let (global_config, _) = global_config_pda(); + let (collection_update_authority, _) = collection_authority_pda(global_config); + + Instruction { + program_id: doom_nft_program::id(), + accounts: InitializeCollection { + global_config, + admin, + collection, + collection_update_authority, + mpl_core_program: mpl_core::ID, + system_program: SYSTEM_PROGRAM_ID, + } + .to_account_metas(None), + data: instruction::InitializeCollection {}.data(), + } +} + +pub fn reserve_token_id_ix(user: Pubkey, token_id: u64) -> Instruction { + let (global_config, _) = global_config_pda(); + let (reservation, _) = reservation_pda(token_id); + + Instruction { + program_id: doom_nft_program::id(), + accounts: ReserveTokenId { + global_config, + reservation, + user, + system_program: SYSTEM_PROGRAM_ID, + } + .to_account_metas(None), + data: instruction::ReserveTokenId {}.data(), + } +} + +pub fn mint_doom_index_nft_ix( + user: Pubkey, + token_id: u64, + asset: Pubkey, + collection: Pubkey, +) -> Instruction { + let (global_config, _) = global_config_pda(); + let (reservation, _) = reservation_pda(token_id); + let (collection_update_authority, _) = collection_authority_pda(global_config); + + Instruction { + program_id: doom_nft_program::id(), + accounts: MintDoomIndexNft { + global_config, + reservation, + user, + asset, + collection_update_authority, + collection, + mpl_core_program: mpl_core::ID, + system_program: SYSTEM_PROGRAM_ID, + } + .to_account_metas(None), + data: instruction::MintDoomIndexNft { token_id }.data(), + } +} + +pub fn set_mint_paused_ix(admin: Pubkey, paused: bool) -> Instruction { + Instruction { + program_id: doom_nft_program::id(), + accounts: SetMintPaused { + global_config: global_config_pda().0, + admin, + } + .to_account_metas(None), + data: instruction::SetMintPaused { paused }.data(), + } +} + +pub fn update_base_metadata_url_ix(admin: Pubkey, base_metadata_url: &str) -> Instruction { + Instruction { + program_id: doom_nft_program::id(), + accounts: UpdateBaseMetadataUrl { + global_config: global_config_pda().0, + admin, + } + .to_account_metas(None), + data: instruction::UpdateBaseMetadataUrl { + base_metadata_url: base_metadata_url.to_owned(), + } + .data(), + } +} + +pub fn transfer_admin_ix( + admin: Pubkey, + upgrade_authority: Pubkey, + new_admin: Pubkey, +) -> Instruction { + Instruction { + program_id: doom_nft_program::id(), + accounts: TransferAdmin { + global_config: global_config_pda().0, + admin, + upgrade_authority, + new_admin, + } + .to_account_metas(None), + data: instruction::TransferAdmin {}.data(), + } +} + +pub fn set_upgrade_authority_ix( + upgrade_authority: Pubkey, + new_upgrade_authority: Pubkey, +) -> Instruction { + Instruction { + program_id: doom_nft_program::id(), + accounts: SetUpgradeAuthority { + global_config: global_config_pda().0, + upgrade_authority, + } + .to_account_metas(None), + data: instruction::SetUpgradeAuthority { + new_upgrade_authority, + } + .data(), + } +} diff --git a/tsconfig.json b/tsconfig.json index cd5d2e3..f740e10 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,5 +6,7 @@ "module": "commonjs", "target": "es6", "esModuleInterop": true - } + }, + "include": ["scripts/**/*.ts"], + "exclude": ["node_modules", "target"] }