From 742e54504dfad075caf91f9535e77b75be56ba22 Mon Sep 17 00:00:00 2001 From: grysz <117801274+grysz@users.noreply.github.com> Date: Mon, 19 Oct 2026 19:37:03 -0400 Subject: [PATCH 1/3] Validate native Toccata v2.1 transactions and close executable spend scripts --- .github/workflows/toccata-compatibility.yml | 24 + .gitignore | 1 + README.md | 6 + cli/src/main.rs | 72 +- compatibility/toccata-v2/Cargo.lock | 5001 +++++++++++++++++++ compatibility/toccata-v2/Cargo.toml | 26 + compatibility/toccata-v2/README.md | 41 + compatibility/toccata-v2/src/lib.rs | 175 + compatibility/toccata-v2/tests/native.rs | 389 ++ compiler/codegen/src/backends/toccata.rs | 29 + docs/TOCCATA_CRATE_COMPATIBILITY.md | 17 + docs/TRANSACTION_BUILDER.md | 11 + sdk/src/testnet.rs | 4 +- tests/golden/cli/toccata.status.json | 62 +- 14 files changed, 5805 insertions(+), 53 deletions(-) create mode 100644 .github/workflows/toccata-compatibility.yml create mode 100644 compatibility/toccata-v2/Cargo.lock create mode 100644 compatibility/toccata-v2/Cargo.toml create mode 100644 compatibility/toccata-v2/README.md create mode 100644 compatibility/toccata-v2/src/lib.rs create mode 100644 compatibility/toccata-v2/tests/native.rs diff --git a/.github/workflows/toccata-compatibility.yml b/.github/workflows/toccata-compatibility.yml new file mode 100644 index 0000000..1e0bd23 --- /dev/null +++ b/.github/workflows/toccata-compatibility.yml @@ -0,0 +1,24 @@ +name: Native Toccata compatibility + +on: + pull_request: + paths: ["compatibility/toccata-v2/**", "compiler/**", "sdk/**", ".github/workflows/toccata-compatibility.yml"] + push: + branches: [main] + paths: ["compatibility/toccata-v2/**", "compiler/**", "sdk/**", ".github/workflows/toccata-compatibility.yml"] + workflow_dispatch: + +permissions: + contents: read + +jobs: + native: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: dtolnay/rust-toolchain@1.95.0 + with: + components: rustfmt, clippy + - run: cargo fmt --manifest-path compatibility/toccata-v2/Cargo.toml -- --check + - run: cargo test --manifest-path compatibility/toccata-v2/Cargo.toml --locked --features silverscript + - run: cargo clippy --manifest-path compatibility/toccata-v2/Cargo.toml --locked --all-targets --features silverscript -- -D warnings diff --git a/.gitignore b/.gitignore index 9227398..5ca9cdc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target/ +/compatibility/toccata-v2/target/ **/*.rs.bk .DS_Store diff --git a/README.md b/README.md index 4a5f8ee..81bf19e 100644 --- a/README.md +++ b/README.md @@ -284,6 +284,12 @@ Read the deeper design: ## Current Status +October 2026 compatibility lane: an isolated native SDK companion in +[`compatibility/toccata-v2`](compatibility/toccata-v2) targets Rusty Kaspa +v2.1.0 with real v1 transaction/RPC types and offline script validation. Its +optional interoperability checks use released Silverscript v1.0.0. This does +not promote the legacy SDK, preview compiler, or mainnet readiness gates. + KaspaScript is an active developer-preview project with a verified compiler subset and deterministic tooling. diff --git a/cli/src/main.rs b/cli/src/main.rs index c764260..7012c49 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -627,13 +627,21 @@ fn toccata_status_report() -> Value { fn toccata_upgrade_profile() -> Value { json!({ "name": "Toccata", + "checked_at": "2026-10-19T23:21:28Z", + "evidence_scope": "dated public-source snapshot; recheck before deployment", "rusty_kaspa_release": { "repo": "https://github.com/kaspanet/rusty-kaspa", - "tag": "v2.0.1", - "name": "Mainnet Toccata Release - v2.0.1", - "published_at": "2026-06-15T19:14:22Z", - "commit": "cfafeb4c093fa37a303f1b9f19c58f986b870ce3", - "upgrade_note": "drop-in update for v2.0.0 nodes and Toccata upgrade version for pre-Toccata 1.x nodes", + "tag": "v2.1.0", + "name": "Rusty Kaspa v2.1.0", + "published_at": "2026-09-22T13:55:36Z", + "commit": "01b532e8b553523216471682649693af92f0fd16", + "upgrade_note": "post-Toccata security, protocol 11, and standalone ZK SDK release; SDK/application compatibility remains separately tested", + }, + "silverscript_release": { + "tag": "v1.0.0", + "commit": "3ed973335b59269293564805cc2c58a14595ec03", + "url": "https://github.com/kaspanet/silverscript/releases/tag/v1.0.0", + "kaspa_script_interoperability": "isolated native engine tests; not shared language or artifact compatibility", }, "baseline_toccata_release": { "tag": "v2.0.0", @@ -642,45 +650,49 @@ fn toccata_upgrade_profile() -> Value { "role": "baseline release that announced the mainnet activation DAA score", }, "node_upgrade_guide": { - "url": "https://github.com/kaspanet/rusty-kaspa/blob/v2.0.1/docs/toccata-guide.md", + "url": "https://github.com/kaspanet/rusty-kaspa/blob/v2.1.0/docs/toccata-guide.md", "database_upgrade": "one-way; downgrade requires resync", "recommended_rehearsal_network": "testnet-10", }, "release_assets": [ { - "name": "kaspa-wasm32-sdk-v2.0.1.zip", - "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.0.1/kaspa-wasm32-sdk-v2.0.1.zip", + "name": "kaspa-wasm32-sdk-v2.1.0.zip", + "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.1.0/kaspa-wasm32-sdk-v2.1.0.zip", }, { - "name": "rusty-kaspa-v2.0.1-linux-amd64.zip", - "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.0.1/rusty-kaspa-v2.0.1-linux-amd64.zip", + "name": "rusty-kaspa-v2.1.0-linux-amd64.zip", + "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.1.0/rusty-kaspa-v2.1.0-linux-amd64.zip", }, { - "name": "rusty-kaspa-v2.0.1-osx.zip", - "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.0.1/rusty-kaspa-v2.0.1-osx.zip", + "name": "rusty-kaspa-v2.1.0-osx.zip", + "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.1.0/rusty-kaspa-v2.1.0-osx.zip", }, { - "name": "rusty-kaspa-v2.0.1-win64.zip", - "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.0.1/rusty-kaspa-v2.0.1-win64.zip", + "name": "rusty-kaspa-v2.1.0-win64.zip", + "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.1.0/rusty-kaspa-v2.1.0-win64.zip", }, ], "maintenance_changes": [ - "seq-commit state and lane-proof RPC support", - "wallet/core and Wasm SMT sync progress notifications", - "SMT database inspection tooling", - "transaction-generation tooling for user-lane workflows", - "covenant binding handling refinements across client and wallet components", - "Wasm client transaction v0 deserialization fix", + "P2P protocol 11 and chunked IBD with protocol 10 compatibility", + "P2P wire limits and Stratum bridge security hardening", + "standalone kaspa-txscript-zk-sdk crate", + "arithmetic safety audit and post-Toccata consensus cleanup", + "RPC covenant preservation and checked integer conversions", + "Wasm sighash mapping and BIP-32 key equality fixes", ], "mainnet_activation": { "daa_score": 474_165_565u64, "estimated_utc": "2026-06-30T16:15:00Z", - "status": "scheduled-not-independently-verified", + "status": "protocol-active-in-dated-snapshot", + "observed_network": "kaspa-mainnet", + "observed_daa_score": 570_318_708u64, + "source": "https://api.kaspa.org/info/blockdag", "kaspa_script_readiness": "blocked-for-production-mainnet", }, "p2p_protocol": { "required_version": 10, - "restriction_window": "24h-before-activation", + "current_version": 11, + "compatibility": "protocol 11 negotiates protocol 10 with older peers", }, "node_requirements": { "minimum": { @@ -753,13 +765,13 @@ fn toccata_upgrade_profile() -> Value { }, ], "integrator_actions": [ - "Upgrade nodes to rusty-kaspa v2.0.1 before the scheduled activation window.", + "Review rusty-kaspa v2.1.0 security and compatibility changes before upgrading.", "Run full wallet, explorer, miner, pool, and indexer rehearsal on Testnet-10.", "Add compatibility coverage for seq-commit lane-proof RPCs and covenant binding refinements.", "Update gRPC/protobuf integrations for transaction version 1 covenant and compute_commit fields.", "Use node fee estimation when available; otherwise apply the Toccata minimum standard fee formula.", "Prefer storage_mass/storageMass in new JSON and protobuf integrations; treat mass as deprecated compatibility only.", - "Keep KaspaScript future-mainnet packages blocked until activation evidence is independently verified.", + "Keep KaspaScript future-mainnet packages blocked until contract lowering, wallet/indexer support, and fee behavior are independently verified.", ], }) } @@ -1575,7 +1587,15 @@ mod tests { ); assert_eq!( report["upgrade"]["rusty_kaspa_release"]["tag"], - Value::String("v2.0.1".to_owned()) + Value::String("v2.1.0".to_owned()) + ); + assert_eq!( + report["upgrade"]["mainnet_activation"]["status"], + Value::String("protocol-active-in-dated-snapshot".to_owned()) + ); + assert_eq!( + report["upgrade"]["mainnet_activation"]["observed_network"], + Value::String("kaspa-mainnet".to_owned()) ); assert_eq!( report["upgrade"]["baseline_toccata_release"]["tag"], @@ -1584,7 +1604,7 @@ mod tests { assert_eq!( report["upgrade"]["node_upgrade_guide"]["url"], Value::String( - "https://github.com/kaspanet/rusty-kaspa/blob/v2.0.1/docs/toccata-guide.md" + "https://github.com/kaspanet/rusty-kaspa/blob/v2.1.0/docs/toccata-guide.md" .to_owned() ) ); diff --git a/compatibility/toccata-v2/Cargo.lock b/compatibility/toccata-v2/Cargo.lock new file mode 100644 index 0000000..7faefc5 --- /dev/null +++ b/compatibility/toccata-v2/Cargo.lock @@ -0,0 +1,5001 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "arc-swap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380962b3d93b99642e50b9febf72c071e97e8b32d86eae9cf4ef582bb960ae6e" +dependencies = [ + "rustversion", +] + +[[package]] +name = "ark-bn254" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" +dependencies = [ + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-r1cs-std 0.5.0", + "ark-std 0.5.0", +] + +[[package]] +name = "ark-bn254" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bc66f96ebe2a17a499475b4f94791d379817592ef494171586967ffdc6f95db" +dependencies = [ + "ark-ec 0.6.0", + "ark-ff 0.6.0", + "ark-std 0.6.0", +] + +[[package]] +name = "ark-crypto-primitives" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0c292754729c8a190e50414fd1a37093c786c709899f29c9f7daccecfa855e" +dependencies = [ + "ahash", + "ark-crypto-primitives-macros", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-relations 0.5.1", + "ark-serialize 0.5.0", + "ark-snark 0.5.1", + "ark-std 0.5.0", + "blake2", + "derivative", + "digest", + "fnv", + "merlin", + "sha2", +] + +[[package]] +name = "ark-crypto-primitives" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b3409b1846fe459d19c95df039481575ac6d5842ae63858ad75cc31219bfc1" +dependencies = [ + "ahash", + "ark-crypto-primitives-macros", + "ark-ec 0.6.0", + "ark-ff 0.6.0", + "ark-r1cs-std 0.6.0", + "ark-relations 0.6.0", + "ark-serialize 0.6.0", + "ark-snark 0.6.0", + "ark-std 0.6.0", + "blake2", + "blake3", + "derivative", + "digest", + "fnv", + "merlin", + "num-bigint", + "rayon", + "sha2", +] + +[[package]] +name = "ark-crypto-primitives-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e89fe77d1f0f4fe5b96dfc940923d88d17b6a773808124f21e764dfb063c6a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-ec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" +dependencies = [ + "ahash", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.5", + "itertools 0.13.0", + "num-bigint", + "num-integer", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8352a2b2aedf6ba2cc38f7520fc51191d518dde96175c729af19f2d059f191c4" +dependencies = [ + "ahash", + "ark-ff 0.6.0", + "ark-poly 0.6.0", + "ark-serialize 0.6.0", + "ark-std 0.6.0", + "educe", + "fnv", + "hashbrown 0.17.1", + "itertools 0.14.0", + "num-bigint", + "num-integer", + "num-traits", + "rayon", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest", + "educe", + "itertools 0.13.0", + "num-bigint", + "num-traits", + "paste", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7a806ac6c8307b929df4645776290a50ee2aac754ad09d8bdf73391309e43af" +dependencies = [ + "ark-ff-asm 0.6.0", + "ark-ff-macros 0.6.0", + "ark-serialize 0.6.0", + "ark-std 0.6.0", + "digest", + "educe", + "num-bigint", + "num-traits", + "rayon", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-ff-asm" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1479009684adc073dff49a1025d3a7065b317a9ead25aaaca38cdc70058ba8a2" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-ff-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0691ed21ef00ef89c1e9bda832eba493dda3ec2f8d892fb25b705f73f06bb8" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-groth16" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88f1d0f3a534bb54188b8dcc104307db6c56cdae574ddc3212aec0625740fc7e" +dependencies = [ + "ark-crypto-primitives 0.5.0", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-relations 0.5.1", + "ark-serialize 0.5.0", + "ark-std 0.5.0", +] + +[[package]] +name = "ark-groth16" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a293328aa422e65527e285614ce5d1dceb0bd7b8b18d18b1b63191ee1f74cb41" +dependencies = [ + "ark-crypto-primitives 0.6.0", + "ark-ec 0.6.0", + "ark-ff 0.6.0", + "ark-poly 0.6.0", + "ark-relations 0.6.0", + "ark-serialize 0.6.0", + "ark-snark 0.6.0", + "ark-std 0.6.0", + "rayon", +] + +[[package]] +name = "ark-poly" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" +dependencies = [ + "ahash", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.5", +] + +[[package]] +name = "ark-poly" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f55af10b672002b8d953e230282c51206842e20e5791a94432219b4201de5c" +dependencies = [ + "ahash", + "ark-ff 0.6.0", + "ark-serialize 0.6.0", + "ark-std 0.6.0", + "educe", + "fnv", + "hashbrown 0.17.1", + "rayon", +] + +[[package]] +name = "ark-r1cs-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941551ef1df4c7a401de7068758db6503598e6f01850bdb2cfdb614a1f9dbea1" +dependencies = [ + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-relations 0.5.1", + "ark-std 0.5.0", + "educe", + "num-bigint", + "num-integer", + "num-traits", + "tracing", +] + +[[package]] +name = "ark-r1cs-std" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291f1c6628bfcac79b0dc2adbe401aa9100e2e96daa971645e0b18fc94de9a98" +dependencies = [ + "ark-ec 0.6.0", + "ark-ff 0.6.0", + "ark-relations 0.6.0", + "ark-std 0.6.0", + "educe", + "itertools 0.14.0", + "num-bigint", + "num-integer", + "num-traits", + "tracing", +] + +[[package]] +name = "ark-relations" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec46ddc93e7af44bcab5230937635b06fb5744464dd6a7e7b083e80ebd274384" +dependencies = [ + "ark-ff 0.5.0", + "ark-std 0.5.0", + "tracing", + "tracing-subscriber 0.2.25", +] + +[[package]] +name = "ark-relations" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4c11c797a64b8a23e22bf4e77bf582ac27bb21395e3183a9a506ba2561e9f9" +dependencies = [ + "ark-ff 0.6.0", + "ark-poly 0.6.0", + "ark-serialize 0.6.0", + "ark-std 0.6.0", + "foldhash 0.1.5", + "indexmap 2.14.2", + "rayon", + "tracing", + "tracing-subscriber 0.3.23", +] + +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-serialize-derive 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a74dd304fd536fb95d0a328e72be759209cc496a9da094c5bc56e5fea4f9e86b" +dependencies = [ + "ark-serialize-derive 0.6.0", + "ark-std 0.6.0", + "digest", + "num-bigint", + "rayon", + "serde_with", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f153690697a2b91e5e1251ff98411ee5371500a111a0fd317a70e588eb300f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-snark" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d368e2848c2d4c129ce7679a7d0d2d612b6a274d3ea6a13bad4445d61b381b88" +dependencies = [ + "ark-ff 0.5.0", + "ark-relations 0.5.1", + "ark-serialize 0.5.0", + "ark-std 0.5.0", +] + +[[package]] +name = "ark-snark" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bdb461d2be9b2bd6f303c79fffc89f5858790a7b4d33257bca3178e2c071fb9" +dependencies = [ + "ark-ff 0.6.0", + "ark-relations 0.6.0", + "ark-serialize 0.6.0", + "ark-std 0.6.0", +] + +[[package]] +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +dependencies = [ + "num-traits", + "rand 0.8.8", +] + +[[package]] +name = "ark-std" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "367c9c827ed431bff6868b7aa926e05b16eb46603cc8b6e768e4a5553fa1d155" +dependencies = [ + "num-traits", + "rand 0.8.8", + "rayon", +] + +[[package]] +name = "arrayvec" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" + +[[package]] +name = "async-attributes" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.5.0", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener 5.4.2", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-std" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" +dependencies = [ + "async-attributes", + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3560a7b1951efe814fcd721938313adc56753ca39f4b23847d7e9a2402f5dbff" +dependencies = [ + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "blake3" +version = "1.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae" +dependencies = [ + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "cpufeatures 0.3.1", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + +[[package]] +name = "blocking" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa" +dependencies = [ + "async-channel 2.5.0", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "borsh" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "553c5d846a6ba5150c65e3b1b8ec073bcf1abc20f9b7220de384a4443ea4e20a" +dependencies = [ + "borsh-derive", + "bytes", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cdfe656708a01f89b451a7d36466e6fe6c414de0aa18fc54f864f6f9ca9f56" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a1f896587b6f2c069c73d2f0913e2d590c3990285cd2f0b6aa02b786b4c679c" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "camino" +version = "1.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbad30e4b4c14a39e3cc8aed085a12a327257c316619c93581e017bc52be591" +dependencies = [ + "serde_core", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "cc" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877bf67ac8e52449eb2f9e98a344ea163beb70dd1f9eebe3cc5357dcfeaee4df" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + +[[package]] +name = "chacha20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.1", + "rand_core 0.10.1", +] + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "clap" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "clap_lex" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.21", +] + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width", + "windows-sys 0.59.0", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "core_detect" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctrlc" +version = "3.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162" +dependencies = [ + "dispatch2", + "nix", + "windows-sys 0.61.2", +] + +[[package]] +name = "defmt" +version = "0.3.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4deef977660e373c458df605a913d4ab121db0ccd18d1ad6976dff7d37cddb53" +dependencies = [ + "defmt 1.2.0", +] + +[[package]] +name = "defmt" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a0795ac740cb54d7b3775c9c17345f6aaecf884c01733b39d6017738e0e3e1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "840bb056bd99c495c9188198a258ab787c79f306d864db3e6e8451442d6d8366" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "defmt-parser" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71958f69fb2de856c5dd51ac9377e986ca1aa5919f931bf5395a807277f889a0" +dependencies = [ + "thiserror 2.0.21", +] + +[[package]] +name = "deranged" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9de72ce2ad1f90dc62fa25f0f430ef85eb4b0d8fa0be4f30373bc40a21d28e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.119", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.119", + "unicode-xid", +] + +[[package]] +name = "destructure_traitobject" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.13.2", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "either" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be" + +[[package]] +name = "elf" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "enum-ordinalize" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89dd01549b09589510cf0647475075d12071456586d70f5c75c98ae2a5537677" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65863d15a4ce2888bd2f0f543cc963d3879c3a022c8ee43f6141d479a3ac815" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" +dependencies = [ + "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.2", + "pin-project-lite", +] + +[[package]] +name = "faster-hex" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" +dependencies = [ + "serde", +] + +[[package]] +name = "faster-hex" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04839bdf9d8c10f66806fad16b852fc72aab80873aebc3cb69d85b4fa41543ed" +dependencies = [ + "autocfg", + "defmt 0.3.101", + "heapless", + "serde", +] + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + +[[package]] +name = "find-msvc-tools" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "flate2" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +dependencies = [ + "crc32fast", + "miniz_oxide", + "zlib-rs", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "futures" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "futures-sink" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", +] + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash 0.2.0", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "allocator-api2", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hexplay" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da1f4f846e8dcc1b5225caf702924816cabd855e4b46115c334ba09d5254a21" +dependencies = [ + "atty", + "termcolor", +] + +[[package]] +name = "humantime" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15" + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "include_bytes_aligned" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee796ad498c8d9a1d68e477df8f754ed784ef875de1414ebdaf169f70a6a784" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "ipnet" +version = "2.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jiff" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b005715dcbeb0089a3c0dab99f2ff1cc3b2525323552703d648585d342a383" +dependencies = [ + "defmt 1.2.0", + "jiff-core", + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" +dependencies = [ + "defmt 1.2.0", + "log", +] + +[[package]] +name = "jiff-static" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc9817253cf7c7ee4684451bd327e88d6f3658014e54a29198625590650695c" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8377070c6bae868759445e5a77f66d84f0b72f3a054bfb00e6d038b8282da7" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "kaspa-addresses" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "borsh", + "js-sys", + "serde", + "smallvec", + "thiserror 2.0.21", + "wasm-bindgen", + "workflow-log", + "workflow-wasm", +] + +[[package]] +name = "kaspa-addresses" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "borsh", + "js-sys", + "serde", + "smallvec", + "thiserror 2.0.21", + "wasm-bindgen", + "workflow-log", + "workflow-wasm", +] + +[[package]] +name = "kaspa-consensus-client" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "ahash", + "borsh", + "cfg-if", + "faster-hex 0.9.0", + "hex", + "itertools 0.13.0", + "js-sys", + "kaspa-addresses 2.1.0", + "kaspa-consensus-core 2.1.0", + "kaspa-hashes 2.1.0", + "kaspa-math 2.1.0", + "kaspa-txscript 2.1.0", + "kaspa-utils 2.1.0", + "kaspa-wasm-core", + "rand 0.8.8", + "secp256k1", + "serde", + "serde-wasm-bindgen", + "serde_json", + "thiserror 2.0.21", + "wasm-bindgen", + "workflow-log", + "workflow-wasm", +] + +[[package]] +name = "kaspa-consensus-core" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "arc-swap", + "async-trait", + "bitflags 2.13.2", + "borsh", + "cfg-if", + "faster-hex 0.9.0", + "futures-util", + "getrandom 0.2.17", + "itertools 0.13.0", + "js-sys", + "kaspa-addresses 2.0.1", + "kaspa-core 2.0.1", + "kaspa-hashes 2.0.1", + "kaspa-math 2.0.1", + "kaspa-merkle 2.0.1", + "kaspa-muhash 2.0.1", + "kaspa-smt 2.0.1", + "kaspa-txscript-errors 2.0.1", + "kaspa-utils 2.0.1", + "rand 0.8.8", + "secp256k1", + "serde", + "serde-value", + "serde-wasm-bindgen", + "serde_json", + "smallvec", + "thiserror 2.0.21", + "wasm-bindgen", + "workflow-core", + "workflow-log", + "workflow-serializer", + "workflow-wasm", +] + +[[package]] +name = "kaspa-consensus-core" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "arc-swap", + "async-trait", + "bitflags 2.13.2", + "borsh", + "cfg-if", + "faster-hex 0.9.0", + "futures-util", + "getrandom 0.2.17", + "itertools 0.13.0", + "js-sys", + "kaspa-addresses 2.1.0", + "kaspa-core 2.1.0", + "kaspa-hashes 2.1.0", + "kaspa-math 2.1.0", + "kaspa-merkle 2.1.0", + "kaspa-muhash 2.1.0", + "kaspa-smt 2.1.0", + "kaspa-txscript-errors 2.1.0", + "kaspa-utils 2.1.0", + "rand 0.8.8", + "secp256k1", + "serde", + "serde-value", + "serde-wasm-bindgen", + "serde_json", + "smallvec", + "thiserror 2.0.21", + "wasm-bindgen", + "workflow-core", + "workflow-log", + "workflow-serializer", + "workflow-wasm", +] + +[[package]] +name = "kaspa-consensus-notify" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "async-channel 2.5.0", + "cfg-if", + "derive_more 0.99.20", + "futures", + "kaspa-consensus-core 2.1.0", + "kaspa-core 2.1.0", + "kaspa-hashes 2.1.0", + "kaspa-notify", + "kaspa-utils 2.1.0", + "log", + "paste", + "thiserror 2.0.21", + "triggered", +] + +[[package]] +name = "kaspa-consensus-wasm" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "cfg-if", + "faster-hex 0.9.0", + "js-sys", + "kaspa-addresses 2.1.0", + "kaspa-consensus-client", + "kaspa-consensus-core 2.1.0", + "kaspa-hashes 2.1.0", + "kaspa-txscript 2.1.0", + "kaspa-utils 2.1.0", + "rand 0.8.8", + "secp256k1", + "serde", + "serde-wasm-bindgen", + "serde_json", + "thiserror 2.0.21", + "wasm-bindgen", + "workflow-log", + "workflow-wasm", +] + +[[package]] +name = "kaspa-core" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "anyhow", + "cfg-if", + "ctrlc", + "downcast", + "futures-util", + "log", + "log4rs", + "num_cpus", + "thiserror 2.0.21", + "tokio", + "triggered", + "wasm-bindgen", + "workflow-log", +] + +[[package]] +name = "kaspa-core" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "anyhow", + "cfg-if", + "ctrlc", + "downcast", + "futures-util", + "log", + "log4rs", + "num_cpus", + "thiserror 2.0.21", + "tokio", + "triggered", + "wasm-bindgen", + "workflow-log", +] + +[[package]] +name = "kaspa-hashes" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "blake2b_simd", + "blake3", + "borsh", + "cc", + "faster-hex 0.9.0", + "kaspa-utils 2.0.1", + "keccak", + "serde", + "sha2", + "sha2-const-stable", + "wasm-bindgen", + "zerocopy", +] + +[[package]] +name = "kaspa-hashes" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "blake2b_simd", + "blake3", + "borsh", + "cc", + "faster-hex 0.9.0", + "js-sys", + "kaspa-utils 2.1.0", + "keccak", + "serde", + "sha2", + "sha2-const-stable", + "wasm-bindgen", + "workflow-wasm", + "zerocopy", +] + +[[package]] +name = "kaspa-index-core" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "async-channel 2.5.0", + "async-trait", + "derive_more 0.99.20", + "futures", + "kaspa-consensus-core 2.1.0", + "kaspa-hashes 2.1.0", + "kaspa-notify", + "kaspa-utils 2.1.0", + "log", + "paste", + "serde", + "thiserror 2.0.21", + "triggered", +] + +[[package]] +name = "kaspa-math" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "borsh", + "faster-hex 0.9.0", + "js-sys", + "kaspa-utils 2.0.1", + "malachite-base", + "malachite-nz", + "serde", + "serde-wasm-bindgen", + "thiserror 2.0.21", + "wasm-bindgen", + "workflow-core", + "workflow-log", + "workflow-wasm", +] + +[[package]] +name = "kaspa-math" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "borsh", + "faster-hex 0.9.0", + "js-sys", + "kaspa-utils 2.1.0", + "malachite-base", + "malachite-nz", + "serde", + "serde-wasm-bindgen", + "thiserror 2.0.21", + "wasm-bindgen", + "workflow-core", + "workflow-log", + "workflow-wasm", +] + +[[package]] +name = "kaspa-merkle" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "kaspa-hashes 2.0.1", +] + +[[package]] +name = "kaspa-merkle" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "kaspa-hashes 2.1.0", +] + +[[package]] +name = "kaspa-mining-errors" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "kaspa-consensus-core 2.1.0", + "thiserror 2.0.21", +] + +[[package]] +name = "kaspa-muhash" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "kaspa-hashes 2.0.1", + "kaspa-math 2.0.1", + "rand_chacha 0.3.1", + "serde", +] + +[[package]] +name = "kaspa-muhash" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "kaspa-hashes 2.1.0", + "kaspa-math 2.1.0", + "rand_chacha 0.3.1", + "serde", +] + +[[package]] +name = "kaspa-notify" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "async-channel 2.5.0", + "async-trait", + "borsh", + "derive_more 0.99.20", + "futures", + "futures-util", + "indexmap 2.14.2", + "itertools 0.13.0", + "kaspa-addresses 2.1.0", + "kaspa-consensus-core 2.1.0", + "kaspa-core 2.1.0", + "kaspa-hashes 2.1.0", + "kaspa-txscript 2.1.0", + "kaspa-txscript-errors 2.1.0", + "kaspa-utils 2.1.0", + "log", + "parking_lot", + "paste", + "rand 0.8.8", + "serde", + "thiserror 2.0.21", + "triggered", + "workflow-core", + "workflow-log", + "workflow-serializer", +] + +[[package]] +name = "kaspa-rpc-core" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "async-channel 2.5.0", + "async-trait", + "borsh", + "cfg-if", + "derive_more 0.99.20", + "downcast", + "faster-hex 0.9.0", + "hex", + "js-sys", + "kaspa-addresses 2.1.0", + "kaspa-consensus-client", + "kaspa-consensus-core 2.1.0", + "kaspa-consensus-notify", + "kaspa-consensus-wasm", + "kaspa-core 2.1.0", + "kaspa-hashes 2.1.0", + "kaspa-index-core", + "kaspa-math 2.1.0", + "kaspa-mining-errors", + "kaspa-notify", + "kaspa-rpc-macros", + "kaspa-txscript 2.1.0", + "kaspa-utils 2.1.0", + "log", + "paste", + "rand 0.8.8", + "serde", + "serde-wasm-bindgen", + "smallvec", + "thiserror 2.0.21", + "uuid", + "wasm-bindgen", + "workflow-core", + "workflow-serializer", + "workflow-wasm", +] + +[[package]] +name = "kaspa-rpc-macros" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "convert_case 0.6.0", + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", +] + +[[package]] +name = "kaspa-smt" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "blake3", + "kaspa-hashes 2.0.1", + "thiserror 2.0.21", + "zerocopy", +] + +[[package]] +name = "kaspa-smt" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "blake3", + "kaspa-hashes 2.1.0", + "thiserror 2.0.21", + "zerocopy", +] + +[[package]] +name = "kaspa-txscript" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "ark-bn254 0.6.0", + "ark-ec 0.6.0", + "ark-groth16 0.6.0", + "ark-relations 0.6.0", + "ark-serialize 0.6.0", + "ark-snark 0.6.0", + "blake2b_simd", + "blake3", + "borsh", + "cfg-if", + "faster-hex 0.9.0", + "hexplay", + "indexmap 2.14.2", + "itertools 0.13.0", + "kaspa-addresses 2.0.1", + "kaspa-consensus-core 2.0.1", + "kaspa-hashes 2.0.1", + "kaspa-txscript-errors 2.0.1", + "kaspa-utils 2.0.1", + "log", + "parking_lot", + "rand 0.8.8", + "risc0-binfmt", + "risc0-circuit-recursion", + "risc0-core", + "risc0-zkp", + "risc0-zkvm-platform", + "secp256k1", + "serde", + "serde-wasm-bindgen", + "serde_json", + "sha2", + "smallvec", + "thiserror 2.0.21", + "wasm-bindgen", + "workflow-wasm", +] + +[[package]] +name = "kaspa-txscript" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "ark-bn254 0.6.0", + "ark-ec 0.6.0", + "ark-groth16 0.6.0", + "ark-relations 0.6.0", + "ark-serialize 0.6.0", + "ark-snark 0.6.0", + "blake2b_simd", + "blake3", + "borsh", + "cfg-if", + "faster-hex 0.9.0", + "hexplay", + "indexmap 2.14.2", + "itertools 0.13.0", + "kaspa-addresses 2.1.0", + "kaspa-consensus-core 2.1.0", + "kaspa-hashes 2.1.0", + "kaspa-txscript-errors 2.1.0", + "kaspa-utils 2.1.0", + "log", + "parking_lot", + "rand 0.8.8", + "risc0-binfmt", + "risc0-circuit-recursion", + "risc0-core", + "risc0-zkp", + "risc0-zkvm-platform", + "secp256k1", + "serde", + "serde-wasm-bindgen", + "serde_json", + "sha2", + "smallvec", + "thiserror 2.0.21", + "wasm-bindgen", + "workflow-wasm", +] + +[[package]] +name = "kaspa-txscript-errors" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "borsh", + "kaspa-hashes 2.0.1", + "secp256k1", + "thiserror 2.0.21", +] + +[[package]] +name = "kaspa-txscript-errors" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "borsh", + "kaspa-hashes 2.1.0", + "secp256k1", + "thiserror 2.0.21", +] + +[[package]] +name = "kaspa-txscript-zk-sdk" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "ark-bn254 0.6.0", + "ark-ec 0.6.0", + "ark-groth16 0.6.0", + "ark-serialize 0.6.0", + "kaspa-txscript 2.0.1", + "risc0-binfmt", + "risc0-groth16", + "risc0-zkvm", + "sha2", + "thiserror 2.0.21", +] + +[[package]] +name = "kaspa-utils" +version = "2.0.1" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=a41a333b08848f41bf737b72592e463a6011b8ac#a41a333b08848f41bf737b72592e463a6011b8ac" +dependencies = [ + "async-channel 2.5.0", + "borsh", + "cfg-if", + "faster-hex 0.9.0", + "ipnet", + "itertools 0.13.0", + "log", + "once_cell", + "parking_lot", + "serde", + "sha2", + "smallvec", + "thiserror 2.0.21", + "uuid", + "wasm-bindgen", +] + +[[package]] +name = "kaspa-utils" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "async-channel 2.5.0", + "borsh", + "cfg-if", + "faster-hex 0.9.0", + "ipnet", + "itertools 0.13.0", + "log", + "once_cell", + "parking_lot", + "serde", + "sha2", + "smallvec", + "thiserror 2.0.21", + "triggered", + "uuid", + "wasm-bindgen", +] + +[[package]] +name = "kaspa-wasm-core" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "faster-hex 0.9.0", + "hexplay", + "js-sys", + "wasm-bindgen", + "workflow-wasm", +] + +[[package]] +name = "kaspascript-codegen" +version = "0.1.0" +dependencies = [ + "kaspascript-ir", + "kaspascript-lexer", + "kaspascript-model", + "serde", + "sha2", + "thiserror 1.0.69", +] + +[[package]] +name = "kaspascript-ir" +version = "0.1.0" +dependencies = [ + "kaspascript-lexer", + "kaspascript-model", + "kaspascript-parser", + "kaspascript-semantic", + "serde", + "thiserror 1.0.69", +] + +[[package]] +name = "kaspascript-lexer" +version = "0.1.0" +dependencies = [ + "logos", + "serde", + "thiserror 1.0.69", +] + +[[package]] +name = "kaspascript-model" +version = "0.1.0" +dependencies = [ + "kaspascript-lexer", + "serde", +] + +[[package]] +name = "kaspascript-parser" +version = "0.1.0" +dependencies = [ + "kaspascript-lexer", + "serde", + "thiserror 1.0.69", +] + +[[package]] +name = "kaspascript-semantic" +version = "0.1.0" +dependencies = [ + "kaspascript-lexer", + "kaspascript-parser", + "thiserror 1.0.69", +] + +[[package]] +name = "kaspascript-toccata-native" +version = "0.1.0" +dependencies = [ + "kaspa-consensus-core 2.1.0", + "kaspa-rpc-core", + "kaspa-txscript 2.1.0", + "kaspascript-codegen", + "secp256k1", + "serde_json", + "silverscript-lang", + "thiserror 1.0.69", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures 0.2.17", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb" +dependencies = [ + "spin", +] + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[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.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" +dependencies = [ + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" +dependencies = [ + "serde_core", + "value-bag", +] + +[[package]] +name = "log-mdc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" + +[[package]] +name = "log4rs" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e947bb896e702c711fccc2bf02ab2abb6072910693818d1d6b07ee2b9dfd86c" +dependencies = [ + "anyhow", + "arc-swap", + "chrono", + "derive_more 2.1.1", + "flate2", + "fnv", + "humantime", + "libc", + "log", + "log-mdc", + "mock_instant", + "parking_lot", + "rand 0.9.5", + "serde", + "serde-value", + "serde_json", + "serde_yaml", + "thiserror 2.0.21", + "thread-id", + "typemap-ors", + "unicode-segmentation", + "winapi", +] + +[[package]] +name = "logos" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7251356ef8cb7aec833ddf598c6cb24d17b689d20b993f9d11a3d764e34e6458" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f80069600c0d66734f5ff52cc42f2dabd6b29d205f333d61fd7832e9e9963f" +dependencies = [ + "beef", + "fnv", + "lazy_static", + "proc-macro2", + "quote", + "regex-syntax", + "syn 2.0.119", +] + +[[package]] +name = "logos-derive" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24fb722b06a9dc12adb0963ed585f19fc61dc5413e6a9be9422ef92c091e731d" +dependencies = [ + "logos-codegen", +] + +[[package]] +name = "malachite-base" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4f44099731f17094b07825c88ccb5fbd1bfa1f82fafff7daa33e8b8652db16e" +dependencies = [ + "hashbrown 0.16.1", + "itertools 0.14.0", + "libm", + "ryu", +] + +[[package]] +name = "malachite-nz" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a137660cdba20f136c8a223125f08088adb4e0b72fbb8466f08c43e31cc0427d" +dependencies = [ + "itertools 0.14.0", + "libm", + "malachite-base", + "wide", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "metal" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" +dependencies = [ + "bitflags 2.13.2", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mock_instant" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb517913cfcfb9eeda59f36020269075a152701a01606c612f547e4890be399" + +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.13.2", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "no_std_strings" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5b0c77c1b780822bc749a33e39aeb2c07584ab93332303babeabb645298a76e" + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-integer" +version = "0.1.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi 0.5.3", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "num_threads" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cabcc654086861f9e1bc5115258de62ef92c79b20f4615a1b0cc57c4e82027d4" +dependencies = [ + "libc", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08849bbd4767dfae9457696856ae1c84fe4e0281bbe4a7abff2d0e06fb7981f8" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "parse-variants" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84b4d1bb0b90012ce8056bd6bb5168d8de026d633dd592a732da5a25d3f6c74c" +dependencies = [ + "parse-variants-derive", +] + +[[package]] +name = "parse-variants-derive" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d80829147ec6f1b27109c7daaea62fc3a21a0348cdddf22b4093f0c35ab25a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pest" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd47a460a9cbc3b3429c7e22bf0d76653e779319bae45a499ca010c9a990bb23" +dependencies = [ + "memchr", + "psm", + "stacker", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "203e46697708f7519ab1608393cf89239cafb46b8e6d08a8ffe359359b11ef44" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e84ae6340a458d3d6cfc73cf328cf3cfe90b2484cd0de25eb66aa954615ed4d5" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "pest_meta" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b57f92f32b3dbce6598fd8f5cdf1f06a6072570b8103fa21728fa9036923e710" +dependencies = [ + "pest", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pin-utils" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13bee6c73da26345c729282832b60b0363cf3dd9f4bfd81d8551b7a1c889a113" + +[[package]] +name = "piper" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.5.3", + "pin-project-lite", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "portable-atomic-util" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + +[[package]] +name = "powerfmt" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6394b9e965e73d0a289ee54f589087e2c676aedf60885baf52c76b771e4958" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8530004ccb15eae51c7e40009fbe317f341f804db54dc033eec1c50be28cfa0" +dependencies = [ + "bitflags 2.13.2", + "chacha20", + "core_detect", + "num-traits", + "rand 0.10.3", + "rand_xorshift", + "unarray", +] + +[[package]] +name = "psm" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810" +dependencies = [ + "cc", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" +dependencies = [ + "chacha20", + "getrandom 0.4.3", + "rand_core 0.10.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "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.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[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_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_xorshift" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60aa6af80be32871323012e02e6e65f8a7cc7890931ae421d217ad8fe0df2ccf" +dependencies = [ + "rand_core 0.10.1", +] + +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.2", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "ref-cast" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "risc0-binfmt" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1883f0c5d19b865f395209a137dcb29e56dc49951424967b8d0114c129f46e77" +dependencies = [ + "anyhow", + "borsh", + "bytemuck", + "derive_more 2.1.1", + "elf", + "lazy_static", + "postcard", + "rand 0.9.5", + "risc0-zkp", + "risc0-zkvm-platform", + "ruint", + "semver", + "serde", + "tracing", +] + +[[package]] +name = "risc0-circuit-keccak" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f543c60287fece797a5da4209384ab1bfebd9644fcfe591e11b1aa85f1a02f8" +dependencies = [ + "anyhow", + "bytemuck", + "paste", + "risc0-binfmt", + "risc0-circuit-recursion", + "risc0-core", + "risc0-zkp", + "tracing", +] + +[[package]] +name = "risc0-circuit-recursion" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2347e909c6b2a65584b5898f3802eec5b8c1b4b45329edfdd8587b6a04dd3357" +dependencies = [ + "anyhow", + "bytemuck", + "hex", + "metal", + "risc0-core", + "risc0-zkp", + "tracing", +] + +[[package]] +name = "risc0-circuit-rv32im" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61676419814a818fdb5e10066b13c5488b3f54aa9668794bd06c99bc91bff1f2" +dependencies = [ + "anyhow", + "bit-vec", + "bytemuck", + "derive_more 2.1.1", + "paste", + "risc0-binfmt", + "risc0-core", + "risc0-zkp", + "serde", + "tracing", +] + +[[package]] +name = "risc0-core" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b956a976b8ce4713694dcc6c370b522a42ccef4ba45da5b6e57dbf26cdb7b1" +dependencies = [ + "bytemuck", + "rand_core 0.9.5", +] + +[[package]] +name = "risc0-groth16" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc57e76bb87193d154ac5ee6ee352fbd7edabddab36f02a81f40a048e5ca14f9" +dependencies = [ + "anyhow", + "ark-bn254 0.5.0", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-groth16 0.5.0", + "ark-serialize 0.5.0", + "bytemuck", + "hex", + "num-bigint", + "num-traits", + "risc0-binfmt", + "risc0-zkp", + "serde", +] + +[[package]] +name = "risc0-zkos-v1compat" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bd70cb45b5d37d025f25663b87c6b9dc9df7f413ee2068531a57f50b0eb95db" +dependencies = [ + "include_bytes_aligned", + "no_std_strings", + "risc0-zkvm-platform", +] + +[[package]] +name = "risc0-zkp" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f40d362a6c146ec6dc69208f539b92fd86e47b0dbc2083801423034a38155a2" +dependencies = [ + "anyhow", + "blake2", + "borsh", + "bytemuck", + "cfg-if", + "digest", + "hex", + "hex-literal", + "metal", + "paste", + "rand_core 0.9.5", + "risc0-core", + "risc0-zkvm-platform", + "serde", + "sha2", + "stability", + "tracing", +] + +[[package]] +name = "risc0-zkvm" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39d9943fe71decea1e8b6a99480cefa33799ab08b5abfccd7e2a18fb07121c1" +dependencies = [ + "anyhow", + "borsh", + "bytemuck", + "derive_more 2.1.1", + "hex", + "risc0-binfmt", + "risc0-circuit-keccak", + "risc0-circuit-recursion", + "risc0-circuit-rv32im", + "risc0-core", + "risc0-groth16", + "risc0-zkos-v1compat", + "risc0-zkp", + "risc0-zkvm-platform", + "rrs-lib", + "semver", + "serde", + "sha2", + "stability", + "tracing", +] + +[[package]] +name = "risc0-zkvm-platform" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4db893788c416287e2e1a87e6b8f5302511a04a45329e699d6a32a16874fd24f" +dependencies = [ + "bytemuck", + "cfg-if", + "getrandom 0.2.17", + "getrandom 0.3.4", + "libm", + "num_enum", + "paste", + "stability", +] + +[[package]] +name = "rlimit" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a" +dependencies = [ + "libc", +] + +[[package]] +name = "rrs-lib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4382d3af3a4ebdae7f64ba6edd9114fff92c89808004c4943b393377a25d001" +dependencies = [ + "downcast-rs", + "paste", +] + +[[package]] +name = "ruint" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2973657b5127d510e230f5c63d2d106af9c8f79393d8b9f4647323e8196bdde5" +dependencies = [ + "borsh", + "proptest", + "rand 0.8.8", + "rand 0.9.5", + "ruint-macro", + "serde_core", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" +dependencies = [ + "bitflags 2.13.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "safe_arch" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42c6efa15875e6ecb39ca61fb0b0c1a40b84fac5a5ffe71eef7d1000c8eb3f5f" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab508826f74a77ca9d5aba6ff19b522583ee3eaf28a19384ff3d0e5835fadf6e" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "secp256k1" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" +dependencies = [ + "rand 0.8.8", + "secp256k1-sys", + "serde", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +dependencies = [ + "cc", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_with" +version = "3.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9adc193c780ef8f159aee8b61e2d5801aaa555e6eb0947fe45530ec506296f" +dependencies = [ + "base64", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.2", + "jiff", + "schemars 0.9.0", + "schemars 1.2.3", + "serde_core", + "serde_json", + "time", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.14.2", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest", +] + +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "silverscript-abi" +version = "0.1.0" +source = "git+https://github.com/kaspanet/silverscript?rev=3ed973335b59269293564805cc2c58a14595ec03#3ed973335b59269293564805cc2c58a14595ec03" +dependencies = [ + "blake3", + "faster-hex 0.10.1", + "kaspa-txscript 2.0.1", + "serde", + "serde_bytes", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "silverscript-lang" +version = "1.0.0" +source = "git+https://github.com/kaspanet/silverscript?rev=3ed973335b59269293564805cc2c58a14595ec03#3ed973335b59269293564805cc2c58a14595ec03" +dependencies = [ + "blake2b_simd", + "blake3", + "chrono", + "clap", + "faster-hex 0.10.1", + "indexmap 2.14.2", + "kaspa-consensus-core 2.0.1", + "kaspa-txscript 2.0.1", + "kaspa-txscript-errors 2.0.1", + "kaspa-txscript-zk-sdk", + "pest", + "pest_derive", + "rand 0.8.8", + "secp256k1", + "semver", + "serde", + "serde_json", + "silverscript-abi", + "thiserror 1.0.69", +] + +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3dc8af474f516a851ff4bd12db780f948b9250ad37211e4eec0bccea54e01b" +dependencies = [ + "serde", +] + +[[package]] +name = "spin" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" + +[[package]] +name = "stability" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "stacker" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707f49d46706bacf8a2b00d51dace3f9de527c13eec3778f570c411f89e69967" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.61.2", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" +dependencies = [ + "thiserror-impl 2.0.21", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "thread-id" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2010d27add3f3240c1fef7959f46c814487b216baee662af53be645ba7831c07" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "thread_local" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" + +[[package]] +name = "tokio" +version = "1.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c168a474b95bfecfe908a65d4bdffc523144b649a74c09c286afb35d53e0bc" +dependencies = [ + "bytes", + "pin-project-lite", + "tokio-macros", +] + +[[package]] +name = "tokio-macros" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "toml_datetime" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.17+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" +dependencies = [ + "indexmap 2.14.2", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "triggered" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "593eddbc8a11f3e099e942c8c065fe376b9d1776741430888f2796682e08ab43" + +[[package]] +name = "typemap-ors" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a68c24b707f02dd18f1e4ccceb9d49f2058c2fb86384ef9972592904d7a28867" +dependencies = [ + "unsafe-any-ors", +] + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "unsafe-any-ors" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a303d30665362d9680d7d91d78b23f5f899504d4f08b3c4cf08d055d87c0ad" +dependencies = [ + "destructure_traitobject", +] + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc1186384beb7dd8eedea376413fd654937285ea6c9cfbb928dc3043ea4b606" +dependencies = [ + "getrandom 0.4.3", + "js-sys", + "rand 0.10.3", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "value-bag" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2799ffb329a792ecfd902b71306c8a815a6ef1c0470fa9953a6aa4d4cecbe511" + +[[package]] +name = "vergen" +version = "8.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2990d9ea5967266ea0ccf413a4aa5c42a93dbcfda9cb49a97de6931726b12566" +dependencies = [ + "anyhow", + "cargo_metadata", + "cfg-if", + "regex", + "rustc_version", + "rustversion", + "time", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.119", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wide" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d920ac99c3c8edce110cb8d07dbb324d6d026011dce85b1e9355b70f0adacc4f" +dependencies = [ + "bytemuck", + "safe_arch", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +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", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "workflow-core" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d67bbe225ea90aa6979167f28935275506696ac867661e218893d3a42e1666" +dependencies = [ + "async-channel 2.5.0", + "async-std", + "borsh", + "bs58", + "cfg-if", + "chrono", + "dirs", + "faster-hex 0.9.0", + "futures", + "getrandom 0.2.17", + "instant", + "js-sys", + "rand 0.8.8", + "rlimit", + "serde", + "serde-wasm-bindgen", + "thiserror 1.0.69", + "tokio", + "triggered", + "vergen", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "workflow-core-macros", + "workflow-log", +] + +[[package]] +name = "workflow-core-macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65659ed208b0066a9344142218abda353eb6c6cc1fc3ae4808b750c560de004b" +dependencies = [ + "convert_case 0.6.0", + "parse-variants", + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "sha2", + "syn 1.0.109", + "workflow-macro-tools", +] + +[[package]] +name = "workflow-log" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64bf52c539193f219b7a79eb0c7c5f6c222ccf9b95c5e0bd59e924feb762256f" +dependencies = [ + "cfg-if", + "console", + "downcast", + "hexplay", + "lazy_static", + "log", + "termcolor", + "wasm-bindgen", +] + +[[package]] +name = "workflow-macro-tools" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "085d3045d5ca780fb589d230030e34fec962b3638d6c69806a72a7d7d1affea4" +dependencies = [ + "convert_case 0.6.0", + "parse-variants", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "workflow-panic-hook" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74c76ca8b459e4f0c949f06ce2d45565a6769748e83ca7064d36671bbd67b4da" +dependencies = [ + "cfg-if", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "workflow-serializer" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64679db6856852a472caff4ce869e3ecebe291fbccc9406e9643eb5951a0904a" +dependencies = [ + "ahash", + "borsh", + "serde", +] + +[[package]] +name = "workflow-wasm" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799e5fbf266e0fffb5c24d6103735eb2b94bb31f93b664b91eaaf63b4f959804" +dependencies = [ + "cfg-if", + "faster-hex 0.9.0", + "futures", + "js-sys", + "serde", + "serde-wasm-bindgen", + "thiserror 1.0.69", + "wasm-bindgen", + "wasm-bindgen-futures", + "workflow-core", + "workflow-log", + "workflow-panic-hook", + "workflow-wasm-macros", +] + +[[package]] +name = "workflow-wasm-macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40237c65ecff78dbfedb13985e33f802a31f6f7de72dff12a6674fcdcf601822" +dependencies = [ + "js-sys", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen", +] + +[[package]] +name = "zerocopy" +version = "0.8.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5fe1f8f1b06191a00962174c61aa5005e0bb391a6d80d07e24d115c01a92ed8" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863ad3ac83293fb4d740aedbfdc9240dd8d1a50c1099acd76ce80ce7c7230c7f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zeroize" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13084392c5e4bc371903e2935a5eaeed24905a7511356b883835e18a78f6879" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zlib-rs" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/compatibility/toccata-v2/Cargo.toml b/compatibility/toccata-v2/Cargo.toml new file mode 100644 index 0000000..99dad3c --- /dev/null +++ b/compatibility/toccata-v2/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "kaspascript-toccata-native" +version = "0.1.0" +edition = "2024" +rust-version = "1.95" +publish = false + +[workspace] + +[dependencies] +kaspa-consensus-core = { git = "https://github.com/kaspanet/rusty-kaspa", rev = "01b532e8b553523216471682649693af92f0fd16" } +kaspa-rpc-core = { git = "https://github.com/kaspanet/rusty-kaspa", rev = "01b532e8b553523216471682649693af92f0fd16" } +kaspa-txscript = { git = "https://github.com/kaspanet/rusty-kaspa", rev = "01b532e8b553523216471682649693af92f0fd16" } +serde_json = "1.0" +thiserror = "1.0" +silverscript-lang = { git = "https://github.com/kaspanet/silverscript", rev = "3ed973335b59269293564805cc2c58a14595ec03", optional = true } + +[features] +silverscript = ["dep:silverscript-lang"] + +[dev-dependencies] +secp256k1 = { version = "0.29.1", features = ["global-context"] } +kaspascript-codegen = { path = "../../compiler/codegen" } + +[profile.dev] +debug = 0 diff --git a/compatibility/toccata-v2/README.md b/compatibility/toccata-v2/README.md new file mode 100644 index 0000000..a4495ba --- /dev/null +++ b/compatibility/toccata-v2/README.md @@ -0,0 +1,41 @@ +# Native Toccata SDK Integration + +This isolated companion crate constructs real Rusty Kaspa v1 transactions using +the exact v2.1.0 release commit. It preserves native compute budgets, storage +mass, covenant bindings, authorizing input, genesis IDs, and RPC serialization. +It provides no key storage, signing, connection, or broadcast operation. + +`Tn10Plan` requires explicit inputs, every recipient/change output, an exact +integer-sompi fee, and network identity `kaspa-testnet-10`. The caller must +verify that identity against its node and supply wallet/node-calculated storage +mass. Offline script validation delegates to the actual v2.1.0 script engine. +It does not replace node UTXO, fee-policy, consensus, or DAG acceptance checks. + +Run from the repository root: + +```bash +cargo test --manifest-path compatibility/toccata-v2/Cargo.toml --locked +cargo test --manifest-path compatibility/toccata-v2/Cargo.toml --features silverscript --locked +cargo clippy --manifest-path compatibility/toccata-v2/Cargo.toml --all-targets -- -D warnings +``` + +The optional interoperability test compiles source with released Silverscript +v1.0.0 and executes the resulting bytecode in the pinned v2.1.0 native engine. +Both compiler paths have positive and underpayment controls: KaspaScript spend +instantiation and Silverscript ABI dispatch are exercised independently. +The dependency graph intentionally retains Silverscript's own Rusty Kaspa pin; +bytecode is the boundary, not an assumed shared Rust struct layout. + +This remains an isolated validation/integration lane. The existing SDK's +`0.15.0` testnet feature is historical and does not gain Toccata support from +this crate. Existing preview/mainnet gates remain in effect. + +All amounts, outpoints, scripts, and storage mass in unit tests are offline +fixtures. Test success must not be reported as accepted TN10 transactions or a +funded lifecycle. Live TN10 verification requires an explicitly scoped funded +test wallet, a verified node, accepted transaction IDs, and indexer evidence. + +The signed fixture covers genesis, continuation, native exit, modified-payment +rejection, replay rejection in a local UTXO ledger, and deterministic fixture +rollback/reapply. It uses a public deterministic fixture key. The library itself +never handles signing keys. The ledger is a test harness, not a DAG indexer. diff --git a/compatibility/toccata-v2/src/lib.rs b/compatibility/toccata-v2/src/lib.rs new file mode 100644 index 0000000..93e4367 --- /dev/null +++ b/compatibility/toccata-v2/src/lib.rs @@ -0,0 +1,175 @@ +//! Pinned native Toccata construction and offline script validation for TN10. +//! No keys, RPC connections, signing, or broadcasting are performed here. + +use std::collections::HashSet; + +use kaspa_consensus_core::hashing::sighash::SigHashReusedValuesUnsync; +use kaspa_consensus_core::subnets::SUBNETWORK_ID_NATIVE; +pub use kaspa_consensus_core::tx::{ + CovenantBinding, GenesisCovenantGroup, PopulatedTransaction, ScriptPublicKey, Transaction, + TransactionInput, TransactionOutpoint, TransactionOutput, UtxoEntry, +}; +use kaspa_rpc_core::RpcTransaction; +use kaspa_txscript::caches::Cache; +use kaspa_txscript::covenants::CovenantsContext; +use kaspa_txscript::{EngineCtx, TxScriptEngine}; +use thiserror::Error; + +pub const UPSTREAM_COMMIT: &str = "01b532e8b553523216471682649693af92f0fd16"; +pub const TN10_NETWORK: &str = "kaspa-testnet-10"; + +#[derive(Clone)] +pub struct InputPlan { + pub outpoint: TransactionOutpoint, + pub utxo: UtxoEntry, + pub compute_budget: u16, + pub sequence: u64, + /// Caller-supplied witness bytes; no secret material is generated or retained. + pub witness: Vec, +} + +pub struct Tn10Plan { + /// The caller must verify this identity against its node before submission. + pub network: String, + pub inputs: Vec, + /// Includes every recipient and change output explicitly. + pub outputs: Vec, + pub genesis_groups: Vec, + pub lock_time: u64, + /// Must come from the wallet/node mass calculation, not a guessed fee model. + pub storage_mass: u64, + pub expected_fee: u64, +} + +#[derive(Debug, Error)] +pub enum PlanError { + #[error("only verified kaspa-testnet-10 plans are accepted")] + WrongNetwork, + #[error("inputs and outputs must be non-empty")] + Empty, + #[error("duplicate input outpoint")] + DuplicateInput, + #[error("value sum overflow")] + Overflow, + #[error("input metadata count does not match transaction inputs")] + InputMetadataMismatch, + #[error("outputs exceed inputs or do not match the explicit fee")] + FeeMismatch, + #[error("native covenant validation failed: {0}")] + Covenant(String), + #[error("native script validation failed for input {index}: {reason}")] + Script { index: usize, reason: String }, +} + +pub struct NativeTransaction { + pub transaction: Transaction, + pub entries: Vec, + pub fee: u64, +} + +impl Tn10Plan { + pub fn build(self) -> Result { + if self.network != TN10_NETWORK { + return Err(PlanError::WrongNetwork); + } + if self.inputs.is_empty() || self.outputs.is_empty() { + return Err(PlanError::Empty); + } + let mut outpoints = HashSet::new(); + if self + .inputs + .iter() + .any(|input| !outpoints.insert(input.outpoint)) + { + return Err(PlanError::DuplicateInput); + } + let total_in = self.inputs.iter().try_fold(0u64, |sum, input| { + sum.checked_add(input.utxo.amount) + .ok_or(PlanError::Overflow) + })?; + let total_out = self.outputs.iter().try_fold(0u64, |sum, output| { + sum.checked_add(output.value).ok_or(PlanError::Overflow) + })?; + let fee = total_in + .checked_sub(total_out) + .ok_or(PlanError::FeeMismatch)?; + if fee != self.expected_fee { + return Err(PlanError::FeeMismatch); + } + let entries = self.inputs.iter().map(|input| input.utxo.clone()).collect(); + let inputs = self + .inputs + .into_iter() + .map(|input| { + TransactionInput::new_with_compute_budget( + input.outpoint, + input.witness, + input.sequence, + input.compute_budget, + ) + }) + .collect(); + let mut transaction = Transaction::new_with_mass( + 1, + inputs, + self.outputs, + self.lock_time, + SUBNETWORK_ID_NATIVE, + 0, + vec![], + self.storage_mass, + ); + transaction + .populate_genesis_covenants(&self.genesis_groups) + .map_err(|error| PlanError::Covenant(error.to_string()))?; + transaction.finalize(); + let native = NativeTransaction { + transaction, + entries, + fee, + }; + CovenantsContext::from_tx(&PopulatedTransaction::new( + &native.transaction, + native.entries.clone(), + )) + .map_err(|error| PlanError::Covenant(error.to_string()))?; + Ok(native) + } +} + +impl NativeTransaction { + /// Validates scripts with the real v2.1.0 engine. This is not mempool, + /// fee-policy, DAG acceptance, or live UTXO verification. + pub fn validate_scripts(&self) -> Result<(), PlanError> { + if self.entries.len() != self.transaction.inputs.len() { + return Err(PlanError::InputMetadataMismatch); + } + let tx = PopulatedTransaction::new(&self.transaction, self.entries.clone()); + let context = CovenantsContext::from_tx(&tx) + .map_err(|error| PlanError::Covenant(error.to_string()))?; + let cache = Cache::new(0); + let reused = SigHashReusedValuesUnsync::new(); + for (index, input) in self.transaction.inputs.iter().enumerate() { + TxScriptEngine::from_transaction_input( + &tx, + input, + index, + &self.entries[index], + EngineCtx::new(&cache) + .with_reused(&reused) + .with_covenants_ctx(&context), + Default::default(), + ) + .execute() + .map_err(|error| PlanError::Script { + index, + reason: error.to_string(), + })?; + } + Ok(()) + } + + pub fn rpc_transaction(&self) -> RpcTransaction { + RpcTransaction::from(&self.transaction) + } +} diff --git a/compatibility/toccata-v2/tests/native.rs b/compatibility/toccata-v2/tests/native.rs new file mode 100644 index 0000000..d5214fa --- /dev/null +++ b/compatibility/toccata-v2/tests/native.rs @@ -0,0 +1,389 @@ +use kaspa_consensus_core::Hash; +use kaspa_rpc_core::RpcTransaction; +use kaspa_txscript::opcodes::codes::*; +use kaspa_txscript::script_builder::ScriptBuilder; +use kaspascript_toccata_native::*; + +fn true_script() -> ScriptPublicKey { + ScriptPublicKey::new(0, vec![OpTrue].into()) +} + +fn plan() -> Tn10Plan { + Tn10Plan { + network: TN10_NETWORK.into(), + inputs: vec![InputPlan { + outpoint: TransactionOutpoint::new(Hash::from_u64_word(1), 0), + utxo: UtxoEntry::new(10_000, true_script(), 0, false, None), + compute_budget: 1000, + sequence: u64::MAX, + witness: vec![], + }], + outputs: vec![TransactionOutput::new(9_000, true_script())], + genesis_groups: vec![], + lock_time: 0, + storage_mass: 640, + expected_fee: 1000, + } +} + +#[test] +fn rpc_round_trip_preserves_native_v1_fields_and_genesis_binding() { + let mut p = plan(); + p.genesis_groups.push(GenesisCovenantGroup::new(0, vec![0])); + let native = p.build().unwrap(); + native.validate_scripts().unwrap(); + let rpc_json = serde_json::to_value(native.rpc_transaction()).unwrap(); + let rpc: RpcTransaction = serde_json::from_value(rpc_json).unwrap(); + let restored = Transaction::try_from(rpc).unwrap(); + assert_eq!(restored, native.transaction); + assert_eq!(restored.storage_mass(), 640); + assert_eq!( + restored.inputs[0].compute_commit.compute_budget(), + Some(1000) + ); + assert_eq!(restored.outputs[0].covenant.unwrap().authorizing_input, 0); +} + +#[test] +fn rejects_wrong_network_duplicate_inputs_hidden_fee_and_overflow() { + let mut p = plan(); + p.network = "kaspa-mainnet".into(); + assert!(matches!(p.build(), Err(PlanError::WrongNetwork))); + let mut p = plan(); + p.inputs.push(p.inputs[0].clone()); + assert!(matches!(p.build(), Err(PlanError::DuplicateInput))); + let mut p = plan(); + p.expected_fee = 999; + assert!(matches!(p.build(), Err(PlanError::FeeMismatch))); + let mut p = plan(); + p.inputs[0].utxo.amount = u64::MAX; + let mut extra = p.inputs[0].clone(); + extra.outpoint.index = 1; + p.inputs.push(extra); + assert!(matches!(p.build(), Err(PlanError::Overflow))); +} + +// An offline introspection fixture, not a wallet authorization policy. +fn continuation_script() -> ScriptPublicKey { + let script = ScriptBuilder::new() + .add_i64(0) + .unwrap() + .add_op(OpAuthOutputCount) + .unwrap() + .add_i64(1) + .unwrap() + .add_op(OpEqualVerify) + .unwrap() + .add_i64(0) + .unwrap() + .add_op(OpTxOutputAmount) + .unwrap() + .add_i64(0) + .unwrap() + .add_op(OpTxInputAmount) + .unwrap() + .add_i64(1000) + .unwrap() + .add_op(OpSub) + .unwrap() + .add_op(OpGreaterThanOrEqual) + .unwrap() + .drain(); + ScriptPublicKey::new(0, script.into()) +} + +#[test] +fn native_genesis_continuation_replay_and_invalid_binding() { + let mut genesis = plan(); + genesis.outputs[0].script_public_key = continuation_script(); + genesis + .genesis_groups + .push(GenesisCovenantGroup::new(0, vec![0])); + let genesis = genesis.build().unwrap(); + genesis.validate_scripts().unwrap(); + let output = &genesis.transaction.outputs[0]; + let covenant_id = output.covenant.unwrap().covenant_id; + let spent_outpoint = TransactionOutpoint::new(genesis.transaction.id(), 0); + let mut next = plan(); + next.inputs[0].outpoint = spent_outpoint; + next.inputs[0].utxo = UtxoEntry::new( + output.value, + output.script_public_key.clone(), + 0, + false, + Some(covenant_id), + ); + next.outputs[0] = TransactionOutput::with_covenant( + 8_000, + continuation_script(), + Some(CovenantBinding::new(0, covenant_id)), + ); + let continuation = next.build().unwrap(); + continuation.validate_scripts().unwrap(); + assert_eq!( + continuation.transaction.outputs[0] + .covenant + .unwrap() + .covenant_id, + covenant_id + ); + + let mut invalid = continuation; + invalid.transaction.outputs[0].covenant = None; + assert!( + invalid.validate_scripts().is_err(), + "covenant cannot disappear in this fixture" + ); + invalid.transaction.outputs[0].covenant = + Some(CovenantBinding::new(0, Hash::from_u64_word(99))); + assert!( + invalid.validate_scripts().is_err(), + "invalid genesis/continuation lineage must fail" + ); +} + +fn signed_vault_script(key: &secp256k1::Keypair) -> ScriptPublicKey { + let public_key = key.x_only_public_key().0.serialize(); + let payout = true_script(); + // Introspection returns the big-endian script version followed by bytecode. + let payout_spk: Vec = payout + .version() + .to_be_bytes() + .into_iter() + .chain(payout.script().iter().copied()) + .collect(); + let script = ScriptBuilder::new() + .add_data(&public_key) + .unwrap() + .add_op(OpCheckSigVerify) + .unwrap() + .add_op(OpIf) + .unwrap() + .add_i64(0) + .unwrap() + .add_op(OpAuthOutputCount) + .unwrap() + .add_i64(1) + .unwrap() + .add_op(OpEqualVerify) + .unwrap() + .add_i64(0) + .unwrap() + .add_op(OpTxOutputSpk) + .unwrap() + .add_i64(0) + .unwrap() + .add_op(OpTxInputSpk) + .unwrap() + .add_op(OpEqualVerify) + .unwrap() + .add_op(OpElse) + .unwrap() + .add_i64(0) + .unwrap() + .add_op(OpAuthOutputCount) + .unwrap() + .add_i64(0) + .unwrap() + .add_op(OpEqualVerify) + .unwrap() + .add_i64(0) + .unwrap() + .add_op(OpTxOutputSpk) + .unwrap() + .add_data(&payout_spk) + .unwrap() + .add_op(OpEqualVerify) + .unwrap() + .add_op(OpEndIf) + .unwrap() + .add_i64(0) + .unwrap() + .add_op(OpTxOutputAmount) + .unwrap() + .add_i64(0) + .unwrap() + .add_op(OpTxInputAmount) + .unwrap() + .add_i64(1000) + .unwrap() + .add_op(OpSub) + .unwrap() + .add_op(OpGreaterThanOrEqual) + .unwrap() + .drain(); + ScriptPublicKey::new(0, script.into()) +} + +fn sign_fixture(native: &mut NativeTransaction, continuation: bool, key: &secp256k1::Keypair) { + use kaspa_consensus_core::hashing::{ + sighash::{SigHashReusedValuesUnsync, calc_schnorr_signature_hash}, + sighash_type::SIG_HASH_ALL, + }; + let hash = calc_schnorr_signature_hash( + &PopulatedTransaction::new(&native.transaction, native.entries.clone()), + 0, + SIG_HASH_ALL, + &SigHashReusedValuesUnsync::new(), + ); + let message = secp256k1::Message::from_digest(hash.as_bytes()); + let signature = key.sign_schnorr(message); + let mut bytes = signature.as_ref().to_vec(); + bytes.push(SIG_HASH_ALL.to_u8()); + native.transaction.inputs[0].signature_script = ScriptBuilder::new() + .add_i64(i64::from(continuation)) + .unwrap() + .add_data(&bytes) + .unwrap() + .drain(); + native.transaction.finalize(); +} + +// This ledger models only fixture UTXO consumption. It is not a node or indexer. +fn apply_fixture( + ledger: &mut std::collections::HashMap, + native: &NativeTransaction, +) -> Result<(), String> { + for (input, expected) in native.transaction.inputs.iter().zip(&native.entries) { + if ledger.get(&input.previous_outpoint) != Some(expected) { + return Err("spent or mismatched fixture input".into()); + } + } + native + .validate_scripts() + .map_err(|error| error.to_string())?; + for input in &native.transaction.inputs { + ledger.remove(&input.previous_outpoint); + } + for (index, output) in native.transaction.outputs.iter().enumerate() { + ledger.insert( + TransactionOutpoint::new(native.transaction.id(), index as u32), + UtxoEntry::new( + output.value, + output.script_public_key.clone(), + 0, + false, + output.covenant.map(|binding| binding.covenant_id), + ), + ); + } + Ok(()) +} + +#[test] +fn signed_offline_vault_lifecycle_rejects_replay_and_invalid_payment() { + // Public deterministic fixture key, used only for offline tests. + let key = secp256k1::Keypair::from_seckey_slice(secp256k1::SECP256K1, &[7; 32]).unwrap(); + let mut genesis = plan(); + let mut ledger = std::collections::HashMap::from([( + genesis.inputs[0].outpoint, + genesis.inputs[0].utxo.clone(), + )]); + genesis.outputs[0].script_public_key = signed_vault_script(&key); + genesis + .genesis_groups + .push(GenesisCovenantGroup::new(0, vec![0])); + let genesis = genesis.build().unwrap(); + apply_fixture(&mut ledger, &genesis).unwrap(); + let before_continuation = ledger.clone(); + let (outpoint, utxo) = ledger.iter().next().unwrap(); + let mut next = plan(); + next.inputs[0].outpoint = *outpoint; + next.inputs[0].utxo = utxo.clone(); + next.outputs[0] = TransactionOutput::with_covenant( + 8_000, + signed_vault_script(&key), + Some(CovenantBinding::new(0, utxo.covenant_id.unwrap())), + ); + let mut next = next.build().unwrap(); + sign_fixture(&mut next, true, &key); + apply_fixture(&mut ledger, &next).unwrap(); + let accepted_state = ledger.clone(); + assert!(apply_fixture(&mut ledger, &next).is_err()); + assert_eq!( + ledger, accepted_state, + "replay must not mutate fixture state" + ); + ledger = before_continuation; + apply_fixture(&mut ledger, &next).unwrap(); + assert_eq!( + ledger, accepted_state, + "reapplying after fixture rollback is deterministic" + ); + + let (outpoint, utxo) = ledger.iter().next().unwrap(); + let mut exit = plan(); + exit.inputs[0].outpoint = *outpoint; + exit.inputs[0].utxo = utxo.clone(); + exit.outputs[0].value = 7_000; + let mut exit = exit.build().unwrap(); + sign_fixture(&mut exit, false, &key); + exit.validate_scripts().unwrap(); + exit.transaction.outputs[0].value = 6_999; + assert!( + apply_fixture(&mut ledger, &exit).is_err(), + "modified signed output must fail" + ); + assert_eq!(ledger, accepted_state); + exit.transaction.outputs[0].value = 7_000; + exit.transaction.finalize(); + apply_fixture(&mut ledger, &exit).unwrap(); + assert_eq!(ledger.len(), 1); + let payout = ledger.values().next().unwrap(); + assert_eq!(payout.amount, 7_000); + assert_eq!(payout.covenant_id, None); +} + +#[cfg(feature = "silverscript")] +#[test] +fn released_silverscript_bytecode_executes_in_v2_1_native_engine() { + use silverscript_lang::compiler::{CompileOptions, compile_contract}; + let source = "contract KeepValue() { entry spend() { require(tx.outputs[0].value >= tx.inputs[0].value - 1000); } }"; + let compiled = compile_contract(source, &[], CompileOptions::default()).unwrap(); + assert!(!compiled.bytecode.is_empty()); + let mut p = plan(); + p.inputs[0].witness = ScriptBuilder::new() + .add_data(&compiled.dispatch_tags["spend"]) + .unwrap() + .drain(); + p.inputs[0].utxo.script_public_key = ScriptPublicKey::new(0, compiled.bytecode.into()); + let mut native = p.build().unwrap(); + native.validate_scripts().unwrap(); + native.transaction.outputs[0].value = 8_999; + assert!( + native.validate_scripts().is_err(), + "compiled value constraint must reject underpayment" + ); +} + +#[test] +fn kaspascript_compiler_output_runs_in_v2_1_native_engine() { + let source = + "contract PreserveValue { spend advance() { require output(0).value >= input(0).value; } }"; + let compiled = kaspascript_codegen::compile_file(source, "native-compat.ks").unwrap(); + let spend_script = kaspascript_codegen::backends::toccata::compile_spend_script( + &compiled.contracts[0].spends[0].instructions, + ) + .unwrap(); + let mut p = plan(); + p.inputs[0].utxo.script_public_key = ScriptPublicKey::new(0, spend_script.into()); + p.outputs[0].value = 10_000; + p.expected_fee = 0; + let mut native = p.build().unwrap(); + native.validate_scripts().unwrap(); + native.transaction.outputs[0].value = 9_999; + assert!( + native.validate_scripts().is_err(), + "KaspaScript constraint must reject value loss" + ); +} + +#[test] +fn missing_input_metadata_returns_an_error_without_panicking() { + let mut native = plan().build().unwrap(); + native.entries.clear(); + assert!(matches!( + native.validate_scripts(), + Err(PlanError::InputMetadataMismatch) + )); +} diff --git a/compiler/codegen/src/backends/toccata.rs b/compiler/codegen/src/backends/toccata.rs index 2eebc7e..a4f0323 100644 --- a/compiler/codegen/src/backends/toccata.rs +++ b/compiler/codegen/src/backends/toccata.rs @@ -132,6 +132,18 @@ pub fn compile_instruction_sequence(instructions: &[Instruction]) -> Result Result, CodegenError> { + if instructions.is_empty() { + return Err(CodegenError::EmptyBytecode); + } + let mut bytecode = compile_instruction_sequence(instructions)?; + bytecode.push(OP_1); + Ok(bytecode) +} + fn collect_grounding( record: &crate::grounding::GroundingRecord, target: Target, @@ -308,6 +320,23 @@ mod tests { use super::*; use kaspascript_ir::{IrContract, IrSpend}; + #[test] + fn spend_instantiation_closes_verified_body_and_rejects_empty_body() { + let span = Span::new(0, 1); + let instructions = vec![ + Instruction::new(span, InstructionKind::Push(Value::Bool(true))), + Instruction::new(span, InstructionKind::Verify), + ]; + assert_eq!( + compile_spend_script(&instructions).unwrap(), + vec![OP_1, OP_VERIFY, OP_1] + ); + assert!(matches!( + compile_spend_script(&[]), + Err(CodegenError::EmptyBytecode) + )); + } + #[test] fn emits_kaspa_canonical_pushes() { let span = Span::new(0, 1); diff --git a/docs/TOCCATA_CRATE_COMPATIBILITY.md b/docs/TOCCATA_CRATE_COMPATIBILITY.md index 24981fc..e1d567f 100644 --- a/docs/TOCCATA_CRATE_COMPATIBILITY.md +++ b/docs/TOCCATA_CRATE_COMPATIBILITY.md @@ -1,5 +1,22 @@ # Toccata Crate Compatibility Spike +## October 2026 Native Integration + +The isolated `compatibility/toccata-v2` companion crate now pins Rusty Kaspa +`v2.1.0` commit `01b532e8b553523216471682649693af92f0fd16`. It builds actual +native v1 transactions with typed compute budgets, storage mass, and covenant +bindings; it checks explicit fees, duplicate inputs, overflow, and TN10 intent. +Native script validation and RPC round trips use upstream types directly. + +The optional `silverscript` feature pins released Silverscript v1.0.0 at +`3ed973335b59269293564805cc2c58a14595ec03` and tests emitted bytecode across +the compiler/node revision boundary. See +[`compatibility/toccata-v2/README.md`](../compatibility/toccata-v2/README.md). + +This lane is independent of the legacy SDK feature below. Offline native-engine +success is not live TN10 acceptance or production readiness. No gate is removed +by updating a source pin. The remaining content records the June spike. + Prepared: 2026-06-05. Updated: 2026-06-17. This spike checks whether the Kaspa crates used by the SDK can move from the diff --git a/docs/TRANSACTION_BUILDER.md b/docs/TRANSACTION_BUILDER.md index 6079f3f..06ca541 100644 --- a/docs/TRANSACTION_BUILDER.md +++ b/docs/TRANSACTION_BUILDER.md @@ -1,5 +1,10 @@ # KaspaScript Transaction Builder +The isolated native Toccata companion in `compatibility/toccata-v2` targets +Rusty Kaspa v2.1.0. See its README for typed TN10 construction, native engine +validation, RPC round trips, and compiler interoperability checks. The legacy +feature described below still uses the historical 0.15.0 SDK dependency lane. + KaspaScript’s testnet transaction builder is feature-gated behind: ```bash @@ -25,6 +30,12 @@ For TN12, the builder records a warning and uses the closest source-available te ## Contract Instantiation +Per-spend IR is a fragment. `compile_spend_script` closes a non-empty body +with a successful stack result after all `VERIFY` checks; it rejects an empty +body. Artifact bytecode alone does not instantiate parameters or select a +spend. Positive and underpayment controls run instantiated KaspaScript and +Silverscript scripts in the v2.1.0 native engine. + Compiled artifacts now include contract ABI and per-spend IR. The builder: 1. Selects a contract and spend path. diff --git a/sdk/src/testnet.rs b/sdk/src/testnet.rs index b56a32d..240d4d8 100644 --- a/sdk/src/testnet.rs +++ b/sdk/src/testnet.rs @@ -39,7 +39,7 @@ use kaspa_txscript::{ use kaspa_wallet_core::tx::mass::{MassCalculator, MAXIMUM_STANDARD_TRANSACTION_MASS}; use kaspa_wallet_core::utxo::NetworkParams; use kaspa_wrpc_client::{KaspaRpcClient, WrpcEncoding}; -use kaspascript_codegen::backends::toccata::compile_instruction_sequence; +use kaspascript_codegen::backends::toccata::compile_spend_script; use kaspascript_codegen::{ bytecode_hex, compile_file, verify_artifact, ArtifactContract, ArtifactParam, ArtifactSpend, CompiledArtifact, @@ -1215,7 +1215,7 @@ pub fn instantiate_contract( } } - let redeem_script = compile_instruction_sequence(&transformed) + let redeem_script = compile_spend_script(&transformed) .map_err(|error| TestnetError::Compile(error.to_string()))?; let script_public_key = pay_to_script_hash_script(&redeem_script); let locking_address = extract_script_pub_key_address(&script_public_key, Prefix::Testnet) diff --git a/tests/golden/cli/toccata.status.json b/tests/golden/cli/toccata.status.json index e4bfdaf..f93da12 100644 --- a/tests/golden/cli/toccata.status.json +++ b/tests/golden/cli/toccata.status.json @@ -205,6 +205,8 @@ "role": "baseline release that announced the mainnet activation DAA score", "tag": "v2.0.0" }, + "checked_at": "2026-10-19T23:21:28Z", + "evidence_scope": "dated public-source snapshot; recheck before deployment", "fee_policy": { "consensus": "standard fee policy is not consensus; zero-fee transactions remain consensus-valid", "formula": "100 sompi * max(compute grams, 2 * transaction bytes)", @@ -218,13 +220,13 @@ "pre_activation_rpc": "direct RPC transaction submission applies the higher minimum standard fee" }, "integrator_actions": [ - "Upgrade nodes to rusty-kaspa v2.0.1 before the scheduled activation window.", + "Review rusty-kaspa v2.1.0 security and compatibility changes before upgrading.", "Run full wallet, explorer, miner, pool, and indexer rehearsal on Testnet-10.", "Add compatibility coverage for seq-commit lane-proof RPCs and covenant binding refinements.", "Update gRPC/protobuf integrations for transaction version 1 covenant and compute_commit fields.", "Use node fee estimation when available; otherwise apply the Toccata minimum standard fee formula.", "Prefer storage_mass/storageMass in new JSON and protobuf integrations; treat mass as deprecated compatibility only.", - "Keep KaspaScript future-mainnet packages blocked until activation evidence is independently verified." + "Keep KaspaScript future-mainnet packages blocked until contract lowering, wallet/indexer support, and fee behavior are independently verified." ], "kips": [ { @@ -260,15 +262,18 @@ "daa_score": 474165565, "estimated_utc": "2026-06-30T16:15:00Z", "kaspa_script_readiness": "blocked-for-production-mainnet", - "status": "scheduled-not-independently-verified" + "observed_daa_score": 570318708, + "observed_network": "kaspa-mainnet", + "source": "https://api.kaspa.org/info/blockdag", + "status": "protocol-active-in-dated-snapshot" }, "maintenance_changes": [ - "seq-commit state and lane-proof RPC support", - "wallet/core and Wasm SMT sync progress notifications", - "SMT database inspection tooling", - "transaction-generation tooling for user-lane workflows", - "covenant binding handling refinements across client and wallet components", - "Wasm client transaction v0 deserialization fix" + "P2P protocol 11 and chunked IBD with protocol 10 compatibility", + "P2P wire limits and Stratum bridge security hardening", + "standalone kaspa-txscript-zk-sdk crate", + "arithmetic safety audit and post-Toccata consensus cleanup", + "RPC covenant preservation and checked integer conversions", + "Wasm sighash mapping and BIP-32 key equality fixes" ], "name": "Toccata", "node_requirements": { @@ -289,37 +294,44 @@ "node_upgrade_guide": { "database_upgrade": "one-way; downgrade requires resync", "recommended_rehearsal_network": "testnet-10", - "url": "https://github.com/kaspanet/rusty-kaspa/blob/v2.0.1/docs/toccata-guide.md" + "url": "https://github.com/kaspanet/rusty-kaspa/blob/v2.1.0/docs/toccata-guide.md" }, "p2p_protocol": { - "required_version": 10, - "restriction_window": "24h-before-activation" + "compatibility": "protocol 11 negotiates protocol 10 with older peers", + "current_version": 11, + "required_version": 10 }, "release_assets": [ { - "name": "kaspa-wasm32-sdk-v2.0.1.zip", - "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.0.1/kaspa-wasm32-sdk-v2.0.1.zip" + "name": "kaspa-wasm32-sdk-v2.1.0.zip", + "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.1.0/kaspa-wasm32-sdk-v2.1.0.zip" }, { - "name": "rusty-kaspa-v2.0.1-linux-amd64.zip", - "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.0.1/rusty-kaspa-v2.0.1-linux-amd64.zip" + "name": "rusty-kaspa-v2.1.0-linux-amd64.zip", + "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.1.0/rusty-kaspa-v2.1.0-linux-amd64.zip" }, { - "name": "rusty-kaspa-v2.0.1-osx.zip", - "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.0.1/rusty-kaspa-v2.0.1-osx.zip" + "name": "rusty-kaspa-v2.1.0-osx.zip", + "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.1.0/rusty-kaspa-v2.1.0-osx.zip" }, { - "name": "rusty-kaspa-v2.0.1-win64.zip", - "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.0.1/rusty-kaspa-v2.0.1-win64.zip" + "name": "rusty-kaspa-v2.1.0-win64.zip", + "url": "https://github.com/kaspanet/rusty-kaspa/releases/download/v2.1.0/rusty-kaspa-v2.1.0-win64.zip" } ], "rusty_kaspa_release": { - "commit": "cfafeb4c093fa37a303f1b9f19c58f986b870ce3", - "name": "Mainnet Toccata Release - v2.0.1", - "published_at": "2026-06-15T19:14:22Z", + "commit": "01b532e8b553523216471682649693af92f0fd16", + "name": "Rusty Kaspa v2.1.0", + "published_at": "2026-09-22T13:55:36Z", "repo": "https://github.com/kaspanet/rusty-kaspa", - "tag": "v2.0.1", - "upgrade_note": "drop-in update for v2.0.0 nodes and Toccata upgrade version for pre-Toccata 1.x nodes" + "tag": "v2.1.0", + "upgrade_note": "post-Toccata security, protocol 11, and standalone ZK SDK release; SDK/application compatibility remains separately tested" + }, + "silverscript_release": { + "commit": "3ed973335b59269293564805cc2c58a14595ec03", + "kaspa_script_interoperability": "isolated native engine tests; not shared language or artifact compatibility", + "tag": "v1.0.0", + "url": "https://github.com/kaspanet/silverscript/releases/tag/v1.0.0" }, "transaction_format": { "mass_field": { From 8dcc33756636fbe932f91ab13981dd9bed6b344e Mon Sep 17 00:00:00 2001 From: grysz <117801274+grysz@users.noreply.github.com> Date: Mon, 19 Oct 2026 19:38:28 -0400 Subject: [PATCH 2/3] Document native compatibility results and remaining live test boundary --- docs/UPGRADE_REPORT_2026-10-19.md | 54 +++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 docs/UPGRADE_REPORT_2026-10-19.md diff --git a/docs/UPGRADE_REPORT_2026-10-19.md b/docs/UPGRADE_REPORT_2026-10-19.md new file mode 100644 index 0000000..f56603d --- /dev/null +++ b/docs/UPGRADE_REPORT_2026-10-19.md @@ -0,0 +1,54 @@ +# October 2026 Compatibility Checkpoint + +Implementation commit: `742e545`. +Review: https://github.com/gryszzz/Kaspa-Script/pull/2. + +## Delivered + +- Isolated native transaction companion targeting Rusty Kaspa v2.1.0 commit + `01b532e8b553523216471682649693af92f0fd16`. +- Explicit TN10 intent, integer-sompi inputs/outputs/fee, compute budgets, + storage mass, genesis/continuation bindings, and native RPC round trips. +- A spend-instantiation fix: non-empty verified bodies end in a successful + stack result; empty bodies are rejected. Existing artifact fragments retain + their meaning and target gates. +- Native positive/underpayment checks for KaspaScript and released Silverscript + v1.0.0 commit `3ed973335b59269293564805cc2c58a14595ec03`. +- A signed offline genesis/continuation/exit fixture with invalid-payment and + replay controls plus deterministic fixture rollback/reapply. +- CLI status updated to the dated October node/compiler and activation baseline, + with production-mainnet readiness still blocked. +- CI for the pinned native integration, triggered by compiler/SDK changes. + +## Verification + +```bash +cargo fmt --all -- --check +cargo test --workspace --features testnet-integration --locked +cargo clippy --workspace --all-targets --features testnet-integration --locked -- -D warnings +cargo fmt --manifest-path compatibility/toccata-v2/Cargo.toml -- --check +cargo test --manifest-path compatibility/toccata-v2/Cargo.toml --locked --features silverscript +cargo clippy --manifest-path compatibility/toccata-v2/Cargo.toml --locked --all-targets --features silverscript -- -D warnings +git diff --check +``` + +Workspace: 83 passed; two live tests ignored. Native companion: seven passed. +Both Clippy passes succeeded locally on arm64 macOS. GitHub CI provides a +separate Linux check; its status is visible on the PR. + +## Remaining Boundaries + +No live funded TN10 lifecycle was executed. The native library does not connect, +sign, or broadcast. A live run still needs a scoped funded testnet wallet, +verified node identity, wallet/node mass and fee calculation, submission and +acceptance evidence, and DAG/indexer reconciliation. No private key was read +from user configuration or sent anywhere during this pass. + +The local fixture ledger is not a DAG indexer. Native engine validation is not +mempool/fee-policy or consensus acceptance. The legacy SDK's 0.15.0 lane remains +historical. Neither protocol activation nor these tests unlock production +contract lowering or establish wallet/indexer readiness. + +The agent skill update is reviewed separately at +https://github.com/gryszzz/Kaspa-Ai-Agent-Skill/pull/23. Both installed skill +locations were backed up and synchronized with the tested context bundle. From 2257004734b9689d7693cf2b65b2dc20ecfb9b36 Mon Sep 17 00:00:00 2001 From: grysz <117801274+grysz@users.noreply.github.com> Date: Mon, 19 Oct 2026 21:23:05 -0400 Subject: [PATCH 3/3] Add native buyer-seller escrow with bounded fees and timeout recovery --- .github/workflows/toccata-compatibility.yml | 8 +- README.md | 6 + compatibility/toccata-v2/Cargo.lock | 1110 ++++++++++++++++- compatibility/toccata-v2/Cargo.toml | 16 +- compatibility/toccata-v2/README.md | 16 +- compatibility/toccata-v2/examples/escrow.rs | 87 ++ .../fixtures/escrow-terms.offline.json | 6 + compatibility/toccata-v2/src/escrow.rs | 491 ++++++++ compatibility/toccata-v2/src/lib.rs | 5 +- compatibility/toccata-v2/tests/escrow.rs | 480 +++++++ compiler/codegen/src/backends/toccata.rs | 30 +- contracts/buyer_seller_escrow.ks | 27 + docs/BUYER_SELLER_ESCROW.md | 147 +++ docs/TRANSACTION_BUILDER.md | 5 + sdk/src/testnet.rs | 27 + 15 files changed, 2438 insertions(+), 23 deletions(-) create mode 100644 compatibility/toccata-v2/examples/escrow.rs create mode 100644 compatibility/toccata-v2/fixtures/escrow-terms.offline.json create mode 100644 compatibility/toccata-v2/src/escrow.rs create mode 100644 compatibility/toccata-v2/tests/escrow.rs create mode 100644 contracts/buyer_seller_escrow.ks create mode 100644 docs/BUYER_SELLER_ESCROW.md diff --git a/.github/workflows/toccata-compatibility.yml b/.github/workflows/toccata-compatibility.yml index 1e0bd23..64fb0cb 100644 --- a/.github/workflows/toccata-compatibility.yml +++ b/.github/workflows/toccata-compatibility.yml @@ -2,10 +2,10 @@ name: Native Toccata compatibility on: pull_request: - paths: ["compatibility/toccata-v2/**", "compiler/**", "sdk/**", ".github/workflows/toccata-compatibility.yml"] + paths: ["compatibility/toccata-v2/**", "contracts/**", "compiler/**", "sdk/**", ".github/workflows/toccata-compatibility.yml"] push: branches: [main] - paths: ["compatibility/toccata-v2/**", "compiler/**", "sdk/**", ".github/workflows/toccata-compatibility.yml"] + paths: ["compatibility/toccata-v2/**", "contracts/**", "compiler/**", "sdk/**", ".github/workflows/toccata-compatibility.yml"] workflow_dispatch: permissions: @@ -20,5 +20,5 @@ jobs: with: components: rustfmt, clippy - run: cargo fmt --manifest-path compatibility/toccata-v2/Cargo.toml -- --check - - run: cargo test --manifest-path compatibility/toccata-v2/Cargo.toml --locked --features silverscript - - run: cargo clippy --manifest-path compatibility/toccata-v2/Cargo.toml --locked --all-targets --features silverscript -- -D warnings + - run: cargo test --manifest-path compatibility/toccata-v2/Cargo.toml --locked --all-features + - run: cargo clippy --manifest-path compatibility/toccata-v2/Cargo.toml --locked --all-targets --all-features -- -D warnings diff --git a/README.md b/README.md index 81bf19e..d5c1582 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,12 @@ Wallet · SDK · Indexer · Node · Application ## Quick Start +For the experimental two-party script with no arbiter, see +[Buyer/Seller Escrow](docs/BUYER_SELLER_ESCROW.md). Its native TN10 builder +commits cooperative release and timeout refund into one P2SH lock. Wallet +integration and live funded acceptance remain unverified; do not fund the +public fixture keys. + ### Prerequisites - Rust 1.80 or newer diff --git a/compatibility/toccata-v2/Cargo.lock b/compatibility/toccata-v2/Cargo.lock index 7faefc5..0a9d56a 100644 --- a/compatibility/toccata-v2/Cargo.lock +++ b/compatibility/toccata-v2/Cargo.lock @@ -704,6 +704,12 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64" version = "0.23.1" @@ -1163,6 +1169,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "data-encoding" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" + [[package]] name = "defmt" version = "0.3.101" @@ -1309,6 +1321,17 @@ dependencies = [ "objc2", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "downcast" version = "0.11.0" @@ -1369,6 +1392,15 @@ 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-ordinalize" version = "4.4.2" @@ -1520,6 +1552,15 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + [[package]] name = "futures" version = "0.3.34" @@ -1680,6 +1721,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "h2" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.14.2", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hash32" version = "0.3.1" @@ -1778,12 +1838,108 @@ dependencies = [ "termcolor", ] +[[package]] +name = "http" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + [[package]] name = "humantime" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15" +[[package]] +name = "hyper" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots 1.0.7", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "libc", + "pin-project-lite", + "socket2 0.6.3", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.65" @@ -1808,6 +1964,109 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "include_bytes_aligned" version = "0.1.4" @@ -2610,6 +2869,43 @@ dependencies = [ "workflow-wasm", ] +[[package]] +name = "kaspa-wrpc-client" +version = "2.1.0" +source = "git+https://github.com/kaspanet/rusty-kaspa?rev=01b532e8b553523216471682649693af92f0fd16#01b532e8b553523216471682649693af92f0fd16" +dependencies = [ + "async-lock", + "async-trait", + "borsh", + "cfg-if", + "futures", + "js-sys", + "kaspa-addresses 2.1.0", + "kaspa-consensus-core 2.1.0", + "kaspa-consensus-wasm", + "kaspa-notify", + "kaspa-rpc-core", + "kaspa-rpc-macros", + "paste", + "rand 0.8.8", + "regex", + "rustls", + "serde", + "serde-wasm-bindgen", + "serde_json", + "thiserror 2.0.21", + "toml", + "wasm-bindgen", + "wasm-bindgen-futures", + "workflow-core", + "workflow-dom", + "workflow-http", + "workflow-log", + "workflow-rpc", + "workflow-serializer", + "workflow-wasm", +] + [[package]] name = "kaspascript-codegen" version = "0.1.0" @@ -2673,14 +2969,21 @@ dependencies = [ name = "kaspascript-toccata-native" version = "0.1.0" dependencies = [ + "hex", + "kaspa-addresses 2.1.0", "kaspa-consensus-core 2.1.0", "kaspa-rpc-core", "kaspa-txscript 2.1.0", + "kaspa-wrpc-client", "kaspascript-codegen", + "kaspascript-ir", "secp256k1", + "serde", "serde_json", "silverscript-lang", "thiserror 1.0.69", + "tokio", + "url", ] [[package]] @@ -2737,6 +3040,12 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + [[package]] name = "lock_api" version = "0.4.14" @@ -2858,6 +3167,15 @@ dependencies = [ "libc", ] +[[package]] +name = "manual_future" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c72f11f1d8e0c453cbd8042dfb83c2b50384f78a5a5d41019627c5f2062ece" +dependencies = [ + "futures-util", +] + [[package]] name = "memchr" version = "2.8.3" @@ -2891,6 +3209,12 @@ dependencies = [ "paste", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.9.1" @@ -2901,6 +3225,17 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "mio" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + [[package]] name = "mock_instant" version = "0.6.1" @@ -3115,6 +3450,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] name = "pest" version = "2.9.4" @@ -3223,6 +3564,15 @@ dependencies = [ "serde", ] +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.1" @@ -3244,7 +3594,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit", + "toml_edit 0.25.17+spec-1.1.0", ] [[package]] @@ -3303,6 +3653,58 @@ dependencies = [ "cc", ] +[[package]] +name = "quinn" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2 0.5.10", + "thiserror 2.0.21", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +dependencies = [ + "bytes", + "getrandom 0.2.17", + "rand 0.8.8", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.21", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.3", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "quote" version = "1.0.47" @@ -3499,14 +3901,74 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] -name = "risc0-binfmt" -version = "3.0.4" +name = "reqwest" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1883f0c5d19b865f395209a137dcb29e56dc49951424967b8d0114c129f46e77" +checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" dependencies = [ - "anyhow", - "borsh", - "bytemuck", + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pemfile", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-rustls", + "tower", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.26.11", + "windows-registry", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "risc0-binfmt" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1883f0c5d19b865f395209a137dcb29e56dc49951424967b8d0114c129f46e77" +dependencies = [ + "anyhow", + "borsh", + "bytemuck", "derive_more 2.1.1", "elf", "lazy_static", @@ -3721,6 +4183,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + [[package]] name = "rustc_version" version = "0.4.1" @@ -3743,6 +4211,50 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.23.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.23" @@ -3898,13 +4410,34 @@ dependencies = [ "zmij", ] +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_with" version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df9adc193c780ef8f159aee8b61e2d5801aaa555e6eb0947fe45530ec506296f" dependencies = [ - "base64", + "base64 0.23.1", "bs58", "chrono", "hex", @@ -3931,6 +4464,17 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest", +] + [[package]] name = "sha2" version = "0.10.9" @@ -4024,6 +4568,26 @@ dependencies = [ "serde", ] +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "spin" version = "0.9.9" @@ -4104,6 +4668,47 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.13.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -4204,6 +4809,16 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.13.3" @@ -4217,8 +4832,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c168a474b95bfecfe908a65d4bdffc523144b649a74c09c286afb35d53e0bc" dependencies = [ "bytes", + "libc", + "mio", "pin-project-lite", + "socket2 0.6.3", "tokio-macros", + "windows-sys 0.61.2", ] [[package]] @@ -4232,6 +4851,66 @@ dependencies = [ "syn 3.0.9", ] +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6989540ced10490aaf14e6bad2e3d33728a2813310a0c71d1574304c49631cd" +dependencies = [ + "futures-util", + "log", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots 0.26.11", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[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" version = "1.1.2+spec-1.1.0" @@ -4241,6 +4920,20 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap 2.14.2", + "serde", + "serde_spanned", + "toml_datetime 0.6.11", + "toml_write", + "winnow 0.7.15", +] + [[package]] name = "toml_edit" version = "0.25.17+spec-1.1.0" @@ -4248,9 +4941,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" dependencies = [ "indexmap 2.14.2", - "toml_datetime", + "toml_datetime 1.1.2+spec-1.1.0", "toml_parser", - "winnow", + "winnow 1.0.4", ] [[package]] @@ -4259,9 +4952,42 @@ version = "1.1.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" dependencies = [ - "winnow", + "winnow 1.0.4", ] +[[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-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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.44" @@ -4335,6 +5061,32 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "593eddbc8a11f3e099e942c8c065fe376b9d1776741430888f2796682e08ab43" +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.8.8", + "rustls", + "rustls-pki-types", + "sha1", + "thiserror 1.0.69", + "utf-8", +] + [[package]] name = "typemap-ors" version = "1.0.0" @@ -4401,6 +5153,36 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -4453,6 +5235,15 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -4549,6 +5340,34 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.7", +] + +[[package]] +name = "webpki-roots" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "wide" version = "1.7.1" @@ -4599,8 +5418,8 @@ dependencies = [ "windows-implement", "windows-interface", "windows-link", - "windows-result", - "windows-strings", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] @@ -4631,6 +5450,26 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" version = "0.4.1" @@ -4640,6 +5479,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-strings" version = "0.5.1" @@ -4658,6 +5507,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -4797,6 +5655,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" version = "1.0.4" @@ -4862,6 +5729,40 @@ dependencies = [ "workflow-macro-tools", ] +[[package]] +name = "workflow-dom" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503bba85907753c960ddfd73b4e79bffadf521cc3c992ef2b2a29fd3af09a957" +dependencies = [ + "futures", + "js-sys", + "regex", + "thiserror 1.0.69", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "workflow-core", + "workflow-log", + "workflow-wasm", +] + +[[package]] +name = "workflow-http" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3c654c7395e448001c658309377a44a8c3d7c28c7acb30e9babbaeacb575bb0" +dependencies = [ + "cfg-if", + "reqwest", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "wasm-bindgen", + "workflow-core", +] + [[package]] name = "workflow-log" version = "0.18.0" @@ -4902,6 +5803,49 @@ dependencies = [ "web-sys", ] +[[package]] +name = "workflow-rpc" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec4235eb167f0bef3bcbdf0c578823a0105ab5303115e3b2afb4d526e2498b08" +dependencies = [ + "ahash", + "async-std", + "async-trait", + "borsh", + "downcast-rs", + "futures", + "futures-util", + "getrandom 0.2.17", + "manual_future", + "rand 0.8.8", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tungstenite", + "wasm-bindgen", + "workflow-core", + "workflow-log", + "workflow-rpc-macros", + "workflow-task", + "workflow-wasm", + "workflow-websocket", +] + +[[package]] +name = "workflow-rpc-macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f048ca6b1c551f468c3c0c829f958e83dd15b20138b5466bb617ffde500e8cf4" +dependencies = [ + "parse-variants", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "workflow-serializer" version = "0.18.0" @@ -4913,6 +5857,34 @@ dependencies = [ "serde", ] +[[package]] +name = "workflow-task" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1a90743bb4d3f68606cb4e9a78551a53399ebc35ddba981cbb56bf2b31940a" +dependencies = [ + "futures", + "thiserror 1.0.69", + "workflow-core", + "workflow-task-macros", +] + +[[package]] +name = "workflow-task-macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ecf6be36b52dc1e16d11b55f717d9ec2fec5804aff7f392af591933ba4af45e" +dependencies = [ + "convert_case 0.6.0", + "parse-variants", + "proc-macro-error", + "proc-macro2", + "quote", + "sha2", + "syn 1.0.109", + "workflow-macro-tools", +] + [[package]] name = "workflow-wasm" version = "0.18.0" @@ -4948,6 +5920,64 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "workflow-websocket" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "515483a047477c91b5142e1090cce0afc21a0139d9c0c06ea42f0d3dbf3a6fcd" +dependencies = [ + "ahash", + "async-channel 2.5.0", + "async-std", + "async-trait", + "cfg-if", + "downcast-rs", + "futures", + "futures-util", + "js-sys", + "thiserror 1.0.69", + "tokio", + "tokio-tungstenite", + "triggered", + "tungstenite", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "workflow-core", + "workflow-log", + "workflow-task", + "workflow-wasm", +] + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "yoke" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.8.63" @@ -4968,6 +5998,27 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + [[package]] name = "zeroize" version = "1.9.1" @@ -4988,6 +6039,39 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "zlib-rs" version = "0.6.8" diff --git a/compatibility/toccata-v2/Cargo.toml b/compatibility/toccata-v2/Cargo.toml index 99dad3c..e59d9d6 100644 --- a/compatibility/toccata-v2/Cargo.toml +++ b/compatibility/toccata-v2/Cargo.toml @@ -11,16 +11,26 @@ publish = false kaspa-consensus-core = { git = "https://github.com/kaspanet/rusty-kaspa", rev = "01b532e8b553523216471682649693af92f0fd16" } kaspa-rpc-core = { git = "https://github.com/kaspanet/rusty-kaspa", rev = "01b532e8b553523216471682649693af92f0fd16" } kaspa-txscript = { git = "https://github.com/kaspanet/rusty-kaspa", rev = "01b532e8b553523216471682649693af92f0fd16" } +kaspa-addresses = { git = "https://github.com/kaspanet/rusty-kaspa", rev = "01b532e8b553523216471682649693af92f0fd16" } +kaspa-wrpc-client = { git = "https://github.com/kaspanet/rusty-kaspa", rev = "01b532e8b553523216471682649693af92f0fd16", optional = true } +kaspascript-codegen = { path = "../../compiler/codegen" } +kaspascript-ir = { path = "../../compiler/ir" } +secp256k1 = { version = "0.29.1", features = ["global-context"] } +serde = { version = "1.0", features = ["derive"] } +hex = "0.4" +tokio = { version = "1", features = ["macros", "rt-multi-thread", "time"], optional = true } +url = { version = "2", optional = true } serde_json = "1.0" thiserror = "1.0" silverscript-lang = { git = "https://github.com/kaspanet/silverscript", rev = "3ed973335b59269293564805cc2c58a14595ec03", optional = true } [features] silverscript = ["dep:silverscript-lang"] +rpc-client = ["dep:kaspa-wrpc-client", "dep:tokio", "dep:url"] -[dev-dependencies] -secp256k1 = { version = "0.29.1", features = ["global-context"] } -kaspascript-codegen = { path = "../../compiler/codegen" } +[[example]] +name = "escrow" +required-features = ["rpc-client"] [profile.dev] debug = 0 diff --git a/compatibility/toccata-v2/README.md b/compatibility/toccata-v2/README.md index a4495ba..cb1960c 100644 --- a/compatibility/toccata-v2/README.md +++ b/compatibility/toccata-v2/README.md @@ -3,7 +3,8 @@ This isolated companion crate constructs real Rusty Kaspa v1 transactions using the exact v2.1.0 release commit. It preserves native compute budgets, storage mass, covenant bindings, authorizing input, genesis IDs, and RPC serialization. -It provides no key storage, signing, connection, or broadcast operation. +It provides no secret-key storage, signing, or broadcast operation. The optional +escrow example connects to a caller-selected node for read-only inspection. `Tn10Plan` requires explicit inputs, every recipient/change output, an exact integer-sompi fee, and network identity `kaspa-testnet-10`. The caller must @@ -39,3 +40,16 @@ The signed fixture covers genesis, continuation, native exit, modified-payment rejection, replay rejection in a local UTXO ledger, and deterministic fixture rollback/reapply. It uses a public deterministic fixture key. The library itself never handles signing keys. The ledger is a test harness, not a DAG indexer. + +## Buyer/Seller Escrow + +`escrow::BuyerSellerEscrow` compiles the repository's +`contracts/buyer_seller_escrow.ks` into one P2SH lock containing cooperative +buyer-and-seller release and buyer timeout refund. It has no arbiter or agent +key. Payout, exact input/output counts and fee cap are script constraints. + +The optional `rpc-client` feature enables a read-only `escrow` example for +public terms, node inspection and unsigned spend previews. It never reads +wallet secrets, signs, funds or submits. See +[the agreement, risks and commands](../../docs/BUYER_SELLER_ESCROW.md). +Native fixture success is not a live funded TN10 lifecycle or an audit. diff --git a/compatibility/toccata-v2/examples/escrow.rs b/compatibility/toccata-v2/examples/escrow.rs new file mode 100644 index 0000000..1c137d1 --- /dev/null +++ b/compatibility/toccata-v2/examples/escrow.rs @@ -0,0 +1,87 @@ +//! Read-only inspection and unsigned previews. No wallet secrets or submission. +use std::{env, error::Error, fs, str::FromStr, time::Duration}; + +use kaspa_consensus_core::Hash; +use kaspa_wrpc_client::{KaspaRpcClient, WrpcEncoding}; +use kaspascript_toccata_native::{TransactionOutpoint, escrow::*}; +use serde_json::json; + +#[tokio::main] +async fn main() { + if let Err(error) = run().await { + eprintln!("{error}"); + std::process::exit(1); + } +} + +async fn run() -> Result<(), Box> { + let args: Vec = env::args().skip(1).collect(); + if !matches!(args.len(), 1 | 2 | 6) { + return Err("usage: escrow TERMS.json [BORSH_WRPC_URL [TXID:INDEX release|refund FEE_SOMPI COMPUTE_BUDGET]]".into()); + } + let bytes = fs::read(&args[0]).map_err(|_| "cannot read public escrow terms file")?; + let terms: EscrowTerms = serde_json::from_slice(&bytes).map_err( + |_| "invalid public escrow terms; private keys and extra fields are not accepted", + )?; + let escrow = BuyerSellerEscrow::new(terms)?; + let mut report = json!({ + "status": "experimental TN10; wallet integration and live lifecycle unverified", + "terms": escrow.terms(), + "locking_address": escrow.address().to_string(), + "source_hash": escrow.source_hash(), + "redeem_script_hex": hex::encode(escrow.redeem_script()), + "broadcast": false, + "node_acceptance_verified": false, + "warning": "Never fund public fixture keys. Both participants must review the payout, deadline and fee cap." + }); + if args.len() > 1 { + let url = url::Url::parse(&args[1]).map_err(|_| "invalid wRPC URL")?; + if !matches!(url.scheme(), "ws" | "wss") + || url.host_str().is_none() + || !url.username().is_empty() + || url.password().is_some() + || url.query().is_some() + || url.fragment().is_some() + { + return Err("use a ws/wss node URL without credentials, query or fragment".into()); + } + let client = KaspaRpcClient::new(WrpcEncoding::Borsh, Some(url.as_str()), None, None, None) + .map_err(|_| "cannot initialize read-only wRPC client")?; + let result = tokio::time::timeout(Duration::from_secs(15), async { + client + .connect(None) + .await + .map_err(|_| "TN10 node connection failed")?; + let observed = observe(&client, &escrow).await?; + report["node"] = serde_json::to_value(&observed.server_info)?; + report["observed_utxos"] = serde_json::to_value(&observed.utxos)?; + report["node_fee_estimate"] = serde_json::to_value(&observed.fee_estimate)?; + if args.len() == 6 { + let (txid, index) = args[2].split_once(':').ok_or("expected TXID:INDEX")?; + let outpoint = TransactionOutpoint::new(Hash::from_str(txid)?, index.parse()?); + let path = match args[3].as_str() { + "release" => EscrowPath::Release, + "refund" => EscrowPath::Refund, + _ => return Err("path must be release or refund".into()), + }; + let (native, preview) = observed.unsigned_spend( + &escrow, + outpoint, + path, + args[4].parse()?, + args[5].parse()?, + )?; + report["signing_preview"] = serde_json::to_value(preview)?; + report["unsigned_rpc_transaction"] = + serde_json::to_value(native.rpc_transaction())?; + } + Ok::<(), Box>(()) + }) + .await; + let _ = tokio::time::timeout(Duration::from_secs(5), client.disconnect()).await; + result + .map_err(|_| "read-only node operation timed out; nothing was signed or submitted")??; + } + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} diff --git a/compatibility/toccata-v2/fixtures/escrow-terms.offline.json b/compatibility/toccata-v2/fixtures/escrow-terms.offline.json new file mode 100644 index 0000000..0e0bf29 --- /dev/null +++ b/compatibility/toccata-v2/fixtures/escrow-terms.offline.json @@ -0,0 +1,6 @@ +{ + "buyer_public_key": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + "seller_public_key": "c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5", + "refund_daa_score": 700000000, + "max_fee_sompi": 100000 +} diff --git a/compatibility/toccata-v2/src/escrow.rs b/compatibility/toccata-v2/src/escrow.rs new file mode 100644 index 0000000..7b4f457 --- /dev/null +++ b/compatibility/toccata-v2/src/escrow.rs @@ -0,0 +1,491 @@ +//! Two-party TN10 escrow compiled from the checked-in KaspaScript source. +//! Keys and signing remain with the participants. This module cannot submit. + +use kaspa_addresses::{Address, Prefix, Version}; +use kaspa_consensus_core::{ + config::params::Params, + constants::LOCK_TIME_THRESHOLD, + hashing::sighash_type::SIG_HASH_ALL, + mass::MassCalculator, + network::{NetworkId, NetworkType}, +}; +use kaspa_rpc_core::{ + GetServerInfoResponse, RpcFeeEstimate, RpcUtxosByAddressesEntry, api::rpc::RpcApi, +}; +use kaspa_txscript::{ + extract_script_pub_key_address, opcodes::codes::*, pay_to_address_script, + pay_to_script_hash_script, script_builder::ScriptBuilder, +}; +use kaspascript_codegen::{ + Target, backends::toccata::compile_spend_script, compile_file_for_target, +}; +use kaspascript_ir::{Instruction, InstructionKind, Value}; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +use crate::{ + InputPlan, NativeTransaction, PlanError, PopulatedTransaction, ScriptPublicKey, TN10_NETWORK, + Tn10Plan, TransactionOutpoint, TransactionOutput, UtxoEntry, +}; + +pub const ESCROW_SOURCE: &str = include_str!("../../../contracts/buyer_seller_escrow.ks"); + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct EscrowTerms { + /// Hex-encoded x-only Schnorr public keys, never private keys. + pub buyer_public_key: String, + pub seller_public_key: String, + /// Absolute DAA score, below the native timestamp threshold. + pub refund_daa_score: u64, + pub max_fee_sompi: u64, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum EscrowPath { + Release, + Refund, +} + +#[derive(Debug, Error)] +pub enum EscrowError { + #[error("buyer and seller must be different valid x-only Schnorr public keys")] + InvalidKeys, + #[error("refund deadline must be a nonzero DAA score below the timestamp threshold")] + InvalidDeadline, + #[error("fee must be nonzero, within the agreed cap, and below the locked amount")] + InvalidFee, + #[error("UTXO must match this escrow's P2SH script and have no covenant or coinbase flag")] + WrongUtxo, + #[error("script construction failed: {0}")] + Script(String), + #[error("exactly the required number of 65-byte SIGHASH_ALL signatures is required")] + InvalidSignatures, + #[error("only a synced, indexed TN10 node is accepted")] + WrongNode, + #[error("node RPC failed: {0}")] + Rpc(String), + #[error("selected escrow outpoint is missing or spent in this node snapshot")] + MissingUtxo, + #[error("refund deadline has not passed at the observed virtual DAA score")] + RefundNotDue, + #[error("native mass calculation failed")] + Mass, + #[error(transparent)] + Plan(#[from] PlanError), +} + +pub struct BuyerSellerEscrow { + terms: EscrowTerms, + buyer: [u8; 32], + seller: [u8; 32], + redeem_script: Vec, + script_public_key: ScriptPublicKey, + address: Address, + source_hash: String, +} + +#[derive(Debug, Serialize)] +pub struct SigningPreview { + pub network: &'static str, + pub transaction_version: u16, + pub path: EscrowPath, + pub input_outpoint: String, + pub input_sompi: u64, + pub recipient: String, + pub recipient_sompi: u64, + pub change_sompi: u64, + pub fee_sompi: u64, + pub max_fee_sompi: u64, + pub refund_daa_score: u64, + pub transaction_lock_time: u64, + pub input_sequence: u64, + pub compute_budget: u16, + pub required_signers: Vec, + pub source_hash: String, + pub redeem_script_hex: String, + pub storage_mass: u64, + /// Includes correctly sized placeholder witnesses, not actual signatures. + pub estimated_signed_mass: u64, + pub broadcast: bool, + pub fee_policy_verified: bool, + pub node_acceptance_verified: bool, +} + +impl BuyerSellerEscrow { + pub fn new(terms: EscrowTerms) -> Result { + let buyer = parse_key(&terms.buyer_public_key)?; + let seller = parse_key(&terms.seller_public_key)?; + if buyer == seller { + return Err(EscrowError::InvalidKeys); + } + if terms.refund_daa_score == 0 || terms.refund_daa_score >= LOCK_TIME_THRESHOLD { + return Err(EscrowError::InvalidDeadline); + } + if terms.max_fee_sompi == 0 || terms.max_fee_sompi > i64::MAX as u64 { + return Err(EscrowError::InvalidFee); + } + let artifact = compile_file_for_target( + ESCROW_SOURCE, + "contracts/buyer_seller_escrow.ks", + Target::Tn10Toccata, + ) + .map_err(|error| EscrowError::Script(error.to_string()))?; + let mut escrow = Self { + terms, + buyer, + seller, + redeem_script: vec![], + script_public_key: ScriptPublicKey::new(0, vec![].into()), + address: Address::new(Prefix::Testnet, Version::PubKey, &buyer), + source_hash: hex::encode(artifact.source_hash), + }; + // Both paths must share one address; instantiating a single spend would + // omit the other path and could remove the buyer's recovery option. + let contract = &artifact.contracts[0]; + let mut branches = Vec::new(); + for name in ["release", "refund"] { + let spend = contract + .spends + .iter() + .find(|spend| spend.name == name) + .ok_or_else(|| EscrowError::Script("escrow source is missing a spend".into()))?; + let instructions = escrow.bind(&spend.instructions)?; + branches.push( + compile_spend_script(&instructions) + .map_err(|error| EscrowError::Script(error.to_string()))?, + ); + } + escrow.redeem_script = ScriptBuilder::new() + .add_op(OpIf) + .and_then(|b| b.add_ops(&branches[0])) + .and_then(|b| b.add_op(OpElse)) + .and_then(|b| b.add_ops(&branches[1])) + .and_then(|b| b.add_op(OpEndIf)) + .map_err(|error| EscrowError::Script(error.to_string()))? + .drain(); + escrow.script_public_key = pay_to_script_hash_script(&escrow.redeem_script); + escrow.address = extract_script_pub_key_address(&escrow.script_public_key, Prefix::Testnet) + .map_err(|error| EscrowError::Script(error.to_string()))?; + Ok(escrow) + } + + pub fn terms(&self) -> &EscrowTerms { + &self.terms + } + + pub fn address(&self) -> &Address { + &self.address + } + + pub fn redeem_script(&self) -> &[u8] { + &self.redeem_script + } + + pub fn script_public_key(&self) -> &ScriptPublicKey { + &self.script_public_key + } + + pub fn source_hash(&self) -> &str { + &self.source_hash + } + + fn payout(&self, path: EscrowPath) -> Address { + let key = match path { + EscrowPath::Release => &self.seller, + EscrowPath::Refund => &self.buyer, + }; + Address::new(Prefix::Testnet, Version::PubKey, key) + } + + // This binder is deliberately scoped to the embedded escrow template, not + // a general-purpose ABI implementation for arbitrary spend arguments. + fn bind(&self, instructions: &[Instruction]) -> Result, EscrowError> { + let mut result = Vec::new(); + for (index, instruction) in instructions.iter().enumerate() { + let InstructionKind::Push(Value::Symbol(name)) = &instruction.kind else { + result.push(instruction.clone()); + continue; + }; + let value = match name.as_str() { + "buyer_sig" | "seller_sig" => continue, + "max_fee" => Value::Integer(self.terms.max_fee_sompi), + "refund_daa_score" => Value::Integer(self.terms.refund_daa_score), + "buyer" | "seller" => { + let key = if name == "buyer" { + self.buyer + } else { + self.seller + }; + let as_spk = index > 0 + && matches!( + instructions[index - 1].kind, + InstructionKind::OutputScript(_) + ); + let bytes = if as_spk { + let spk = pay_to_address_script(&Address::new( + Prefix::Testnet, + Version::PubKey, + &key, + )); + spk.version() + .to_be_bytes() + .into_iter() + .chain(spk.script().iter().copied()) + .collect() + } else { + key.to_vec() + }; + Value::Bytes(bytes) + } + _ => { + return Err(EscrowError::Script( + "unexpected escrow source parameter".into(), + )); + } + }; + result.push(Instruction::new( + instruction.span, + InstructionKind::Push(value), + )); + } + Ok(result) + } + + /// Pure construction from caller-supplied metadata. Network identity and + /// UTXO liveness are not proven here. Use observe() for a read-only snapshot. + pub fn unsigned_spend( + &self, + network: &str, + outpoint: TransactionOutpoint, + utxo: UtxoEntry, + path: EscrowPath, + fee_sompi: u64, + compute_budget: u16, + ) -> Result<(NativeTransaction, SigningPreview), EscrowError> { + if network != TN10_NETWORK { + return Err(PlanError::WrongNetwork.into()); + } + if utxo.script_public_key != self.script_public_key + || utxo.covenant_id.is_some() + || utxo.is_coinbase + || utxo.amount > i64::MAX as u64 + { + return Err(EscrowError::WrongUtxo); + } + if fee_sompi == 0 + || fee_sompi > self.terms.max_fee_sompi + || utxo.amount <= self.terms.max_fee_sompi + { + return Err(EscrowError::InvalidFee); + } + if compute_budget == 0 { + return Err(EscrowError::Mass); + } + let recipient = self.payout(path); + let recipient_sompi = utxo.amount - fee_sompi; + let input_sompi = utxo.amount; + let lock_time = if path == EscrowPath::Refund { + self.terms.refund_daa_score + } else { + 0 + }; + let mut native = Tn10Plan { + network: network.into(), + inputs: vec![InputPlan { + outpoint, + utxo, + compute_budget, + sequence: if path == EscrowPath::Refund { + 0 + } else { + u64::MAX + }, + witness: vec![], + }], + outputs: vec![TransactionOutput::new( + recipient_sompi, + pay_to_address_script(&recipient), + )], + genesis_groups: vec![], + lock_time, + storage_mass: 0, + expected_fee: fee_sompi, + } + .build()?; + let params = Params::from(NetworkId::with_suffix(NetworkType::Testnet, 10)); + let calculator = MassCalculator::new_with_consensus_params(¶ms); + let storage = calculator + .calc_contextual_masses(&PopulatedTransaction::new( + &native.transaction, + native.entries.clone(), + )) + .ok_or(EscrowError::Mass)? + .storage_mass; + native.transaction.set_storage_mass(storage); + native.transaction.finalize(); + let mut sized = native.transaction.clone(); + let mut placeholder = vec![0; 65]; + placeholder[64] = SIG_HASH_ALL.to_u8(); + sized.inputs[0].signature_script = + self.signature_script(path, &vec![placeholder; signer_count(path)])?; + let masses = calculator.calc_non_contextual_masses(&sized); + let estimated_signed_mass = masses + .normalized_max(¶ms.block_mass_limits.cofactors()) + .max((storage as f64 * params.block_mass_limits.cofactors().storage).ceil() as u64); + let mut required_signers = vec![hex::encode(self.buyer)]; + if path == EscrowPath::Release { + required_signers.push(hex::encode(self.seller)); + } + let preview = SigningPreview { + network: TN10_NETWORK, + transaction_version: native.transaction.version, + path, + input_outpoint: format!("{}:{}", outpoint.transaction_id, outpoint.index), + input_sompi, + recipient: recipient.to_string(), + recipient_sompi, + change_sompi: 0, + fee_sompi, + max_fee_sompi: self.terms.max_fee_sompi, + refund_daa_score: self.terms.refund_daa_score, + transaction_lock_time: lock_time, + input_sequence: native.transaction.inputs[0].sequence, + compute_budget, + required_signers, + source_hash: self.source_hash.clone(), + redeem_script_hex: hex::encode(&self.redeem_script), + storage_mass: storage, + estimated_signed_mass, + broadcast: false, + fee_policy_verified: false, + node_acceptance_verified: false, + }; + Ok((native, preview)) + } + + /// Encodes externally supplied public signatures; never generates them. + pub fn signature_script( + &self, + path: EscrowPath, + signatures: &[Vec], + ) -> Result, EscrowError> { + if signatures.len() != signer_count(path) + || signatures + .iter() + .any(|sig| sig.len() != 65 || sig[64] != SIG_HASH_ALL.to_u8()) + { + return Err(EscrowError::InvalidSignatures); + } + let mut builder = ScriptBuilder::new(); + for sig in signatures { + builder + .add_data(sig) + .map_err(|error| EscrowError::Script(error.to_string()))?; + } + builder + .add_i64(i64::from(path == EscrowPath::Release)) + .and_then(|b| b.add_data(&self.redeem_script)) + .map_err(|error| EscrowError::Script(error.to_string()))?; + Ok(builder.drain()) + } +} + +fn signer_count(path: EscrowPath) -> usize { + match path { + EscrowPath::Release => 2, + EscrowPath::Refund => 1, + } +} + +fn parse_key(value: &str) -> Result<[u8; 32], EscrowError> { + let bytes: [u8; 32] = hex::decode(value) + .map_err(|_| EscrowError::InvalidKeys)? + .try_into() + .map_err(|_| EscrowError::InvalidKeys)?; + secp256k1::XOnlyPublicKey::from_slice(&bytes).map_err(|_| EscrowError::InvalidKeys)?; + Ok(bytes) +} + +pub fn validate_node(info: &GetServerInfoResponse) -> Result<(), EscrowError> { + if info.network_id != NetworkId::with_suffix(NetworkType::Testnet, 10) + || !info.is_synced + || !info.has_utxo_index + { + return Err(EscrowError::WrongNode); + } + Ok(()) +} + +/// Point-in-time observations from the supplied node, not acceptance receipts. +pub struct EscrowObservation { + pub server_info: GetServerInfoResponse, + pub utxos: Vec, + pub fee_estimate: RpcFeeEstimate, +} + +/// Uses an existing native RPC client. No signing or submission API is called. +pub async fn observe( + rpc: &dyn RpcApi, + escrow: &BuyerSellerEscrow, +) -> Result { + let info = rpc + .get_server_info() + .await + .map_err(|e| EscrowError::Rpc(e.to_string()))?; + validate_node(&info)?; + let utxos = rpc + .get_utxos_by_addresses(vec![escrow.address.clone()]) + .await + .map_err(|e| EscrowError::Rpc(e.to_string()))?; + let fee_estimate = rpc + .get_fee_estimate() + .await + .map_err(|e| EscrowError::Rpc(e.to_string()))?; + // Recheck identity after reads as reconnects/provider changes are untrusted. + let after = rpc + .get_server_info() + .await + .map_err(|e| EscrowError::Rpc(e.to_string()))?; + validate_node(&after)?; + Ok(EscrowObservation { + server_info: after, + utxos, + fee_estimate, + }) +} + +impl EscrowObservation { + pub fn unsigned_spend( + &self, + escrow: &BuyerSellerEscrow, + outpoint: TransactionOutpoint, + path: EscrowPath, + fee_sompi: u64, + compute_budget: u16, + ) -> Result<(NativeTransaction, SigningPreview), EscrowError> { + validate_node(&self.server_info)?; + if path == EscrowPath::Refund + && self.server_info.virtual_daa_score <= escrow.terms.refund_daa_score + { + return Err(EscrowError::RefundNotDue); + } + let mut matches = self + .utxos + .iter() + .filter(|entry| TransactionOutpoint::from(entry.outpoint) == outpoint); + let entry = matches.next().ok_or(EscrowError::MissingUtxo)?; + if matches.next().is_some() { + return Err(EscrowError::WrongUtxo); + } + escrow.unsigned_spend( + TN10_NETWORK, + outpoint, + entry.utxo_entry.clone().into(), + path, + fee_sompi, + compute_budget, + ) + } +} diff --git a/compatibility/toccata-v2/src/lib.rs b/compatibility/toccata-v2/src/lib.rs index 93e4367..84ae024 100644 --- a/compatibility/toccata-v2/src/lib.rs +++ b/compatibility/toccata-v2/src/lib.rs @@ -1,5 +1,8 @@ //! Pinned native Toccata construction and offline script validation for TN10. -//! No keys, RPC connections, signing, or broadcasting are performed here. +//! No secret keys, signing, or broadcasting are performed here. The escrow +//! reader can query an existing RPC client without submission authority. + +pub mod escrow; use std::collections::HashSet; diff --git a/compatibility/toccata-v2/tests/escrow.rs b/compatibility/toccata-v2/tests/escrow.rs new file mode 100644 index 0000000..f57055b --- /dev/null +++ b/compatibility/toccata-v2/tests/escrow.rs @@ -0,0 +1,480 @@ +use kaspa_consensus_core::{ + Hash, + constants::LOCK_TIME_THRESHOLD, + hashing::{ + sighash::{SigHashReusedValuesUnsync, calc_schnorr_signature_hash}, + sighash_type::SIG_HASH_ALL, + }, + network::{NetworkId, NetworkType}, +}; +use kaspa_rpc_core::{ + GetServerInfoResponse, RpcFeeEstimate, RpcFeerateBucket, RpcUtxosByAddressesEntry, +}; +use kaspa_txscript::{opcodes::codes::OpTrue, pay_to_address_script}; +use kaspascript_toccata_native::{escrow::*, *}; +use secp256k1::{Keypair, Message, SECP256K1}; + +// Public deterministic keys for offline fixtures ONLY. Never fund these keys. +fn key(byte: u8) -> Keypair { + Keypair::from_seckey_slice(SECP256K1, &[byte; 32]).unwrap() +} + +fn terms() -> EscrowTerms { + EscrowTerms { + buyer_public_key: hex::encode(key(7).x_only_public_key().0.serialize()), + seller_public_key: hex::encode(key(8).x_only_public_key().0.serialize()), + refund_daa_score: 128, + max_fee_sompi: 128, + } +} + +fn escrow() -> BuyerSellerEscrow { + BuyerSellerEscrow::new(terms()).unwrap() +} + +fn locked(escrow: &BuyerSellerEscrow) -> UtxoEntry { + UtxoEntry::new( + 100_000_000, + escrow.script_public_key().clone(), + 1, + false, + None, + ) +} + +fn outpoint() -> TransactionOutpoint { + TransactionOutpoint::new(Hash::from_u64_word(123), 0) +} + +fn unsigned(escrow: &BuyerSellerEscrow, path: EscrowPath) -> NativeTransaction { + escrow + .unsigned_spend(TN10_NETWORK, outpoint(), locked(escrow), path, 100, 1000) + .unwrap() + .0 +} + +fn sign( + native: &mut NativeTransaction, + escrow: &BuyerSellerEscrow, + path: EscrowPath, + keys: &[Keypair], +) { + let hash = calc_schnorr_signature_hash( + &PopulatedTransaction::new(&native.transaction, native.entries.clone()), + 0, + SIG_HASH_ALL, + &SigHashReusedValuesUnsync::new(), + ); + let signatures: Vec> = keys + .iter() + .map(|key| { + let mut signature = key + .sign_schnorr(Message::from_digest(hash.as_bytes())) + .as_ref() + .to_vec(); + signature.push(SIG_HASH_ALL.to_u8()); + signature + }) + .collect(); + native.transaction.inputs[0].signature_script = + escrow.signature_script(path, &signatures).unwrap(); + native.transaction.finalize(); +} + +#[test] +fn both_paths_execute_from_the_same_p2sh_lock() { + let escrow = escrow(); + let mut release = unsigned(&escrow, EscrowPath::Release); + assert!( + release.validate_scripts().is_err(), + "unsigned is not authorized" + ); + sign( + &mut release, + &escrow, + EscrowPath::Release, + &[key(7), key(8)], + ); + release.validate_scripts().unwrap(); + let mut refund = unsigned(&escrow, EscrowPath::Refund); + sign(&mut refund, &escrow, EscrowPath::Refund, &[key(7)]); + refund.validate_scripts().unwrap(); + assert_eq!( + release.entries[0].script_public_key, + refund.entries[0].script_public_key + ); + assert_ne!( + release.transaction.outputs[0].script_public_key, + refund.transaction.outputs[0].script_public_key + ); + assert!(escrow.address().to_string().starts_with("kaspatest:")); +} + +#[test] +fn numeric_fee_cap_boundaries_execute_in_the_native_engine() { + for cap in [127, 128, 255, 256, 32768, 8388608] { + let mut t = terms(); + t.max_fee_sompi = cap; + let escrow = BuyerSellerEscrow::new(t).unwrap(); + let mut native = unsigned(&escrow, EscrowPath::Release); + sign(&mut native, &escrow, EscrowPath::Release, &[key(7), key(8)]); + native.validate_scripts().unwrap(); + } +} + +#[test] +fn requires_buyer_and_seller_without_an_arbiter_or_agent_key() { + let escrow = escrow(); + for keys in [ + [key(7), key(7)], + [key(8), key(8)], + [key(7), key(9)], + [key(9), key(8)], + ] { + let mut release = unsigned(&escrow, EscrowPath::Release); + sign(&mut release, &escrow, EscrowPath::Release, &keys); + assert!(release.validate_scripts().is_err()); + } + for wrong_key in [key(8), key(9)] { + let mut refund = unsigned(&escrow, EscrowPath::Refund); + sign(&mut refund, &escrow, EscrowPath::Refund, &[wrong_key]); + assert!(refund.validate_scripts().is_err()); + } + assert!(escrow.signature_script(EscrowPath::Release, &[]).is_err()); + let mut non_all = vec![0; 65]; + non_all[64] = 2; + assert!( + escrow + .signature_script(EscrowPath::Refund, &[non_all]) + .is_err() + ); +} + +#[test] +fn native_script_rejects_redirected_payout_even_with_both_signatures() { + let escrow = escrow(); + for path in [EscrowPath::Release, EscrowPath::Refund] { + let mut native = unsigned(&escrow, path); + native.transaction.outputs[0].script_public_key = + ScriptPublicKey::new(0, vec![OpTrue].into()); + let keys = if path == EscrowPath::Release { + vec![key(7), key(8)] + } else { + vec![key(7)] + }; + sign(&mut native, &escrow, path, &keys); + assert!(native.validate_scripts().is_err()); + } +} + +#[test] +fn native_script_enforces_fee_cap_and_exact_transaction_shape() { + let escrow = escrow(); + for path in [EscrowPath::Release, EscrowPath::Refund] { + let keys = if path == EscrowPath::Release { + vec![key(7), key(8)] + } else { + vec![key(7)] + }; + let mut excess_fee = unsigned(&escrow, path); + excess_fee.transaction.outputs[0].value = excess_fee.entries[0].amount - 129; + sign(&mut excess_fee, &escrow, path, &keys); + assert!(excess_fee.validate_scripts().is_err()); + let mut extra_output = unsigned(&escrow, path); + extra_output.transaction.outputs[0].value -= 1; + extra_output + .transaction + .outputs + .push(TransactionOutput::new( + 1, + pay_to_address_script(escrow.address()), + )); + sign(&mut extra_output, &escrow, path, &keys); + assert!(extra_output.validate_scripts().is_err()); + let mut extra_input = unsigned(&escrow, path); + extra_input + .transaction + .inputs + .push(TransactionInput::new_with_compute_budget( + TransactionOutpoint::new(Hash::from_u64_word(124), 0), + vec![], + u64::MAX, + 1000, + )); + extra_input.entries.push(UtxoEntry::new( + 1, + ScriptPublicKey::new(0, vec![OpTrue].into()), + 1, + false, + None, + )); + sign(&mut extra_input, &escrow, path, &keys); + assert!(extra_input.validate_scripts().is_err()); + } +} + +#[test] +fn refund_enforces_lock_time_and_nonfinal_sequence() { + let escrow = escrow(); + let mut early = unsigned(&escrow, EscrowPath::Refund); + early.transaction.lock_time = escrow.terms().refund_daa_score - 1; + sign(&mut early, &escrow, EscrowPath::Refund, &[key(7)]); + assert!(early.validate_scripts().is_err()); + let mut final_sequence = unsigned(&escrow, EscrowPath::Refund); + final_sequence.transaction.inputs[0].sequence = u64::MAX; + sign(&mut final_sequence, &escrow, EscrowPath::Refund, &[key(7)]); + assert!(final_sequence.validate_scripts().is_err()); + let mut modified_after_signing = unsigned(&escrow, EscrowPath::Release); + sign( + &mut modified_after_signing, + &escrow, + EscrowPath::Release, + &[key(7), key(8)], + ); + modified_after_signing.transaction.outputs[0].value -= 1; + modified_after_signing.transaction.finalize(); + assert!(modified_after_signing.validate_scripts().is_err()); +} + +#[test] +fn terms_reject_ambiguous_keys_deadlines_and_unbounded_fees() { + let mut t = terms(); + t.seller_public_key = t.buyer_public_key.clone(); + assert!(matches!( + BuyerSellerEscrow::new(t), + Err(EscrowError::InvalidKeys) + )); + let mut t = terms(); + t.buyer_public_key = "00".repeat(32); + assert!(matches!( + BuyerSellerEscrow::new(t), + Err(EscrowError::InvalidKeys) + )); + for deadline in [0, LOCK_TIME_THRESHOLD, u64::MAX] { + let mut t = terms(); + t.refund_daa_score = deadline; + assert!(matches!( + BuyerSellerEscrow::new(t), + Err(EscrowError::InvalidDeadline) + )); + } + for cap in [0, u64::MAX] { + let mut t = terms(); + t.max_fee_sompi = cap; + assert!(matches!( + BuyerSellerEscrow::new(t), + Err(EscrowError::InvalidFee) + )); + } + let mut json = serde_json::to_value(terms()).unwrap(); + json["arbiter"] = "not-supported".into(); + assert!(serde_json::from_value::(json).is_err()); +} + +#[test] +fn unsigned_plan_rejects_wrong_network_utxo_and_fee() { + let escrow = escrow(); + assert!( + escrow + .unsigned_spend( + "kaspa-mainnet", + outpoint(), + locked(&escrow), + EscrowPath::Release, + 100, + 1000 + ) + .is_err() + ); + for fee in [0, 129, u64::MAX] { + assert!( + escrow + .unsigned_spend( + TN10_NETWORK, + outpoint(), + locked(&escrow), + EscrowPath::Release, + fee, + 1000 + ) + .is_err() + ); + } + let mut wrong = locked(&escrow); + wrong.script_public_key = ScriptPublicKey::new(0, vec![OpTrue].into()); + assert!( + escrow + .unsigned_spend( + TN10_NETWORK, + outpoint(), + wrong, + EscrowPath::Release, + 100, + 1000 + ) + .is_err() + ); + let mut wrong = locked(&escrow); + wrong.covenant_id = Some(Hash::from_u64_word(1)); + assert!( + escrow + .unsigned_spend( + TN10_NETWORK, + outpoint(), + wrong, + EscrowPath::Release, + 100, + 1000 + ) + .is_err() + ); + assert!( + escrow + .unsigned_spend( + TN10_NETWORK, + outpoint(), + locked(&escrow), + EscrowPath::Release, + 100, + 0 + ) + .is_err() + ); +} + +#[test] +fn preview_accounts_for_every_sompi_and_never_claims_submission() { + let escrow = escrow(); + let (native, preview) = escrow + .unsigned_spend( + TN10_NETWORK, + outpoint(), + locked(&escrow), + EscrowPath::Release, + 100, + 1000, + ) + .unwrap(); + assert_eq!( + preview.input_sompi, + preview.recipient_sompi + preview.fee_sompi + ); + assert_eq!(preview.change_sompi, 0); + assert_eq!(native.transaction.outputs.len(), 1); + assert_eq!(preview.required_signers.len(), 2); + assert_eq!(preview.fee_sompi, native.fee); + assert!(!preview.broadcast); + assert!(!preview.fee_policy_verified); + assert!(!preview.node_acceptance_verified); + assert_eq!(preview.compute_budget, 1000); + assert_eq!(preview.transaction_version, 1); + assert_eq!(preview.input_sequence, u64::MAX); + assert!(preview.estimated_signed_mass > preview.storage_mass); + assert_eq!(preview.source_hash, escrow.source_hash()); + assert_eq!( + preview.redeem_script_hex, + hex::encode(escrow.redeem_script()) + ); + assert_eq!(native.transaction.inputs[0].signature_script.len(), 0); + assert_eq!(serde_json::to_value(preview).unwrap()["fee_sompi"], 100); +} + +fn node_info(daa: u64) -> GetServerInfoResponse { + GetServerInfoResponse { + rpc_api_version: 1, + rpc_api_revision: 0, + server_version: "offline-fixture-v2.1.0".into(), + network_id: NetworkId::with_suffix(NetworkType::Testnet, 10), + has_utxo_index: true, + is_synced: true, + virtual_daa_score: daa, + } +} + +fn observation(escrow: &BuyerSellerEscrow, daa: u64) -> EscrowObservation { + let bucket = RpcFeerateBucket { + feerate: 1.0, + estimated_seconds: 1.0, + }; + EscrowObservation { + server_info: node_info(daa), + utxos: vec![RpcUtxosByAddressesEntry { + address: Some(escrow.address().clone()), + outpoint: outpoint().into(), + utxo_entry: locked(escrow).into(), + }], + fee_estimate: RpcFeeEstimate { + priority_bucket: bucket, + normal_buckets: vec![bucket], + low_buckets: vec![bucket], + }, + } +} + +#[test] +fn node_gate_rejects_mainnet_wrong_suffix_unsynced_and_unindexed() { + let mut info = node_info(100); + info.network_id = NetworkId::new(NetworkType::Mainnet); + assert!(validate_node(&info).is_err()); + info.network_id = NetworkId::with_suffix(NetworkType::Testnet, 12); + assert!(validate_node(&info).is_err()); + info = node_info(100); + info.is_synced = false; + assert!(validate_node(&info).is_err()); + info = node_info(100); + info.has_utxo_index = false; + assert!(validate_node(&info).is_err()); +} + +#[test] +fn snapshot_requires_unspent_outpoint_and_deadline_strictly_passed() { + let escrow = escrow(); + for daa in [127, 128] { + assert!(matches!( + observation(&escrow, daa).unsigned_spend( + &escrow, + outpoint(), + EscrowPath::Refund, + 100, + 1000 + ), + Err(EscrowError::RefundNotDue) + )); + } + assert!( + observation(&escrow, 129) + .unsigned_spend(&escrow, outpoint(), EscrowPath::Refund, 100, 1000) + .is_ok() + ); + let mut observed = observation(&escrow, 129); + observed.utxos.clear(); + assert!(matches!( + observed.unsigned_spend(&escrow, outpoint(), EscrowPath::Release, 100, 1000), + Err(EscrowError::MissingUtxo) + )); + let mut observed = observation(&escrow, 129); + observed.utxos.push(observed.utxos[0].clone()); + assert!( + observed + .unsigned_spend(&escrow, outpoint(), EscrowPath::Release, 100, 1000) + .is_err() + ); +} + +#[test] +fn fee_and_deadline_parameters_change_the_committed_lock() { + let original = escrow(); + let mut changed = terms(); + changed.refund_daa_score += 1; + assert_ne!( + original.address(), + BuyerSellerEscrow::new(changed).unwrap().address() + ); + let mut changed = terms(); + changed.max_fee_sompi += 1; + assert_ne!( + original.address(), + BuyerSellerEscrow::new(changed).unwrap().address() + ); + assert_eq!(original.address(), escrow().address()); +} diff --git a/compiler/codegen/src/backends/toccata.rs b/compiler/codegen/src/backends/toccata.rs index a4f0323..81706b8 100644 --- a/compiler/codegen/src/backends/toccata.rs +++ b/compiler/codegen/src/backends/toccata.rs @@ -276,6 +276,12 @@ fn encode_indexed(opcode: u8, index: u32, out: &mut Vec) -> Result<(), Codeg } fn encode_u64(value: u64, span: Span, out: &mut Vec) -> Result<(), CodegenError> { + if value > i64::MAX as u64 { + return Err(CodegenError::ValueTooLarge { + span, + message: "positive script number exceeds the native signed 64-bit range".to_owned(), + }); + } if value == 0 { out.push(OP_FALSE); return Ok(()); @@ -290,7 +296,12 @@ fn encode_u64(value: u64, span: Span, out: &mut Vec) -> Result<(), CodegenEr .iter() .rposition(|byte| *byte != 0) .map_or(0, |index| index + 1); - encode_data(&bytes[..trimmed_size], span, out) + let mut encoded = bytes[..trimmed_size].to_vec(); + // Script integers reserve the high bit for the sign, unlike raw LE u64. + if encoded.last().is_some_and(|byte| byte & 0x80 != 0) { + encoded.push(0); + } + encode_data(&encoded, span, out) } fn encode_data(bytes: &[u8], span: Span, out: &mut Vec) -> Result<(), CodegenError> { @@ -320,6 +331,23 @@ mod tests { use super::*; use kaspascript_ir::{IrContract, IrSpend}; + #[test] + fn positive_script_numbers_preserve_the_sign_boundary() { + let span = Span::new(0, 1); + for (value, expected) in [ + (127, vec![1, 0x7f]), + (128, vec![2, 0x80, 0]), + (255, vec![2, 0xff, 0]), + (256, vec![2, 0, 1]), + (32768, vec![3, 0, 0x80, 0]), + ] { + let mut encoded = Vec::new(); + encode_u64(value, span, &mut encoded).unwrap(); + assert_eq!(encoded, expected); + } + assert!(encode_u64(u64::MAX, span, &mut Vec::new()).is_err()); + } + #[test] fn spend_instantiation_closes_verified_body_and_rejects_empty_body() { let span = Span::new(0, 1); diff --git a/contracts/buyer_seller_escrow.ks b/contracts/buyer_seller_escrow.ks new file mode 100644 index 0000000..650e0a0 --- /dev/null +++ b/contracts/buyer_seller_escrow.ks @@ -0,0 +1,27 @@ +contract BuyerSellerEscrow { + params { + buyer: PublicKey, + seller: PublicKey, + refund_daa_score: BlockHeight, + max_fee: Amount, + } + + spend release(buyer_sig: Signature, seller_sig: Signature) { + require multisig(2, [buyer, seller], [buyer_sig, seller_sig]); + require input_count == 1; + require output_count == 1; + require input(0).value > max_fee; + require output(0).value >= input(0).value - max_fee; + require output(0).script == seller; + } + + spend refund(buyer_sig: Signature) { + require buyer_sig.verify(buyer); + require block.height >= refund_daa_score; + require input_count == 1; + require output_count == 1; + require input(0).value > max_fee; + require output(0).value >= input(0).value - max_fee; + require output(0).script == buyer; + } +} diff --git a/docs/BUYER_SELLER_ESCROW.md b/docs/BUYER_SELLER_ESCROW.md new file mode 100644 index 0000000..3528564 --- /dev/null +++ b/docs/BUYER_SELLER_ESCROW.md @@ -0,0 +1,147 @@ +# Buyer/Seller Escrow + +Status: experimental native implementation; TN10 only; no funds moved. + +## Spending Agreement + +This example has two participants and no arbiter, administrator, agent key, +platform recipient, or service fee. The buyer and seller must be different +Schnorr public keys. Both participants review the complete script and terms +before funding its P2SH address. + +- Release: buyer AND seller authorize one payment to the seller. +- Timeout refund: buyer authorizes one payment back to the buyer once the + agreed absolute DAA-score deadline has passed. +- Either path has exactly one input and one output. Its explicit miner fee + comes from the locked amount and cannot exceed the agreed cap. +- Both paths are committed into the SAME redeem script before funding. +- The timeout is a DAA score, not a block height or a guaranteed wall-clock + time. Script checks alone do not establish node-level finalization. + +This agreement cannot determine whether goods were delivered. The buyer can +withhold cooperative release and later take the timeout refund. After the +deadline, a cooperative release and refund can conflict; node/DAG acceptance +determines the accepted spend. There is no automatic scheduler or dispute +resolution. Losing the buyer key can make recovery impossible. If fees exceed +the cap, this intentionally single-input example may remain unspendable until +fees fall. These are terms to review, not production security guarantees. + +## Source Boundary + +The governing readiness rule is the Kaspa skill's +`docs/kaspa/mainnet-readiness-gate.md`: protocol activation does not prove +application, wallet, or indexer readiness. This work retains the mainnet gate. + +Native behavior is pinned to Rusty Kaspa v2.1.0 commit +`01b532e8b553523216471682649693af92f0fd16`: + +- [Signature, multisig, lock-time and introspection opcodes](https://github.com/kaspanet/rusty-kaspa/blob/01b532e8b553523216471682649693af92f0fd16/crypto/txscript/src/opcodes/mod.rs) +- [Standard P2SH construction](https://github.com/kaspanet/rusty-kaspa/blob/01b532e8b553523216471682649693af92f0fd16/crypto/txscript/src/standard.rs) +- [Transaction mass calculation](https://github.com/kaspanet/rusty-kaspa/blob/01b532e8b553523216471682649693af92f0fd16/consensus/core/src/mass/mod.rs) +- [DAA/time finalization](https://github.com/kaspanet/rusty-kaspa/blob/01b532e8b553523216471682649693af92f0fd16/consensus/src/processes/transaction_validator/tx_validation_in_header_context.rs) + +## Build Checklist + +- [x] Add readable `.ks` source with explicit two-party payout constraints. +- [x] Compile both paths into a single native P2SH script. +- [x] Add unsigned spend previews, exact amounts, fee cap and native mass. +- [x] Add read-only RPC checks for TN10, sync, UTXOs and fee estimates. +- [x] Test unauthorized signatures, payout changes, early refund and fee abuse. +- [x] Run workspace and native tests, formatting, Clippy and diff checks. +- [ ] Complete wallet-provider signing and rejection handling. +- [ ] Execute an explicitly approved, funded TN10 lifecycle and capture receipts. +- [ ] Reconcile accepted state and conflicting spends through a DAG-aware indexer. + +Only the first six items can be completed without a wallet integration and a +scoped live test. Offline signatures use public fixture keys. They must never +be used for real funding. + +## Inspect Without A Wallet + +From the repository root, inspect the public OFFLINE fixture terms: + +```bash +cargo run --manifest-path compatibility/toccata-v2/Cargo.toml --locked \ + --features rpc-client --example escrow -- \ + compatibility/toccata-v2/fixtures/escrow-terms.offline.json +``` + +The fixture keys are public, known keys. Never fund the displayed fixture +address. Replace the public-key terms with independently verified participant +keys before a separately scoped test. The inspector does not generate keys. + +Add a Borsh wRPC URL to query your node, with no signing or submission: + +```bash +cargo run --manifest-path compatibility/toccata-v2/Cargo.toml --locked \ + --features rpc-client --example escrow -- \ + /path/to/public-terms.json ws://127.0.0.1:17210 +``` + +After observing a real funded test outpoint, the read-only tool can produce an +unsigned preview. Supply the outpoint, path, exact fee in sompi and explicit +compute budget: + +```text +... /path/to/public-terms.json WRPC_URL TXID:INDEX release FEE_SOMPI COMPUTE_BUDGET +... /path/to/public-terms.json WRPC_URL TXID:INDEX refund FEE_SOMPI COMPUTE_BUDGET +``` + +The tool verifies node network identity, sync and UTXO-index support, finds the +exact outpoint, calculates storage mass with pinned native TN10 parameters, +and displays the node's fee estimates separately. It does not claim that a +chosen fee meets node policy or that the transaction is accepted. Refund +previews require observed virtual DAA strictly greater than the deadline. +The RPC read sequence is not an atomic snapshot; a provider or wallet must +refresh UTXO/network/fee checks before signing and submission. Remote nodes +are a trust boundary, not independent acceptance evidence. + +The optional transport reuses the upstream `kaspa-wrpc-client`; it is +feature-gated to keep network dependencies out of the default offline lane. +There is no hand-written replacement for Kaspa's wire protocol. + +## Verification + +```bash +cargo test --workspace --features testnet-integration --locked +cargo clippy --workspace --all-targets --features testnet-integration --locked -- -D warnings +cargo test --manifest-path compatibility/toccata-v2/Cargo.toml --locked --all-features +cargo clippy --manifest-path compatibility/toccata-v2/Cargo.toml --locked --all-targets --all-features -- -D warnings +cargo fmt --all -- --check +cargo fmt --manifest-path compatibility/toccata-v2/Cargo.toml -- --check +git diff --check +``` + +Regression coverage also checks positive script-number sign boundaries. The +first native positive escrow run exposed incorrect signed-number encoding for +the fee cap `128`; the compiler now emits a zero sign byte when needed and +rejects positive values outside the native signed numeric range. + +The legacy 0.15.0 SDK now refuses multi-path instantiation instead of silently +locking only one path. Source inspection/compilation is still available, but +this escrow's two-path native builder must be used for its shared P2SH script. + +## Checkpoint: 2026-10-20 UTC + +- Workspace: 85 tests passed; two live tests remain ignored. +- Native all-features lane: 19 tests passed, including 12 escrow controls. +- Both format and Clippy passes and `git diff --check` passed. +- Read-only inspector compiled and displayed the public fixture terms/script. +- A deliberately unreachable loopback node timed out and exited with no + signing or submission, as expected. No live TN10 node result is claimed. +- Agent repository: 55 tests and 19 behavioral reference cases passed; + extracted skill package: 43 tests passed. Both installed skill copies were + backed up and synchronized with the tested package. + +Wallet-provider signing, visual approval UX, a funded live lifecycle and +DAG-aware recovery are still open. No real keys were read, funds moved, +release published, or mainnet readiness claimed. At this pre-integration +checkpoint, changes were local and the remote draft PRs were unchanged. + +## Integration Authorization + +The user subsequently authorized commits, pushes and merges. These changes +are being integrated through [PR #2](https://github.com/gryszzz/Kaspa-Script/pull/2) +after fresh local checks and GitHub CI. The PR's commit/check/merge history is +the integration receipt. This authorization does not include release +publication, private-key access, signing, funding or transaction submission. diff --git a/docs/TRANSACTION_BUILDER.md b/docs/TRANSACTION_BUILDER.md index 06ca541..abaa311 100644 --- a/docs/TRANSACTION_BUILDER.md +++ b/docs/TRANSACTION_BUILDER.md @@ -30,6 +30,11 @@ For TN12, the builder records a warning and uses the closest source-available te ## Contract Instantiation +The legacy single-spend SDK rejects contracts with multiple spend paths. It +cannot commit all of those paths to one P2SH lock and must not silently omit +recovery. The experimental buyer/seller escrow uses the separate native +two-path builder; see [Buyer/Seller Escrow](BUYER_SELLER_ESCROW.md). + Per-spend IR is a fragment. `compile_spend_script` closes a non-empty body with a successful stack result after all `VERIFY` checks; it rejects an empty body. Artifact bytecode alone does not instantiate parameters or select a diff --git a/sdk/src/testnet.rs b/sdk/src/testnet.rs index 240d4d8..a766a6e 100644 --- a/sdk/src/testnet.rs +++ b/sdk/src/testnet.rs @@ -1174,6 +1174,11 @@ pub fn instantiate_contract( target: TestnetTarget, ) -> Result { let contract = find_contract(artifact, contract_name)?; + if contract.spends.len() != 1 { + return Err(TestnetError::Unsupported( + "legacy single-spend instantiation cannot preserve multiple paths in one locking script; use a reviewed native dispatcher".to_owned(), + )); + } let spend = find_spend(contract, spend_name)?; validate_param_bindings(&contract.params, &contract_params)?; @@ -2156,6 +2161,28 @@ mod tests { .starts_with("kaspatest:")); } + #[test] + fn legacy_instantiation_cannot_silently_remove_escrow_refund_paths() { + for (name, source) in [ + ("Escrow", include_str!("../../tests/contracts/escrow.ks")), + ( + "BuyerSellerEscrow", + include_str!("../../contracts/buyer_seller_escrow.ks"), + ), + ] { + let plan = ContractDeploymentPlan::from_source(name, "escrow.ks", source) + .expect("source compiles"); + let result = instantiate_contract( + &plan.artifact, + name, + "release", + BTreeMap::new(), + TestnetTarget::Tn10, + ); + assert!(matches!(result, Err(TestnetError::Unsupported(_)))); + } + } + #[test] fn proof_json_never_contains_private_key_material() { let wallet = TestWallet::generate_ephemeral().expect("wallet");