diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ca416ce3..84bbe17e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -125,7 +125,7 @@ jobs: integration-test-eigenlayer: timeout-minutes: 90 - runs-on: macos-latest + runs-on: ubuntu-latest steps: - name: checkout code uses: actions/checkout@v2 @@ -133,20 +133,20 @@ jobs: - name: Install Foundry run: | curl -L https://foundry.paradigm.xyz | bash - source /Users/runner/.bashrc - foundryup + ${FOUNDRY_DIR:-"$HOME/.foundry"}/bin/foundryup + env: + FOUNDRY_DIR: ${{ runner.temp }}/foundry + shell: bash - name: Add Foundry to PATH - run: echo "${HOME}/.foundry/bin" >> $GITHUB_PATH + run: echo "${{ runner.temp }}/foundry/bin" >> $GITHUB_PATH + - name: Forge build run: forge update && cd blueprints/incredible-squaring-eigenlayer && forge build --root ./contracts && cd ../../ - - name: setup-docker - run: brew install docker - - - name: Verify Forge and Docker installation - run: forge --version && docker --version + - name: Set up Docker + uses: crazy-max/ghaction-setup-docker@v3 - name: Run anvil in background run: anvil --version && anvil & @@ -160,13 +160,10 @@ jobs: with: cache-on-failure: "true" - - name: install protobuf - run: brew install protobuf gmp - - - name: Set Relevant M1 env vars + - name: install protobuf and gmp run: | - export LIBRARY_PATH=$LIBRARY_PATH:/opt/homebrew/lib - export INCLUDE_PATH=$INCLUDE_PATH:/opt/homebrew/include + sudo apt-get update + sudo apt-get install -y protobuf-compiler libprotobuf-dev libgmp-dev - name: install cargo-nextest run: cargo install cargo-nextest --locked @@ -176,4 +173,3 @@ jobs: - name: tests run: RUST_LOG=gadget=trace cargo test --package blueprint-test-utils test_eigenlayer_incredible_squaring_blueprint -- --nocapture - diff --git a/.gitmodules b/.gitmodules index e085e360..daa95fb7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,17 +14,13 @@ path = blueprints/incredible-squaring-eigenlayer/contracts/lib/forge-std url = https://github.com/foundry-rs/forge-std -# For the ecdsa-threshold-mpc blueprint -[submodule "blueprints/ecdsa-threshold-mpc/contracts/lib/forge-std"] - path = blueprints/ecdsa-threshold-mpc/contracts/lib/forge-std - url = https://github.com/foundry-rs/forge-std -[submodule "blueprints/ecdsa-threshold-mpc/contracts/lib/tnt-core"] - path = blueprints/ecdsa-threshold-mpc/contracts/lib/tnt-core - url = https://github.com/tangle-network/tnt-core - branch = main +# For the incredible-squaring-symbiotic blueprint [submodule "blueprints/incredible-squaring-symbiotic/contracts/lib/forge-std"] path = blueprints/incredible-squaring-symbiotic/contracts/lib/forge-std url = https://github.com/foundry-rs/forge-std [submodule "blueprints/incredible-squaring-symbiotic/contracts/lib/core"] path = blueprints/incredible-squaring-symbiotic/contracts/lib/core url = https://github.com/symbioticfi/core +[submodule "blueprints/examples/contracts/lib/forge-std"] + path = blueprints/examples/contracts/lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/Cargo.lock b/Cargo.lock index d5ad28b7..1d46f9b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,11 +128,11 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy-chains" -version = "0.1.44" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c660915971620592abe2c292c859957eb60e73a60c0eba34a6793eea60512cff" +checksum = "18c5c520273946ecf715c0010b4e3503d7eba9893cd9ce6b7fff5654c4a3c470" dependencies = [ - "alloy-primitives 0.8.10", + "alloy-primitives 0.8.11", "num_enum", "strum", ] @@ -146,7 +146,7 @@ dependencies = [ "alloy-eips", "alloy-primitives 0.7.7", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.1.4", "c-kzg", "serde", ] @@ -195,13 +195,24 @@ checksum = "f76ecab54890cdea1e4808fc0891c7e6cfcf71fe1a9fe26810c7280ef768f4ed" dependencies = [ "alloy-primitives 0.7.7", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.1.4", "c-kzg", "once_cell", "serde", "sha2 0.10.8", ] +[[package]] +name = "alloy-genesis" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8429cf4554eed9b40feec7f4451113e76596086447550275e3def933faf47ce3" +dependencies = [ + "alloy-primitives 0.8.11", + "alloy-serde 0.4.2", + "serde", +] + [[package]] name = "alloy-json-abi" version = "0.7.7" @@ -233,8 +244,8 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fa8a1a3c4cbd221f2b8e3693aeb328fca79a757fe556ed08e47bbbc2a70db7" dependencies = [ - "alloy-primitives 0.8.10", - "alloy-sol-types 0.8.10", + "alloy-primitives 0.8.11", + "alloy-sol-types 0.8.11", "serde", "serde_json", "thiserror", @@ -252,7 +263,7 @@ dependencies = [ "alloy-json-rpc 0.1.4", "alloy-primitives 0.7.7", "alloy-rpc-types-eth", - "alloy-serde", + "alloy-serde 0.1.4", "alloy-signer", "alloy-sol-types 0.7.7", "async-trait", @@ -261,6 +272,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "alloy-node-bindings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f1334a738aa1710cb8227441b3fcc319202ce78e967ef37406940242df4a454" +dependencies = [ + "alloy-genesis", + "alloy-primitives 0.8.11", + "k256", + "rand", + "serde_json", + "tempfile", + "thiserror", + "tracing", + "url", +] + [[package]] name = "alloy-primitives" version = "0.7.7" @@ -285,9 +313,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8edae627382349b56cd6a7a2106f4fd69b243a9233e560c55c2e03cabb7e1d3c" +checksum = "fd58d377699e6cfeab52c4a9d28bdc4ef37e2bd235ff2db525071fe37a2e9af5" dependencies = [ "alloy-rlp", "bytes", @@ -295,7 +323,7 @@ dependencies = [ "const-hex", "derive_more 1.0.0", "foldhash", - "hashbrown 0.15.0", + "hashbrown 0.15.1", "hex-literal", "indexmap 2.6.0", "itoa", @@ -383,7 +411,7 @@ checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -418,7 +446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "370143ed581aace6e663342d21d209c6b2e34ee6142f7d6675adb518deeaf0dc" dependencies = [ "alloy-json-rpc 0.4.2", - "alloy-primitives 0.8.10", + "alloy-primitives 0.8.11", "alloy-transport 0.4.2", "alloy-transport-http 0.4.2", "futures", @@ -440,7 +468,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "184a7a42c7ba9141cc9e76368356168c282c3bc3d9e5d78f3556bdfe39343447" dependencies = [ "alloy-rpc-types-eth", - "alloy-serde", + "alloy-serde 0.1.4", ] [[package]] @@ -453,7 +481,7 @@ dependencies = [ "alloy-eips", "alloy-primitives 0.7.7", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.1.4", "alloy-sol-types 0.7.7", "itertools 0.13.0", "serde", @@ -472,6 +500,17 @@ dependencies = [ "serde_json", ] +[[package]] +name = "alloy-serde" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dff0ab1cdd43ca001e324dc27ee0e8606bd2161d6623c63e0e0b8c4dfc13600" +dependencies = [ + "alloy-primitives 0.8.11", + "serde", + "serde_json", +] + [[package]] name = "alloy-signer" version = "0.1.4" @@ -531,21 +570,21 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] name = "alloy-sol-macro" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841eabaa4710f719fddbc24c95d386eae313f07e6da4babc25830ee37945be0c" +checksum = "8a1b42ac8f45e2f49f4bcdd72cbfde0bb148f5481d403774ffa546e48b83efc1" dependencies = [ - "alloy-sol-macro-expander 0.8.10", - "alloy-sol-macro-input 0.8.10", + "alloy-sol-macro-expander 0.8.11", + "alloy-sol-macro-input 0.8.11", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -562,26 +601,26 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "syn-solidity 0.7.7", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-expander" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6672337f19d837b9f7073c45853aeb528ed9f7dd6a4154ce683e9e5cb7794014" +checksum = "06318f1778e57f36333e850aa71bd1bb5e560c10279e236622faae0470c50412" dependencies = [ - "alloy-sol-macro-input 0.8.10", + "alloy-sol-macro-input 0.8.11", "const-hex", "heck 0.5.0", "indexmap 2.6.0", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.85", - "syn-solidity 0.8.10", + "syn 2.0.87", + "syn-solidity 0.8.11", "tiny-keccak", ] @@ -598,23 +637,23 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.85", + "syn 2.0.87", "syn-solidity 0.7.7", ] [[package]] name = "alloy-sol-macro-input" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dff37dd20bfb118b777c96eda83b2067f4226d2644c5cfa00187b3bc01770ba" +checksum = "eaebb9b0ad61a41345a22c9279975c0cdd231b97947b10d7aad1cf0a7181e4a5" dependencies = [ "const-hex", "dunce", "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.85", - "syn-solidity 0.8.10", + "syn 2.0.87", + "syn-solidity 0.8.11", ] [[package]] @@ -642,12 +681,12 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa828bb1b9a6dc52208fbb18084fb9ce2c30facc2bfda6a5d922349b4990354f" +checksum = "374d7fb042d68ddfe79ccb23359de3007f6d4d53c13f703b64fb0db422132111" dependencies = [ - "alloy-primitives 0.8.10", - "alloy-sol-macro 0.8.10", + "alloy-primitives 0.8.11", + "alloy-sol-macro 0.8.11", "const-hex", ] @@ -766,9 +805,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -781,9 +820,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" @@ -815,9 +854,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" [[package]] name = "anymap2" @@ -1094,7 +1133,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "synstructure 0.13.1", ] @@ -1106,7 +1145,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1170,7 +1209,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix 0.38.38", + "rustix 0.38.39", "slab", "tracing", "windows-sys 0.59.0", @@ -1213,7 +1252,7 @@ dependencies = [ "cfg-if 1.0.0", "event-listener 5.3.1", "futures-lite", - "rustix 0.38.38", + "rustix 0.38.39", "tracing", ] @@ -1229,7 +1268,7 @@ dependencies = [ "cfg-if 1.0.0", "futures-core", "futures-io", - "rustix 0.38.38", + "rustix 0.38.39", "signal-hook-registry", "slab", "windows-sys 0.59.0", @@ -1254,7 +1293,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1271,7 +1310,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1359,7 +1398,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1434,9 +1473,9 @@ dependencies = [ [[package]] name = "aws-sdk-kms" -version = "1.48.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2afbd208dabc6785946d4ef2444eb1f54fe0aaf0f62f2a4f9a9e9c303aeff0be" +checksum = "1f4c89f1d2e0df99ccd21f98598c1e587ad78bd87ae22a74aba392b5566bb038" dependencies = [ "aws-credential-types", "aws-runtime", @@ -1546,9 +1585,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.7.2" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e086682a53d3aa241192aa110fa8dfce98f2f5ac2ead0de84d41582c7e8fdb96" +checksum = "92165296a47a812b267b4f41032ff8069ab7ff783696d217f0994a0d7ab585cd" dependencies = [ "aws-smithy-async", "aws-smithy-types", @@ -1563,9 +1602,9 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.2.8" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c9cdc179e6afbf5d391ab08c85eac817b51c87e1892a5edb5f7bbdc64314b4" +checksum = "4fbd94a32b3a7d55d3806fe27d98d3ad393050439dd05eb53ece36ec5e3d3510" dependencies = [ "base64-simd", "bytes", @@ -1734,7 +1773,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.85", + "syn 2.0.87", "which", ] @@ -1884,6 +1923,36 @@ dependencies = [ name = "blueprint-build-utils" version = "0.1.0" +[[package]] +name = "blueprint-examples" +version = "0.1.1" +dependencies = [ + "alloy-consensus", + "alloy-contract", + "alloy-json-abi", + "alloy-network", + "alloy-node-bindings", + "alloy-primitives 0.7.7", + "alloy-provider", + "alloy-pubsub", + "alloy-rpc-client 0.4.2", + "alloy-rpc-types", + "alloy-rpc-types-eth", + "alloy-signer", + "alloy-signer-local", + "alloy-sol-types 0.7.7", + "alloy-transport 0.1.4", + "alloy-transport-http 0.1.4", + "blueprint-metadata", + "color-eyre", + "gadget-sdk", + "reqwest 0.12.9", + "serde_json", + "tokio", + "tracing", + "uuid 1.11.0", +] + [[package]] name = "blueprint-manager" version = "0.1.1" @@ -2229,9 +2298,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.31" +version = "1.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "0f57c4b4da2a9d619dd035f27316d7a426305b75be93d09e92f2b9229c34feaf" dependencies = [ "jobserver", "libc", @@ -2394,7 +2463,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2755,7 +2824,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2814,7 +2883,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2871,7 +2940,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2893,7 +2962,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2989,7 +3058,7 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3000,7 +3069,7 @@ checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3013,7 +3082,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3033,7 +3102,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "unicode-xid", ] @@ -3121,7 +3190,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3132,18 +3201,18 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "docify" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a2f138ad521dc4a2ced1a4576148a6a610b4c5923933b062a263130a6802ce" +checksum = "a772b62b1837c8f060432ddcc10b17aae1453ef17617a99bc07789252d2a5896" dependencies = [ "docify_macros", ] [[package]] name = "docify_macros" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a081e51fb188742f5a7a1164ad752121abcb22874b21e2c3b0dd040c515fdad" +checksum = "60e6be249b0a462a14784a99b19bf35a667bb5e09de611738bb7362fa4c95ff7" dependencies = [ "common-path", "derive-syn-parse", @@ -3151,7 +3220,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.85", + "syn 2.0.87", "termcolor", "toml", "walkdir", @@ -3740,7 +3809,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3753,7 +3822,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3960,7 +4029,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", - "syn 2.0.85", + "syn 2.0.87", "toml", "walkdir", ] @@ -3978,7 +4047,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4004,7 +4073,7 @@ dependencies = [ "serde", "serde_json", "strum", - "syn 2.0.85", + "syn 2.0.87", "tempfile", "thiserror", "tiny-keccak", @@ -4191,7 +4260,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4506,9 +4575,9 @@ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +checksum = "3f1fa2f9765705486b33fd2acf1577f8ec449c2ba1f318ae5447697b7c08d210" dependencies = [ "fastrand", "futures-core", @@ -4535,7 +4604,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4627,7 +4696,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.85", + "syn 2.0.87", "tracing", "trybuild", ] @@ -4675,7 +4744,7 @@ dependencies = [ "gadget-sdk", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "trybuild", ] @@ -4751,6 +4820,7 @@ dependencies = [ "lock_api", "log", "nix 0.29.0", + "num-bigint 0.4.6", "parking_lot 0.12.3", "prometheus", "rand", @@ -5264,9 +5334,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" dependencies = [ "allocator-api2", "equivalent", @@ -5726,6 +5796,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -5744,12 +5932,23 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -6002,7 +6201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", "serde", ] @@ -7008,7 +7207,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -7230,7 +7429,7 @@ checksum = "3b51f1d220e3fa869e24cfd75915efe3164bd09bb11b3165db3f37f57bf673e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -7248,6 +7447,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "lock_api" version = "0.4.12" @@ -7270,7 +7475,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.0", + "hashbrown 0.15.1", ] [[package]] @@ -7337,7 +7542,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.38", + "rustix 0.38.39", ] [[package]] @@ -7739,9 +7944,9 @@ dependencies = [ [[package]] name = "ntex" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "223834e688405dcc46b5c28bc9225648c603e64d7b61e8903da33064b6f1464e" +checksum = "d7b2a207ac0bec11a1cc6b44b2dcbcab3991b0482337f62a78c919bf13e1b4f2" dependencies = [ "base64 0.22.1", "bitflags 2.6.0", @@ -7798,9 +8003,9 @@ dependencies = [ [[package]] name = "ntex-h2" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c26686e5f3b21552a554e83b5a3312a00038d82e262d6e01f507e2f81bda8a" +checksum = "d6f96f9a837c794ccf047438a1bbbf3d93fdcf2bfce42eb2a777595d1393ec7e" dependencies = [ "bitflags 2.6.0", "fxhash", @@ -7833,9 +8038,9 @@ dependencies = [ [[package]] name = "ntex-io" -version = "2.7.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c49628e35ff52f36137a8e732261f392de621406a163571888f6163e3f6b10" +checksum = "2ab41a7f7a96c6d1f9736d71efae9eb91c59274cb35757986eae9bd1fd76b052" dependencies = [ "bitflags 2.6.0", "log", @@ -7903,9 +8108,9 @@ dependencies = [ [[package]] name = "ntex-server" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9c3f4b038d1bcc3aff4e457a4b8258828b8e119c9ef4fd1e42c8df5e732cee" +checksum = "300921ed1f8626d7bfb06813ff839945eed08f763fbc1296590f878b8ee7f9e3" dependencies = [ "async-broadcast", "async-channel", @@ -7924,18 +8129,18 @@ dependencies = [ [[package]] name = "ntex-service" -version = "3.2.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02daa9c4fc8b5382b24dd69d504599a72774d6828e4fc21e9013cb62096db7aa" +checksum = "62351b99deeb128baafbd71fc22e8ef93bef643fc60fbb51db8a45006f03cda1" dependencies = [ "slab", ] [[package]] name = "ntex-tls" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e08948d9a1d27d11c474c374e6b8c0eee7e2dd4a288967d5dcce13d7adbd80e" +checksum = "5b6df536ec6f8f2499f5e3a2e2893cfc1b775408ee0c917d0570821025dc22e3" dependencies = [ "log", "ntex-bytes", @@ -7947,22 +8152,23 @@ dependencies = [ [[package]] name = "ntex-tokio" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "623868ff022f737d7b94212dc85e471f895e58f6c59c72552cdc9a22c5f167ed" +checksum = "c41ff5282a2912445e9fcf0c751b8c71edefa803bf71478515c8600f4e3e8853" dependencies = [ "log", "ntex-bytes", "ntex-io", + "ntex-rt", "ntex-util", "tokio", ] [[package]] name = "ntex-util" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b95f0cf57859407e61c61a7e131cd339b05537046580b65abbf0a817f46917be" +checksum = "10fc97836b6bf4044897370725b7fbcfecef9a8be29c352c35f8c0a587e2e721" dependencies = [ "bitflags 2.6.0", "futures-core", @@ -8110,7 +8316,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8224,7 +8430,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8263,9 +8469,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "4.4.0" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83e7ccb95e240b7c9506a3d544f10d935e142cc90b0a1d56954fb44d89ad6b97" +checksum = "c65ee1f9701bf938026630b455d5315f490640234259037edb259798b3bcf85e" dependencies = [ "num-traits", ] @@ -8404,7 +8610,7 @@ dependencies = [ "regex", "regex-syntax 0.8.5", "structmeta", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8527,28 +8733,6 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "periodic-web-poller-blueprint" -version = "0.1.1" -dependencies = [ - "async-trait", - "blueprint-metadata", - "color-eyre", - "ed25519-zebra 4.0.3", - "gadget-sdk", - "hex", - "k256", - "lock_api", - "parking_lot 0.12.3", - "reqwest 0.12.9", - "serde_json", - "sp-core", - "subxt-signer", - "tokio", - "tokio-util 0.7.12", - "tracing", -] - [[package]] name = "pest" version = "2.7.14" @@ -8580,7 +8764,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8653,7 +8837,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8691,7 +8875,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8783,7 +8967,7 @@ dependencies = [ "polkavm-common 0.8.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8795,7 +8979,7 @@ dependencies = [ "polkavm-common 0.9.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8805,7 +8989,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15e85319a0d5129dc9f021c62607e0804f5fb777a05cdda44d750ac0732def66" dependencies = [ "polkavm-derive-impl 0.8.0", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8815,7 +8999,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429" dependencies = [ "polkavm-derive-impl 0.9.0", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8828,7 +9012,7 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.38", + "rustix 0.38.39", "tracing", "windows-sys 0.59.0", ] @@ -8890,7 +9074,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8959,7 +9143,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -9011,7 +9195,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -9124,9 +9308,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e346e016eacfff12233c243718197ca12f148c84e1e84268a896699b41c71780" +checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" dependencies = [ "cfg_aliases 0.2.1", "libc", @@ -9311,7 +9495,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -9517,7 +9701,7 @@ checksum = "a5a11a05ee1ce44058fa3d5961d05194fdbe3ad6b40f904af764d81b86450e6b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -9775,9 +9959,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.38" +version = "0.38.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" dependencies = [ "bitflags 2.6.0", "errno", @@ -10092,7 +10276,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10118,7 +10302,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10140,7 +10324,7 @@ dependencies = [ "proc-macro2", "quote", "scale-info", - "syn 2.0.85", + "syn 2.0.87", "thiserror", ] @@ -10386,7 +10570,7 @@ checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10397,7 +10581,7 @@ checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10420,7 +10604,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10480,7 +10664,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10978,7 +11162,7 @@ checksum = "48d09fa0a5f7299fb81ee25ae3853d26200f7a348148aed6de76be905c007dbe" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -11099,7 +11283,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -11518,7 +11702,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -11529,7 +11713,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -11551,7 +11735,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -11627,7 +11811,7 @@ dependencies = [ "scale-info", "scale-typegen", "subxt-metadata", - "syn 2.0.85", + "syn 2.0.87", "thiserror", "tokio", ] @@ -11700,7 +11884,7 @@ dependencies = [ "quote", "scale-typegen", "subxt-codegen", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -11783,9 +11967,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.85" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -11801,19 +11985,19 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] name = "syn-solidity" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16320d4a2021ba1a32470b3759676114a918885e9800e68ad60f2c67969fba62" +checksum = "edf42e81491fb8871b74df3d222c64ae8cbc1269ea509fa768a3ed3e1b0ac8cb" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -11851,7 +12035,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -11910,16 +12094,6 @@ dependencies = [ "libc", ] -[[package]] -name = "tangle-raw-event-listener-blueprint" -version = "0.1.1" -dependencies = [ - "blueprint-metadata", - "color-eyre", - "gadget-sdk", - "tracing", -] - [[package]] name = "tangle-subxt" version = "0.5.0" @@ -11960,7 +12134,7 @@ checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if 1.0.0", "fastrand", - "rustix 0.38.38", + "rustix 0.38.39", "windows-sys 0.52.0", ] @@ -12000,7 +12174,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" dependencies = [ - "rustix 0.38.38", + "rustix 0.38.39", "windows-sys 0.59.0", ] @@ -12041,22 +12215,22 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] name = "thiserror" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -12120,6 +12294,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -12161,7 +12345,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -12384,7 +12568,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -12557,7 +12741,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -12629,7 +12813,7 @@ checksum = "f9534daa9fd3ed0bd911d462a37f172228077e7abf18c18a5f67199d959205f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -12761,12 +12945,12 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna 1.0.3", "percent-encoding", "serde", ] @@ -12783,6 +12967,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[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" @@ -12840,9 +13036,9 @@ checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" [[package]] name = "w3f-bls" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a48c48447120a85b0bdb897ba9426a7aa15b4229498a2e19103e8c9368dd4b2" +checksum = "70a3028804c8bbae2a97a15b71ffc0e308c4b01a520994aafa77d56e94e19024" dependencies = [ "ark-bls12-377", "ark-bls12-381", @@ -12924,7 +13120,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -12958,7 +13154,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -13209,7 +13405,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.38", + "rustix 0.38.39", ] [[package]] @@ -13317,7 +13513,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -13328,7 +13524,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -13603,6 +13799,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "ws_stream_wasm" version = "0.7.4" @@ -13727,6 +13935,30 @@ dependencies = [ "time", ] +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure 0.13.1", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -13745,7 +13977,28 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure 0.13.1", ] [[package]] @@ -13765,7 +14018,29 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 19a03955..47c17172 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,7 @@ members = [ "blueprints/incredible-squaring", "blueprints/incredible-squaring-eigenlayer", "blueprints/incredible-squaring-symbiotic", - "blueprints/periodic-web-poller", - "blueprints/tangle-raw-event-listener", + "blueprints/examples", "cli", "gadget-io", "blueprint-test-utils", @@ -54,8 +53,7 @@ gadget-sdk = { path = "./sdk", default-features = false, version = "0.3.0" } incredible-squaring-blueprint = { path = "./blueprints/incredible-squaring", default-features = false, version = "0.1.1" } incredible-squaring-blueprint-eigenlayer = { path = "./blueprints/incredible-squaring-eigenlayer", default-features = false, version = "0.1.1" } incredible-squaring-blueprint-symbiotic = { path = "./blueprints/incredible-squaring-symbiotic", default-features = false, version = "0.1.1" } -periodic-web-poller-blueprint = { path = "./blueprints/periodic-web-poller", default-features = false, version = "0.1.1" } -tangle-raw-event-listener-blueprint = { path = "./blueprints/tangle-raw-event-listener", default-features = false, version = "0.1.1" } +blueprint-examples = { path = "./blueprints/examples", default-features = false, version = "0.1.1" } gadget-blueprint-proc-macro = { path = "./macros/blueprint-proc-macro", default-features = false, version = "0.3.0" } gadget-blueprint-proc-macro-core = { path = "./macros/blueprint-proc-macro-core", default-features = false, version = "0.1.5" } gadget-context-derive = { path = "./macros/context-derive", default-features = false, version = "0.2.0" } diff --git a/blueprints/ecdsa-threshold-mpc/.gitignore b/blueprints/ecdsa-threshold-mpc/.gitignore deleted file mode 100644 index c046cc39..00000000 --- a/blueprints/ecdsa-threshold-mpc/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by Cargo -target/ - -# These are backup files generated by rustfmt -**/*.rs.bk - -# MSVC Windows builds of rustc generate these, which store debugging information -*.pdb - -.idea -.vscode -.zed - -.direnv -.DS_Store -# Solc Compiler files -cache/ -out/ - -# Ignores development broadcast logs -!/broadcast -/broadcast/*/31337/ -/broadcast/**/dry-run/ - -# Docs -docs/ - -# Dotenv file -.env -blueprint.lock diff --git a/blueprints/ecdsa-threshold-mpc/Cargo.toml b/blueprints/ecdsa-threshold-mpc/Cargo.toml deleted file mode 100644 index 71e27f7b..00000000 --- a/blueprints/ecdsa-threshold-mpc/Cargo.toml +++ /dev/null @@ -1,43 +0,0 @@ -[package] -name = "ecdsa-threshold-mpc" -version = "0.1.1" -edition = "2021" -description = "A threshold MPC blueprint allowing key generation, threshold signing, and key refreshes." -authors = ["drewstone "] -license = "Unlicense" -homepage = "https://tangle.tools" -repository = "https://github.com/tangle-network/ecdsa-threshold-mpc" -readme = "README.md" -categories = ["cryptography", "cryptography::cryptocurrencies"] -keywords = ["tangle", "blueprint", "avs"] -rust-version = "1.81" -publish = false - -[dependencies] -thiserror = { workspace = true } -futures = { workspace = true } -rand = { workspace = true, features = ["alloc"] } -gadget-sdk = { workspace = true, features = ["std"] } - -color-eyre = { workspace = true } -tokio = { workspace = true, default-features = false, features = ["full"] } -tracing-subscriber = { workspace = true, features = ["parking_lot", "env-filter"] } -serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true } -sp-core = { workspace = true, features = ["std"] } -itertools = { workspace = true } - -cggmp21 = { version = "0.4", features = ["curve-stark", "curve-secp256k1", "curve-secp256r1"] } -key-share = { version = "0.4", default-features = false } - -generic-ec = { version = "0.4.1", default-features = false } -round-based = { version = "0.3", default-features = false } -digest = { version = "0.10", default-features = false } -sha2 = { version = "0.10", default-features = false } - -[build-dependencies] -blueprint-metadata = "0.1" - -[features] -default = ["std"] -std = [] diff --git a/blueprints/ecdsa-threshold-mpc/LICENSE b/blueprints/ecdsa-threshold-mpc/LICENSE deleted file mode 100644 index fdddb29a..00000000 --- a/blueprints/ecdsa-threshold-mpc/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -This is free and unencumbered software released into the public domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -For more information, please refer to diff --git a/blueprints/ecdsa-threshold-mpc/README.md b/blueprints/ecdsa-threshold-mpc/README.md deleted file mode 100644 index 4e03f048..00000000 --- a/blueprints/ecdsa-threshold-mpc/README.md +++ /dev/null @@ -1,13 +0,0 @@ -## ECDSA Threshold MPC Blueprint - -_Note: This Blueprint is under active development._ - -A Blueprint for running a ECDSA threshold MPC protocol on the Tangle Network. - -## Building the Blueprint - -- To build the blueprint, just run the following command: - -```bash -cargo build -p ecdsa-threshold-mpc -``` diff --git a/blueprints/ecdsa-threshold-mpc/build.rs b/blueprints/ecdsa-threshold-mpc/build.rs deleted file mode 100644 index c77402e1..00000000 --- a/blueprints/ecdsa-threshold-mpc/build.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=src/main.rs"); - blueprint_metadata::generate_json(); -} diff --git a/blueprints/ecdsa-threshold-mpc/contracts/remappings.txt b/blueprints/ecdsa-threshold-mpc/contracts/remappings.txt deleted file mode 100644 index d4921f78..00000000 --- a/blueprints/ecdsa-threshold-mpc/contracts/remappings.txt +++ /dev/null @@ -1,10 +0,0 @@ -@uniswap/v3-core/=lib/tnt-core/lib/uniswap-v3-core/contracts/ -clones/=lib/tnt-core/lib/clones-with-immutable-args/src/ -forge-std/=lib/forge-std/src/ -forge-test/=lib/tnt-core/lib/prb-test/src/ -math/=lib/tnt-core/lib/prb-math/src/ -openzeppelin-contracts-upgradeable/=lib/tnt-core/lib/openzeppelin-contracts-upgradeable/contracts/ -openzeppelin-contracts/=lib/tnt-core/lib/openzeppelin-contracts/contracts/ -solmate/=lib/tnt-core/lib/solmate/src/ -test/=lib/tnt-core/test/ -tnt-core/=lib/tnt-core/src/ \ No newline at end of file diff --git a/blueprints/ecdsa-threshold-mpc/contracts/src/HelloBlueprint.sol b/blueprints/ecdsa-threshold-mpc/contracts/src/HelloBlueprint.sol deleted file mode 100644 index c159a3c0..00000000 --- a/blueprints/ecdsa-threshold-mpc/contracts/src/HelloBlueprint.sol +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: UNLICENSE -pragma solidity >=0.8.13; - -import "tnt-core/BlueprintServiceManager.sol"; - -/** - * @title HelloBlueprint - * @dev This contract is an example of a service blueprint that provides a single service. - */ -contract HelloBlueprint is BlueprintServiceManager { - /** - * @dev Hook for service operator registration. Called when a service operator - * attempts to register with the blueprint. - * @param operator The operator's details. - * @param _registrationInputs Inputs required for registration. - */ - function onRegister(bytes calldata operator, bytes calldata _registrationInputs) - public - payable - override - onlyFromRootChain - { - // Do something with the operator's details - } - - /** - * @dev Hook for service instance requests. Called when a user requests a service - * instance from the blueprint. - * @param serviceId The ID of the requested service. - * @param operators The operators involved in the service. - * @param _requestInputs Inputs required for the service request. - */ - function onRequest(uint64 serviceId, bytes[] calldata operators, bytes calldata _requestInputs) - public - payable - override - onlyFromRootChain - { - // Do something with the service request - } - - /** - * @dev Hook for handling job call results. Called when operators send the result - * of a job execution. - * @param serviceId The ID of the service related to the job. - * @param job The job identifier. - * @param _jobCallId The unique ID for the job call. - * @param participant The participant (operator) sending the result. - * @param _inputs Inputs used for the job execution. - * @param _outputs Outputs resulting from the job execution. - */ - function onJobCallResult( - uint64 serviceId, - uint8 job, - uint64 _jobCallId, - bytes calldata participant, - bytes calldata _inputs, - bytes calldata _outputs - ) public virtual override onlyFromRootChain { - // Do something with the job call result - } - - /** - * @dev Verifies the result of a job call. This function is used to validate the - * outputs of a job execution against the expected results. - * @param serviceId The ID of the service related to the job. - * @param job The job identifier. - * @param jobCallId The unique ID for the job call. - * @param participant The participant (operator) whose result is being verified. - * @param inputs Inputs used for the job execution. - * @param outputs Outputs resulting from the job execution. - * @return bool Returns true if the job call result is verified successfully, - * otherwise false. - */ - function verifyJobCallResult( - uint64 serviceId, - uint8 job, - uint64 jobCallId, - bytes calldata participant, - bytes calldata inputs, - bytes calldata outputs - ) public view virtual override onlyFromRootChain returns (bool) { - // Verify the job call result here - return true; - } - - /** - * @dev Converts a public key to an operator address. - * @param publicKey The public key to convert. - * @return address The operator address. - */ - function operatorAddressFromPublicKey(bytes calldata publicKey) internal pure returns (address) { - return address(uint160(uint256(keccak256(publicKey)))); - } -} diff --git a/blueprints/ecdsa-threshold-mpc/foundry.toml b/blueprints/ecdsa-threshold-mpc/foundry.toml deleted file mode 100644 index 26bed054..00000000 --- a/blueprints/ecdsa-threshold-mpc/foundry.toml +++ /dev/null @@ -1,10 +0,0 @@ -[profile.default] -src = "contracts/src" -test = "contracts/test" -out = "contracts/out" -script = "contracts/script" -cache_path = "contracts/cache" -broadcast = "contracts/broadcast" -libs = ["contracts/lib"] - -# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/blueprints/ecdsa-threshold-mpc/rust-toolchain.toml b/blueprints/ecdsa-threshold-mpc/rust-toolchain.toml deleted file mode 100644 index 288fa153..00000000 --- a/blueprints/ecdsa-threshold-mpc/rust-toolchain.toml +++ /dev/null @@ -1,5 +0,0 @@ -[toolchain] -channel = "stable" -components = ["rustfmt", "clippy", "rust-src"] -targets = ["wasm32-unknown-unknown"] -profile = "minimal" diff --git a/blueprints/ecdsa-threshold-mpc/src/jobs/keygen.rs b/blueprints/ecdsa-threshold-mpc/src/jobs/keygen.rs deleted file mode 100644 index 77710c48..00000000 --- a/blueprints/ecdsa-threshold-mpc/src/jobs/keygen.rs +++ /dev/null @@ -1,122 +0,0 @@ -use cggmp21::{ - progress::PerfProfiler, - supported_curves::{Secp256k1, Secp256r1, Stark}, -}; -use gadget_sdk::{ - self as sdk, - network::{channels::UserID, IdentifierInfo, ProtocolMessage}, -}; -use generic_ec::Curve; -use rand::SeedableRng; -use sdk::tangle_subxt::subxt::ext::futures::future::try_join_all; -use sp_core::{ecdsa, keccak_256}; -use std::sync::Arc; -use std::{collections::HashMap, convert::Infallible, fmt::format}; -use tokio::spawn; - -use color_eyre::Result; - -use crate::mpc::{keygen::run_full_keygen_protocol, DefaultCryptoHasher, DefaultSecurityLevel}; - -use super::Context; - -/// The execution of these jobs represent a service instance with specific operators. -/// -/// Things that are appealing to provide the developer are: -/// - For networked protocols we need a unique identifier for protocol execution. Each job/task should have a unique identifier. -/// If multiple messaging protocols are created in a single task, they should have unique identifiers. This should be clearly -/// provided/exposed to the developer using our SDK. The variable names should likely indicate uniqueness. -#[sdk::job( - id = 0, - params(curve, t, num_keys, hd_wallet), - - verifier(evm = "HelloBlueprint") -)] -pub async fn keygen( - ctx: Context, - curve: u8, - t: u16, - num_keys: u16, - hd_wallet: bool, -) -> Result { - // TODO: How to grab the specific operators? What index am I? - let n = 3 * (t + 1); - let i = 0; - // TODO: Constructing mapping from user IDs to ecdsa keys? - let mapping: HashMap = HashMap::new(); - // TODO: How to get my ecdsa key? - let my_ecdsa_key = ecdsa::Public::from_raw([0u8; 33]); - // TODO: How to grab api / task / job specific onchain metadata? - // TODO: How to get restake information about this instance? - // TODO: How to get the service ID? - let service_id = 1u64; - let (session_id, block_id, task_id, retry_id) = - (Some(0u64), Some(0u64), Some(0u64), Some(0u64)); - let identifier_info: IdentifierInfo = IdentifierInfo { - session_id, - block_id, - task_id, - retry_id, - }; - let rng = rand::rngs::StdRng::from_entropy(); - // TODO: How to get the raw job bytes? - let job_id_bytes = vec![0u8; 32]; - let mix = keccak_256(b"cggmp21-keygen"); - let eid_bytes = [&job_id_bytes[..], &mix[..]].concat(); - let eid = cggmp21::ExecutionId::new(&eid_bytes); - let mix = keccak_256(b"cggmp21-keygen-aux"); - let aux_eid_bytes = [&job_id_bytes[..], &mix[..]].concat(); - let aux_eid = cggmp21::ExecutionId::new(&aux_eid_bytes); - let tracer = PerfProfiler::new(); - - let id = service_id.to_string(); - let _span = tracing::info_span!("cggmp21-keygen", id = id).entered(); - - // TODO: What is the protocol message channel? Can I get it from the network? - let (_dummy_sender, protocol_message_channel) = - futures::channel::mpsc::unbounded::(); - let mut handles = Vec::new(); - macro_rules! run_keygen_for_curve { - ($curve:ty) => { - for _ in 0..num_keys { - let handle = spawn(async move { - run_full_keygen_protocol::< - $curve, - DefaultSecurityLevel, - DefaultCryptoHasher, - _, - _, - >( - protocol_message_channel, - identifier_info, - Arc::new(mapping), - my_ecdsa_key, - ctx.network, - tracer, - eid, - aux_eid, - i, - n, - t, - hd_wallet, - rng, - &job_id_bytes[..], - ) - .await - }); - handles.push(handle); - } - }; - } - - match curve { - 0 => run_keygen_for_curve!(Secp256k1), - 1 => run_keygen_for_curve!(Secp256r1), - 2 => run_keygen_for_curve!(Stark), - _ => panic!("Invalid curve"), - } - - let results = try_join_all(handles).await?; - - Ok("Hello World!".to_string()) -} diff --git a/blueprints/ecdsa-threshold-mpc/src/jobs/mod.rs b/blueprints/ecdsa-threshold-mpc/src/jobs/mod.rs deleted file mode 100644 index c6de6928..00000000 --- a/blueprints/ecdsa-threshold-mpc/src/jobs/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -use gadget_sdk::network::gossip::GossipHandle; - -pub mod keygen; -pub mod refresh; -pub mod sign; - -pub use keygen::*; -pub use refresh::*; -pub use sign::*; - -#[derive(Clone)] -pub struct Context { - pub network: GossipHandle, -} - -impl Context { - // TODO: Get my index in the network (deterministically) - // TODO: Get the mapping of all peers to their keys -} diff --git a/blueprints/ecdsa-threshold-mpc/src/jobs/refresh.rs b/blueprints/ecdsa-threshold-mpc/src/jobs/refresh.rs deleted file mode 100644 index 3e158e57..00000000 --- a/blueprints/ecdsa-threshold-mpc/src/jobs/refresh.rs +++ /dev/null @@ -1,14 +0,0 @@ -use gadget_sdk as sdk; -use std::convert::Infallible; - -use color_eyre::Result; - -#[sdk::job( - id = 2, - params(keygen_id, new_parties, t), - - verifier(evm = "HelloBlueprint") -)] -pub fn refresh(keygen_id: u32, new_parties: Vec, t: u16) -> Result { - Ok("Hello World!".to_string()) -} diff --git a/blueprints/ecdsa-threshold-mpc/src/jobs/sign.rs b/blueprints/ecdsa-threshold-mpc/src/jobs/sign.rs deleted file mode 100644 index c6230b6b..00000000 --- a/blueprints/ecdsa-threshold-mpc/src/jobs/sign.rs +++ /dev/null @@ -1,14 +0,0 @@ -use gadget_sdk as sdk; -use std::convert::Infallible; - -use color_eyre::Result; - -#[sdk::job( - id = 1, - params(msgs, is_prehashed), - - verifier(evm = "HelloBlueprint") -)] -pub fn sign(msgs: Vec, is_prehashed: bool) -> Result { - Ok("Hello World!".to_string()) -} diff --git a/blueprints/ecdsa-threshold-mpc/src/main.rs b/blueprints/ecdsa-threshold-mpc/src/main.rs deleted file mode 100644 index 63d6e2db..00000000 --- a/blueprints/ecdsa-threshold-mpc/src/main.rs +++ /dev/null @@ -1,62 +0,0 @@ -use gadget_sdk as sdk; -use std::convert::Infallible; - -use color_eyre::{eyre::OptionExt, Result}; -use sdk::{ - events_watcher::tangle::TangleEventsWatcher, keystore::backend::GenericKeyStore, - keystore::Backend, tangle_subxt::*, -}; - -pub mod jobs; -pub mod mpc; - -#[tokio::main] -async fn main() -> Result<()> { - color_eyre::install()?; - - // Initialize the logger - let env_filter = tracing_subscriber::EnvFilter::from_default_env(); - tracing_subscriber::fmt() - .compact() - .with_target(true) - .with_env_filter(env_filter) - .init(); - - // Initialize the environment - let env = sdk::config::load(None)?; - let keystore = env.keystore()?; - let signer = env.first_signer()?; - let client: TangleClient = - subxt::OnlineClient::from_url(&env.http_rpc_endpoint).await?; - - // // Create the event handler from the job - // let keygen_job = KeygenEventHandler { - // service_id: env.service_id, - // signer, - // }; - - // let signing_job = SigningEventHandler { - // service_id: env.service_id, - // signer, - // }; - - // let key_refresh_job = KeyRefreshEventHandler { - // service_id: env.service_id, - // signer, - // }; - - // tracing::info!("Starting the event watcher ..."); - - // SubstrateEventWatcher::run( - // &TangleEventsWatcher, - // client, - // // Add more handler here if we have more functions. - // vec![ - // Box::new(keygen_job), - // Box::new(signing_job), - // Box::new(key_refresh_job), - // ], - // ) - // .await?; - Ok(()) -} diff --git a/blueprints/ecdsa-threshold-mpc/src/mpc/keygen.rs b/blueprints/ecdsa-threshold-mpc/src/mpc/keygen.rs deleted file mode 100644 index 0a39dfbe..00000000 --- a/blueprints/ecdsa-threshold-mpc/src/mpc/keygen.rs +++ /dev/null @@ -1,206 +0,0 @@ -use cggmp21::generic_ec::Curve; -use cggmp21::key_refresh::msg::aux_only; -use cggmp21::key_refresh::AuxInfoGenerationBuilder; -use cggmp21::key_share::DirtyKeyShare; -use cggmp21::key_share::Validate; -use cggmp21::keygen::msg::threshold::Msg; -use cggmp21::keygen::KeygenBuilder; -use cggmp21::progress::PerfProfiler; -use cggmp21::security_level::SecurityLevel; -use cggmp21::supported_curves::{Secp256k1, Secp256r1, Stark}; -use cggmp21::KeyShare; -use cggmp21::PregeneratedPrimes; -use digest::typenum::U32; -use digest::Digest; -use gadget_sdk::network::channels::create_job_manager_to_async_protocol_channel_split_io; -use gadget_sdk::network::channels::UserID; -use gadget_sdk::network::deserialize; -use gadget_sdk::network::serialize; -use gadget_sdk::network::IdentifierInfo; -use gadget_sdk::network::Network; -use gadget_sdk::network::ProtocolMessage; -use gadget_sdk::store::KeyValueStoreBackend; -use gadget_sdk::{debug, trace}; -use itertools::Itertools; -use rand::rngs::{OsRng, StdRng}; -use rand::{CryptoRng, RngCore, SeedableRng}; -use round_based::{Delivery, Incoming, MpcParty, Outgoing}; -use serde::Serialize; -use sp_core::keccak_256; -use sp_core::{ecdsa, Pair}; -use std::collections::{BTreeMap, HashMap}; -use std::sync::Arc; -use tokio::sync::mpsc::UnboundedReceiver; - -use crate::mpc::{DefaultCryptoHasher, DefaultSecurityLevel}; - -use super::Error; - -#[allow(clippy::too_many_arguments)] -pub async fn run_and_serialize_keygen< - 'r, - E: Curve, - S: SecurityLevel, - H: Digest + Clone + Send + 'static, - D, - R, ->( - tracer: &mut PerfProfiler, - eid: cggmp21::ExecutionId<'r>, - i: u16, - n: u16, - t: u16, - hd_wallet: bool, - party: MpcParty, D>, - mut rng: R, -) -> Result, Error> -where - D: Delivery>, - R: RngCore + CryptoRng, -{ - let builder = KeygenBuilder::::new(eid, i, n); - let incomplete_key_share = builder - .set_progress_tracer(tracer) - .set_threshold(t) - .hd_wallet(hd_wallet) - .start(&mut rng, party) - .await?; - debug!("Finished AsyncProtocol - Keygen"); - serialize(&incomplete_key_share).map_err(Into::into) -} - -#[allow(clippy::too_many_arguments)] -pub async fn run_and_serialize_keyrefresh< - 'r, - E: Curve, - S: SecurityLevel, - H: Digest + Clone + Send + 'static, - D, ->( - incomplete_key_share: Vec, - pregenerated_primes: PregeneratedPrimes, - tracer: &mut PerfProfiler, - aux_eid: cggmp21::ExecutionId<'r>, - i: u16, - n: u16, - party: MpcParty, D>, - mut rng: StdRng, -) -> Result<(Vec, Vec), Error> -where - D: Delivery>, -{ - let incomplete_key_share: cggmp21::key_share::Valid< - cggmp21::key_share::DirtyIncompleteKeyShare, - > = deserialize(&incomplete_key_share)?; - - let aux_info_builder = - AuxInfoGenerationBuilder::::new_aux_gen(aux_eid, i, n, pregenerated_primes); - - let aux_info = aux_info_builder - .set_progress_tracer(tracer) - .start(&mut rng, party) - .await?; - let perf_report = tracer.get_report()?; - trace!("Aux info protocol report: {perf_report}"); - debug!("Finished AsyncProtocol - Aux Info"); - - let key_share: KeyShare = DirtyKeyShare { - core: incomplete_key_share.into_inner(), - aux: aux_info.into_inner(), - } - .validate() - .map_err(|e| Error::ValidateError(e.to_string()))?; - // Serialize the key share and the public key - serialize(&key_share) - .map(|ks| (ks, key_share.shared_public_key.to_bytes(true).to_vec())) - .map_err(Into::into) -} - -async fn pregenerate_primes( - tracer: &PerfProfiler, - job_id_bytes: &[u8], -) -> Result<(PerfProfiler, PregeneratedPrimes), Error> { - let perf_report = tracer.get_report()?; - trace!("Incomplete Keygen protocol report: {perf_report}"); - debug!("Finished AsyncProtocol - Incomplete Keygen"); - let tracer = PerfProfiler::new(); - - let pregenerated_primes_key = - keccak_256(&[&b"dfns-cggmp21-keygen-primes"[..], job_id_bytes].concat()); - let now = tokio::time::Instant::now(); - let pregenerated_primes = tokio::task::spawn_blocking(|| { - let mut rng = OsRng; - cggmp21::PregeneratedPrimes::::generate(&mut rng) - }) - .await?; - - let elapsed = now.elapsed(); - debug!("Pregenerated primes took {elapsed:?}"); - - Ok((tracer, pregenerated_primes)) -} - -#[allow(clippy::too_many_arguments)] -pub async fn run_full_keygen_protocol< - 'a, - E: Curve, - S: SecurityLevel, - H: Digest + Clone + Send + 'static, - KBE: KeyValueStoreBackend, - N: Network, ->( - protocol_message_channel: UnboundedReceiver, - identifier_info: IdentifierInfo, - mapping: Arc>, - my_role_id: ecdsa::Public, - network: N, - mut tracer: PerfProfiler, - eid: cggmp21::ExecutionId<'a>, - aux_eid: cggmp21::ExecutionId<'a>, - i: u16, - n: u16, - t: u16, - hd_wallet: bool, - rng: StdRng, - job_id_bytes: &[u8], -) -> Result<(Vec, Vec), Error> { - let (tx0, rx0, tx1, rx1) = create_job_manager_to_async_protocol_channel_split_io( - protocol_message_channel, - identifier_info, - mapping, - my_role_id, - network, - i, - ); - let delivery = (rx0, tx0); - let party = MpcParty::, _, _>::connected(delivery); - let incomplete_key_share = run_and_serialize_keygen::( - &mut tracer, - eid, - i, - n, - t, - hd_wallet, - party, - rng.clone(), - ) - .await?; - let (mut tracer, pregenerated_primes) = - pregenerate_primes::(&tracer, job_id_bytes).await?; - - let delivery = (rx1, tx1); - let party = MpcParty::, _, _>::connected(delivery); - let (key_share, serialized_public_key) = run_and_serialize_keyrefresh::( - incomplete_key_share, - pregenerated_primes, - &mut tracer, - aux_eid, - i, - n, - party, - rng, - ) - .await?; - - Ok((key_share, serialized_public_key)) -} diff --git a/blueprints/ecdsa-threshold-mpc/src/mpc/mod.rs b/blueprints/ecdsa-threshold-mpc/src/mpc/mod.rs deleted file mode 100644 index 59b67f03..00000000 --- a/blueprints/ecdsa-threshold-mpc/src/mpc/mod.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::collections::HashMap; - -use cggmp21::security_level::SecurityLevel128; -use cggmp21::{key_share::InvalidKeyShare, progress::ProfileError, security_level::SecurityLevel}; -use generic_ec::Curve; -use sha2::Sha256; -use sp_core::ecdsa; - -pub mod keygen; -pub mod refresh; -pub mod sign; - -pub type DefaultSecurityLevel = SecurityLevel128; -pub type DefaultCryptoHasher = Sha256; - -#[derive(thiserror::Error, Debug)] -pub enum Error { - #[error("IO error")] - Cggmp21IoError(String), - #[error("SDK error")] - SdkError(#[from] gadget_sdk::Error), - #[error("Serialization error")] - SerializationError(#[from] serde_json::Error), - #[error("Keygen error")] - KeygenError(#[from] cggmp21::keygen::KeygenError), - #[error("Sign error")] - SignError(#[from] cggmp21::signing::SigningError), - #[error("Key refresh error")] - KeyRefreshError(#[from] cggmp21::key_refresh::KeyRefreshError), - #[error("Invalid key share")] - ValidateError(String), - #[error("Tokio join error")] - JoinError(#[from] tokio::task::JoinError), - #[error("Tracer profile error")] - TracerProfileError(#[from] cggmp21::progress::ProfileError), -} diff --git a/blueprints/ecdsa-threshold-mpc/src/mpc/refresh.rs b/blueprints/ecdsa-threshold-mpc/src/mpc/refresh.rs deleted file mode 100644 index 8b137891..00000000 --- a/blueprints/ecdsa-threshold-mpc/src/mpc/refresh.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/blueprints/ecdsa-threshold-mpc/src/mpc/sign.rs b/blueprints/ecdsa-threshold-mpc/src/mpc/sign.rs deleted file mode 100644 index 8b137891..00000000 --- a/blueprints/ecdsa-threshold-mpc/src/mpc/sign.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/blueprints/ecdsa-threshold-mpc/taplo.toml b/blueprints/ecdsa-threshold-mpc/taplo.toml deleted file mode 100644 index 3b9f0df9..00000000 --- a/blueprints/ecdsa-threshold-mpc/taplo.toml +++ /dev/null @@ -1,4 +0,0 @@ -[formatting] -align_entries = false -array_auto_expand = true -column_width = 120 diff --git a/blueprints/examples/Cargo.toml b/blueprints/examples/Cargo.toml new file mode 100644 index 00000000..393c0f6d --- /dev/null +++ b/blueprints/examples/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "blueprint-examples" +version = "0.1.1" +description = "A variety of example blueprint jobs, event listeners, contexts, and more." +authors.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +publish = false + +[dependencies] +gadget-sdk = { workspace = true, features = ["std"] } +color-eyre = { workspace = true } +reqwest = { workspace = true } +serde_json = { workspace = true } +tokio = { workspace = true, features = ["full"] } +tracing = { workspace = true } +uuid = { workspace = true } + +alloy-primitives = "0.7.2" +alloy-json-abi = "0.7.2" +alloy-sol-types = "0.7.2" +alloy-rpc-client = "0.4.2" +alloy-rpc-types = { version = "0.1" } +alloy-rpc-types-eth = { version = "0.1" } +alloy-provider = { version = "0.1", features = ["reqwest", "ws"] } +alloy-pubsub = { version = "0.1" } +alloy-signer = { version = "0.1" } +alloy-signer-local = { version = "0.1" } +alloy-network = { version = "0.1" } +alloy-node-bindings = "0.4.2" +alloy-contract = { version = "0.1" } +alloy-consensus = { version = "0.1" } +alloy-transport = { version = "0.1" } +alloy-transport-http = { version = "0.1" } +[build-dependencies] +blueprint-metadata = { workspace = true } + +[features] +default = ["std"] +std = [] diff --git a/blueprints/tangle-raw-event-listener/build.rs b/blueprints/examples/build.rs similarity index 72% rename from blueprints/tangle-raw-event-listener/build.rs rename to blueprints/examples/build.rs index acb638b3..9d51e42b 100644 --- a/blueprints/tangle-raw-event-listener/build.rs +++ b/blueprints/examples/build.rs @@ -1,5 +1,5 @@ fn main() { println!("cargo:rerun-if-changed=src/lib.rs"); println!("cargo:rerun-if-changed=src/main.rs"); - blueprint_metadata::generate_json(); + // blueprint_metadata::generate_json(); } diff --git a/blueprints/examples/contracts/.github/workflows/test.yml b/blueprints/examples/contracts/.github/workflows/test.yml new file mode 100644 index 00000000..762a2966 --- /dev/null +++ b/blueprints/examples/contracts/.github/workflows/test.yml @@ -0,0 +1,45 @@ +name: CI + +on: + push: + pull_request: + workflow_dispatch: + +env: + FOUNDRY_PROFILE: ci + +jobs: + check: + strategy: + fail-fast: true + + name: Foundry project + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Show Forge version + run: | + forge --version + + - name: Run Forge fmt + run: | + forge fmt --check + id: fmt + + - name: Run Forge build + run: | + forge build --sizes + id: build + + - name: Run Forge tests + run: | + forge test -vvv + id: test diff --git a/blueprints/ecdsa-threshold-mpc/contracts/.gitignore b/blueprints/examples/contracts/.gitignore similarity index 100% rename from blueprints/ecdsa-threshold-mpc/contracts/.gitignore rename to blueprints/examples/contracts/.gitignore diff --git a/blueprints/ecdsa-threshold-mpc/contracts/README.md b/blueprints/examples/contracts/README.md similarity index 100% rename from blueprints/ecdsa-threshold-mpc/contracts/README.md rename to blueprints/examples/contracts/README.md diff --git a/blueprints/examples/contracts/foundry.toml b/blueprints/examples/contracts/foundry.toml new file mode 100644 index 00000000..25b918f9 --- /dev/null +++ b/blueprints/examples/contracts/foundry.toml @@ -0,0 +1,6 @@ +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/blueprints/examples/contracts/lib/forge-std b/blueprints/examples/contracts/lib/forge-std new file mode 160000 index 00000000..1eea5bae --- /dev/null +++ b/blueprints/examples/contracts/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 1eea5bae12ae557d589f9f0f0edae2faa47cb262 diff --git a/blueprints/examples/contracts/script/Counter.s.sol b/blueprints/examples/contracts/script/Counter.s.sol new file mode 100644 index 00000000..cdc1fe9a --- /dev/null +++ b/blueprints/examples/contracts/script/Counter.s.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Script, console} from "forge-std/Script.sol"; +import {Counter} from "../src/Counter.sol"; + +contract CounterScript is Script { + Counter public counter; + + function setUp() public {} + + function run() public { + vm.startBroadcast(); + + counter = new Counter(); + + vm.stopBroadcast(); + } +} diff --git a/blueprints/examples/contracts/src/Counter.sol b/blueprints/examples/contracts/src/Counter.sol new file mode 100644 index 00000000..6e5b1272 --- /dev/null +++ b/blueprints/examples/contracts/src/Counter.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + struct NumberSequence { + uint256[5] numbers; + } + + mapping(bytes32 => NumberSequence) sequences; + + event NumberIncremented(bytes32 indexed id, uint8 indexed index, uint256 indexed oldValue, uint256 newValue); + + function setNumber(bytes32 id, uint8 index, uint256 newNumber) public { + require(index < 5, "Index out of bounds"); + sequences[id].numbers[index] = newNumber; + } + + function increment(bytes32 id, uint8 index) public { + require(index < 5, "Index out of bounds"); + uint256 oldValue = sequences[id].numbers[index]; + sequences[id].numbers[index]++; + emit NumberIncremented(id, index, oldValue, sequences[id].numbers[index]); + } + + function getSequence(bytes32 id) public view returns (uint256[5] memory) { + return sequences[id].numbers; + } +} diff --git a/blueprints/examples/contracts/test/Counter.t.sol b/blueprints/examples/contracts/test/Counter.t.sol new file mode 100644 index 00000000..c9df4f51 --- /dev/null +++ b/blueprints/examples/contracts/test/Counter.t.sol @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Test, console} from "forge-std/Test.sol"; +import {Counter} from "../src/Counter.sol"; + +contract CounterTest is Test { + Counter public counter; + bytes32 constant TEST_ID = bytes32(uint256(1)); + bytes32 constant TEST_ID_2 = bytes32(uint256(2)); + uint8 constant TEST_INDEX = 0; + + function setUp() public { + counter = new Counter(); + } + + function test_InitialSequenceIsZero() public { + uint256[5] memory sequence = counter.getSequence(TEST_ID); + for(uint8 i = 0; i < 5; i++) { + assertEq(sequence[i], 0); + } + } + + function test_SetNumber() public { + counter.setNumber(TEST_ID, TEST_INDEX, 42); + uint256[5] memory sequence = counter.getSequence(TEST_ID); + assertEq(sequence[TEST_INDEX], 42); + } + + function test_Increment() public { + counter.increment(TEST_ID, TEST_INDEX); + uint256[5] memory sequence = counter.getSequence(TEST_ID); + assertEq(sequence[TEST_INDEX], 1); + } + + function test_MultipleIncrements() public { + for(uint8 i = 0; i < 5; i++) { + counter.increment(TEST_ID, TEST_INDEX); + } + uint256[5] memory sequence = counter.getSequence(TEST_ID); + assertEq(sequence[TEST_INDEX], 5); + } + + function test_IncrementMultipleIndices() public { + for(uint8 i = 0; i < 5; i++) { + counter.increment(TEST_ID, i); + } + uint256[5] memory sequence = counter.getSequence(TEST_ID); + for(uint8 i = 0; i < 5; i++) { + assertEq(sequence[i], 1); + } + } + + function test_MultipleSequences() public { + counter.increment(TEST_ID, 0); + counter.increment(TEST_ID_2, 0); + + uint256[5] memory sequence1 = counter.getSequence(TEST_ID); + uint256[5] memory sequence2 = counter.getSequence(TEST_ID_2); + + assertEq(sequence1[0], 1); + assertEq(sequence2[0], 1); + } + + function testFuzz_SetNumber(uint256 x) public { + vm.assume(x < type(uint256).max); + counter.setNumber(TEST_ID, TEST_INDEX, x); + uint256[5] memory sequence = counter.getSequence(TEST_ID); + assertEq(sequence[TEST_INDEX], x); + } + + function testFuzz_SetNumberMultipleIndices(uint8 index, uint256 value) public { + vm.assume(index < 5); + vm.assume(value < type(uint256).max); + counter.setNumber(TEST_ID, index, value); + uint256[5] memory sequence = counter.getSequence(TEST_ID); + assertEq(sequence[index], value); + } + + function test_RevertWhenIndexOutOfBounds() public { + vm.expectRevert("Index out of bounds"); + counter.setNumber(TEST_ID, 5, 1); + } + + function test_RevertWhenIncrementIndexOutOfBounds() public { + vm.expectRevert("Index out of bounds"); + counter.increment(TEST_ID, 5); + } + + function test_EventEmission() public { + vm.expectEmit(true, true, true, true); + emit Counter.NumberIncremented(TEST_ID, TEST_INDEX, 0, 1); + counter.increment(TEST_ID, TEST_INDEX); + } + + function test_SequenceIndependence() public { + counter.setNumber(TEST_ID, 0, 1); + counter.setNumber(TEST_ID, 1, 2); + counter.setNumber(TEST_ID, 2, 3); + + uint256[5] memory sequence = counter.getSequence(TEST_ID); + assertEq(sequence[0], 1); + assertEq(sequence[1], 2); + assertEq(sequence[2], 3); + assertEq(sequence[3], 0); + assertEq(sequence[4], 0); + } +} diff --git a/blueprints/examples/src/examples/mod.rs b/blueprints/examples/src/examples/mod.rs new file mode 100644 index 00000000..54d9a0a3 --- /dev/null +++ b/blueprints/examples/src/examples/mod.rs @@ -0,0 +1,2 @@ +pub mod periodic_web_poller; +pub mod raw_tangle_events; diff --git a/blueprints/periodic-web-poller/src/lib.rs b/blueprints/examples/src/examples/periodic_web_poller.rs similarity index 91% rename from blueprints/periodic-web-poller/src/lib.rs rename to blueprints/examples/src/examples/periodic_web_poller.rs index 4f6a4768..d68bf800 100644 --- a/blueprints/periodic-web-poller/src/lib.rs +++ b/blueprints/examples/src/examples/periodic_web_poller.rs @@ -1,13 +1,19 @@ -use async_trait::async_trait; +use gadget_sdk::async_trait::async_trait; use gadget_sdk::event_listener::periodic::PeriodicEventListener; use gadget_sdk::event_listener::EventListener; +use gadget_sdk::event_utils::InitializableEventHandler; use gadget_sdk::job; use std::convert::Infallible; +pub fn constructor() -> impl InitializableEventHandler { + WebPollerEventHandler { + client: reqwest::Client::new(), + } +} + #[job( id = 0, params(value), - event_listener( listener = PeriodicEventListener<2000, WebPoller, serde_json::Value, reqwest::Client>, pre_processor = pre_process, diff --git a/blueprints/examples/src/examples/raw_tangle_events.rs b/blueprints/examples/src/examples/raw_tangle_events.rs new file mode 100644 index 00000000..602ab8ee --- /dev/null +++ b/blueprints/examples/src/examples/raw_tangle_events.rs @@ -0,0 +1,45 @@ +use gadget_sdk::config::StdGadgetConfiguration; +use gadget_sdk::event_listener::tangle::{TangleEvent, TangleEventListener}; +use gadget_sdk::event_utils::InitializableEventHandler; +use gadget_sdk::job; +use gadget_sdk::tangle_subxt::tangle_testnet_runtime::api; + +#[derive(Clone)] +pub struct MyContext; + +pub async fn constructor( + env: StdGadgetConfiguration, +) -> color_eyre::Result { + use gadget_sdk::subxt_core::tx::signer::Signer; + + let client = env.client().await.map_err(|e| color_eyre::eyre::eyre!(e))?; + let signer = env + .first_sr25519_signer() + .map_err(|e| color_eyre::eyre::eyre!(e))?; + + gadget_sdk::info!("Starting the event watcher for {} ...", signer.account_id()); + Ok(RawEventHandler { + service_id: env.service_id().expect("No service ID found"), + context: MyContext, + client, + signer, + }) +} + +#[job( + id = 0, + event_listener( + listener = TangleEventListener, + ), +)] +pub fn raw(event: TangleEvent, context: MyContext) -> Result { + if let Some(balance_transfer) = event + .evt + .as_event::() + .ok() + .flatten() + { + gadget_sdk::info!("Found a balance transfer: {balance_transfer:?}"); + } + Ok(0) +} diff --git a/blueprints/examples/src/lib.rs b/blueprints/examples/src/lib.rs new file mode 100644 index 00000000..e837f5d9 --- /dev/null +++ b/blueprints/examples/src/lib.rs @@ -0,0 +1 @@ +pub mod examples; diff --git a/blueprints/examples/src/main.rs b/blueprints/examples/src/main.rs new file mode 100644 index 00000000..8dcde172 --- /dev/null +++ b/blueprints/examples/src/main.rs @@ -0,0 +1,17 @@ +use blueprint::examples::*; +use blueprint_examples as blueprint; +use gadget_sdk::info; +use gadget_sdk::runners::{tangle::TangleConfig, BlueprintRunner}; + +#[gadget_sdk::main(env)] +async fn main() { + info!("~~~ Executing the incredible squaring blueprint ~~~"); + BlueprintRunner::new(TangleConfig::default(), env.clone()) + .job(raw_tangle_events::constructor(env.clone()).await?) + .job(periodic_web_poller::constructor()) + .run() + .await?; + + info!("Exiting..."); + Ok(()) +} diff --git a/blueprints/incredible-squaring-eigenlayer/contracts/lib/forge-std b/blueprints/incredible-squaring-eigenlayer/contracts/lib/forge-std index 1de6eecf..1eea5bae 160000 --- a/blueprints/incredible-squaring-eigenlayer/contracts/lib/forge-std +++ b/blueprints/incredible-squaring-eigenlayer/contracts/lib/forge-std @@ -1 +1 @@ -Subproject commit 1de6eecf821de7fe2c908cc48d3ab3dced20717f +Subproject commit 1eea5bae12ae557d589f9f0f0edae2faa47cb262 diff --git a/blueprints/incredible-squaring-eigenlayer/src/contexts/aggregator.rs b/blueprints/incredible-squaring-eigenlayer/src/contexts/aggregator.rs index 40842e61..a9e489f9 100644 --- a/blueprints/incredible-squaring-eigenlayer/src/contexts/aggregator.rs +++ b/blueprints/incredible-squaring-eigenlayer/src/contexts/aggregator.rs @@ -60,7 +60,6 @@ impl AggregatorContext { pub async fn new( port_address: String, task_manager_address: Address, - http_rpc_url: String, wallet: EthereumWallet, sdk_config: StdGadgetConfiguration, ) -> Result { @@ -70,7 +69,7 @@ impl AggregatorContext { tasks: Arc::new(Mutex::new(HashMap::new())), tasks_responses: Arc::new(Mutex::new(HashMap::new())), bls_aggregation_service: None, - http_rpc_url, + http_rpc_url: sdk_config.http_rpc_endpoint.clone(), wallet, response_cache: Arc::new(Mutex::new(VecDeque::new())), sdk_config, diff --git a/blueprints/incredible-squaring-eigenlayer/src/contexts/client.rs b/blueprints/incredible-squaring-eigenlayer/src/contexts/client.rs index 178dd492..b4e73d64 100644 --- a/blueprints/incredible-squaring-eigenlayer/src/contexts/client.rs +++ b/blueprints/incredible-squaring-eigenlayer/src/contexts/client.rs @@ -19,7 +19,7 @@ pub struct SignedTaskResponse { pub operator_id: OperatorId, } -/// Client for interacting with the Aggregator RPC +/// Client for interacting with the Aggregator RPC server #[derive(Debug, Clone)] pub struct AggregatorClient { client: ReqwestClient, diff --git a/blueprints/incredible-squaring-eigenlayer/src/contexts/x_square.rs b/blueprints/incredible-squaring-eigenlayer/src/contexts/x_square.rs index dfec91e3..0011574b 100644 --- a/blueprints/incredible-squaring-eigenlayer/src/contexts/x_square.rs +++ b/blueprints/incredible-squaring-eigenlayer/src/contexts/x_square.rs @@ -1,9 +1,9 @@ use crate::contexts::client::AggregatorClient; -use gadget_sdk::config::GadgetConfiguration; -use parking_lot::RawRwLock; +use gadget_sdk::{config::StdGadgetConfiguration, ctx::KeystoreContext}; -#[derive(Clone)] +#[derive(Clone, KeystoreContext)] pub struct EigenSquareContext { pub client: AggregatorClient, - pub env: GadgetConfiguration, + #[config] + pub std_config: StdGadgetConfiguration, } diff --git a/blueprints/incredible-squaring-eigenlayer/src/jobs/compute_x_square.rs b/blueprints/incredible-squaring-eigenlayer/src/jobs/compute_x_square.rs index afc38617..d4b57b53 100644 --- a/blueprints/incredible-squaring-eigenlayer/src/jobs/compute_x_square.rs +++ b/blueprints/incredible-squaring-eigenlayer/src/jobs/compute_x_square.rs @@ -5,18 +5,22 @@ use crate::{IncredibleSquaringTaskManager, INCREDIBLE_SQUARING_TASK_MANAGER_ABI_ use alloy_primitives::keccak256; use alloy_primitives::{Bytes, U256}; use alloy_sol_types::SolType; -use ark_bn254::Fq; -use ark_ff::{BigInteger, PrimeField}; use color_eyre::Result; use eigensdk::crypto_bls::BlsKeyPair; use eigensdk::crypto_bls::OperatorId; +use gadget_sdk::ctx::KeystoreContext; use gadget_sdk::event_listener::evm::contracts::EvmContractEventListener; use gadget_sdk::keystore::BackendExt; use gadget_sdk::{error, info, job}; use std::{convert::Infallible, ops::Deref}; use IncredibleSquaringTaskManager::TaskResponse; -/// Returns x^2 saturating to [`u64::MAX`] if overflow occurs. +/// Sends a signed task response to the BLS Aggregator. +/// +/// This job is triggered by the `NewTaskCreated` event emitted by the `IncredibleSquaringTaskManager`. +/// The job calculates the square of the number to be squared and sends the signed task response to the BLS Aggregator. +/// The job returns 1 if the task response was sent successfully. +/// The job returns 0 if the task response failed to send or failed to get the BLS key. #[job( id = 0, params(number_to_be_squared, task_created_block, quorum_numbers, quorum_threshold_percentage, task_index), @@ -36,7 +40,6 @@ pub async fn xsquare_eigen( task_index: u32, ) -> std::result::Result { let client = ctx.client.clone(); - let env = ctx.env.clone(); // Calculate our response to job let task_response = TaskResponse { @@ -44,23 +47,13 @@ pub async fn xsquare_eigen( numberSquared: number_to_be_squared.saturating_pow(U256::from(2u32)), }; - let bls_key_pair = match env.keystore() { - Ok(keystore) => { - let pair = keystore.bls_bn254_key(); - match pair { - Ok(pair) => pair, - Err(e) => { - error!("Failed to get BLS key pair: {:#?}", e); - return Ok(1); - } - } - } - Err(e) => { - error!("Failed to get keystore: {:#?}", e); - return Ok(1); - } + let bls_key_pair = match ctx.keystore().map(|ks| ks.bls_bn254_key()) { + Ok(kp) => match kp { + Ok(k) => k, + Err(e) => return Ok(0), + }, + Err(e) => return Ok(0), }; - let operator_id: OperatorId = operator_id_from_key(bls_key_pair.clone()); // Sign the Hashed Message and send it to the BLS Aggregator @@ -121,11 +114,3 @@ pub async fn convert_event_to_inputs( task_index, )) } - -/// Helper for converting a PrimeField to its U256 representation for Ethereum compatibility -/// (U256 reads data as big endian) -pub fn point_to_u256(point: Fq) -> U256 { - let point = point.into_bigint(); - let point_bytes = point.to_bytes_be(); - U256::from_be_slice(&point_bytes[..]) -} diff --git a/blueprints/incredible-squaring-eigenlayer/src/main.rs b/blueprints/incredible-squaring-eigenlayer/src/main.rs index 3e07fa7d..9f249d75 100644 --- a/blueprints/incredible-squaring-eigenlayer/src/main.rs +++ b/blueprints/incredible-squaring-eigenlayer/src/main.rs @@ -18,72 +18,36 @@ use incredible_squaring_blueprint_eigenlayer::{ #[gadget_sdk::main(env)] async fn main() { - // Get the ECDSA key from the private key seed using alloy let signer: PrivateKeySigner = AGGREGATOR_PRIVATE_KEY .parse() .expect("failed to generate wallet "); let wallet = EthereumWallet::from(signer); let provider = get_wallet_provider_http(&env.http_rpc_endpoint, wallet.clone()); - info!("Task Manager Address: {:?}", *TASK_MANAGER_ADDRESS); + let server_address = format!("{}:{}", env.target_addr, 8081); + let eigen_client_context = EigenSquareContext { + client: AggregatorClient::new(&server_address)?, + std_config: env.clone(), + }; + let aggregator_context = + AggregatorContext::new(server_address, *TASK_MANAGER_ADDRESS, wallet, env.clone()) + .await + .unwrap(); + let contract = IncredibleSquaringTaskManager::IncredibleSquaringTaskManagerInstance::new( *TASK_MANAGER_ADDRESS, provider, ); - info!("Protocol: Eigenlayer"); - info!( - "Registry Coordinator Address: {:?}", - env.protocol_specific - .eigenlayer()? - .registry_coordinator_address - ); - info!( - "Operator State Retriever Address: {:?}", - env.protocol_specific - .eigenlayer()? - .operator_state_retriever_address - ); - info!( - "Delegation Manager Address: {:?}", - env.protocol_specific - .eigenlayer()? - .delegation_manager_address - ); - info!( - "Strategy Manager Address: {:?}", - env.protocol_specific.eigenlayer()?.strategy_manager_address - ); - info!( - "AVS Directory Address: {:?}", - env.protocol_specific.eigenlayer()?.avs_directory_address - ); - - let server_address = format!("{}:{}", env.target_addr, 8081); - let aggregator_client = AggregatorClient::new(&server_address)?; - let ctx = EigenSquareContext { - client: aggregator_client, - env: env.clone(), - }; - let x_square_eigen = XsquareEigenEventHandler { - ctx, + let initialize_task = InitializeBlsTaskEventHandler { + ctx: aggregator_context.clone(), contract: contract.clone(), contract_instance: Default::default(), }; - let aggregator_context = AggregatorContext::new( - server_address, - *TASK_MANAGER_ADDRESS, - env.http_rpc_endpoint.clone(), - wallet, - env.clone(), - ) - .await - .unwrap(); - - let initialize_task = InitializeBlsTaskEventHandler { - ctx: aggregator_context.clone(), - contract, + let x_square_eigen = XsquareEigenEventHandler { + ctx: eigen_client_context, + contract: contract.clone(), contract_instance: Default::default(), }; diff --git a/blueprints/incredible-squaring-symbiotic/src/main.rs b/blueprints/incredible-squaring-symbiotic/src/main.rs index cf633f16..4eaf10e7 100644 --- a/blueprints/incredible-squaring-symbiotic/src/main.rs +++ b/blueprints/incredible-squaring-symbiotic/src/main.rs @@ -19,10 +19,8 @@ lazy_static! { #[gadget_sdk::main(env)] async fn main() { - // Get the ECDSA key from the private key seed using alloy let operator_signer = env.keystore()?.ecdsa_key()?.alloy_key()?; let wallet = EthereumWallet::new(operator_signer); - let provider = get_wallet_provider_http(&env.http_rpc_endpoint, wallet); let contract = IncredibleSquaringTaskManager::IncredibleSquaringTaskManagerInstance::new( @@ -30,11 +28,7 @@ async fn main() { provider, ); - let x_square = blueprint::XsquareEventHandler { - context: blueprint::MyContext {}, - contract: contract.clone(), - contract_instance: Default::default(), - }; + let x_square = blueprint::XsquareEventHandler::new(contract, blueprint::MyContext {}); info!("~~~ Executing the incredible squaring blueprint ~~~"); let symb_config = SymbioticConfig::default(); diff --git a/blueprints/incredible-squaring/contracts/lib/forge-std b/blueprints/incredible-squaring/contracts/lib/forge-std index 1de6eecf..1eea5bae 160000 --- a/blueprints/incredible-squaring/contracts/lib/forge-std +++ b/blueprints/incredible-squaring/contracts/lib/forge-std @@ -1 +1 @@ -Subproject commit 1de6eecf821de7fe2c908cc48d3ab3dced20717f +Subproject commit 1eea5bae12ae557d589f9f0f0edae2faa47cb262 diff --git a/blueprints/incredible-squaring/contracts/src/IncredibleSquaringBlueprint.sol b/blueprints/incredible-squaring/contracts/src/IncredibleSquaringBlueprint.sol index 70071701..687a7d7a 100644 --- a/blueprints/incredible-squaring/contracts/src/IncredibleSquaringBlueprint.sol +++ b/blueprints/incredible-squaring/contracts/src/IncredibleSquaringBlueprint.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.19; import "tnt-core/BlueprintServiceManagerBase.sol"; +import "incredible-squaring/IncredibleSquaringInstance.sol"; /** * @title IncredibleSquaringBlueprint @@ -9,7 +10,6 @@ import "tnt-core/BlueprintServiceManagerBase.sol"; * service to square a number. It demonstrates the lifecycle hooks that can be * implemented in a service blueprint. */ - contract IncredibleSquaringBlueprint is BlueprintServiceManagerBase { /** * @dev A mapping of all service operators registered with the blueprint. @@ -20,45 +20,24 @@ contract IncredibleSquaringBlueprint is BlueprintServiceManagerBase { * @dev A mapping of all service instances requested from the blueprint. * The key is the service ID and the value is the service operator's address. */ - mapping(uint64 => address[]) public serviceInstances; - + mapping(uint64 => address) public serviceInstances; /** - * @dev Hook for handling job call results. Called when operators send the result - * of a job execution. - * @param serviceId The ID of the service related to the job. - * @param job The job identifier. - * @param _jobCallId The unique ID for the job call. - * @param participant The participant (operator) sending the result. - * @param _inputs Inputs used for the job execution. - * @param _outputs Outputs resulting from the job execution. + * @dev Hook for service instance requests. Called when a user requests a service + * instance from the blueprint. + * @param serviceId The ID of the requested service. + * @param operatorsOfService The operators involved in the service in bytes array format. + * @param requestInputs Inputs required for the service request in bytes format. */ - function onJobResult( - uint64 serviceId, - uint8 job, - uint64 _jobCallId, - bytes calldata participant, - bytes calldata _inputs, - bytes calldata _outputs - ) public virtual payable override onlyFromRootChain { -/* // check that we have this service instance - require( - serviceInstances[serviceId].length > 0, - "Service instance not found" - ); - // check if job is zero. - require(job == 0, "Job not found"); - // Check if the participant is a registered operator - address operatorAddress = address(bytes20(keccak256(participant))); - require( - operators[operatorAddress].length > 0, - "Operator not registered" - ); - // Check if operator is part of the service instance - require( - isOperatorInServiceInstance(serviceId, operatorAddress), - "Operator not part of service instance" - );*/ + function onRequest(uint64 serviceId, bytes[] calldata operatorsOfService, bytes calldata requestInputs) + public + payable + virtual + override + onlyFromRootChain + { + IncredibleSquaringInstance deployed = new IncredibleSquaringInstance(serviceId); + serviceInstances[serviceId] = address(deployed); } /** @@ -70,28 +49,20 @@ contract IncredibleSquaringBlueprint is BlueprintServiceManagerBase { * @param participant The participant (operator) whose result is being verified. * @param inputs Inputs used for the job execution. * @param outputs Outputs resulting from the job execution. - * @return bool Returns true if the job call result is verified successfully, - * otherwise false. */ - function verifyJobCallResult( + function onJobResult( uint64 serviceId, uint8 job, uint64 jobCallId, bytes calldata participant, bytes calldata inputs, bytes calldata outputs - ) public pure returns (bool) { - // Someone requested to verify the result of a job call. - // We need to check if the output is the square of the input. - + ) public payable override { // Decode the inputs and outputs uint256 input = abi.decode(inputs, (uint256)); uint256 output = abi.decode(outputs, (uint256)); // Check if the output is the square of the input bool isValid = output == input * input; require(isValid, "Invalid result"); - - return true; } } - diff --git a/blueprints/incredible-squaring/contracts/src/IncredibleSquaringInstance.sol b/blueprints/incredible-squaring/contracts/src/IncredibleSquaringInstance.sol new file mode 100644 index 00000000..6f6b4184 --- /dev/null +++ b/blueprints/incredible-squaring/contracts/src/IncredibleSquaringInstance.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.20; + +/** + * @title IncredibleSquaringInstance + * @dev This contract represents an instance of the IncredibleSquaring service. + * It is deployed when a user requests a new service instance and handles the + * actual squaring computation. + */ +contract IncredibleSquaringInstance { + // Address of the blueprint that created this instance + address public immutable blueprint; + + // Service ID assigned by the root chain + uint64 public immutable serviceId; + + constructor(uint64 _serviceId) { + blueprint = msg.sender; + serviceId = _serviceId; + } +} diff --git a/blueprints/incredible-squaring/src/main.rs b/blueprints/incredible-squaring/src/main.rs index a252bd77..aefa4287 100644 --- a/blueprints/incredible-squaring/src/main.rs +++ b/blueprints/incredible-squaring/src/main.rs @@ -1,4 +1,4 @@ -use color_eyre::{eyre::eyre, Result}; +use color_eyre::Result; use gadget_sdk::info; use gadget_sdk::runners::tangle::TangleConfig; use gadget_sdk::runners::BlueprintRunner; @@ -7,17 +7,12 @@ use incredible_squaring_blueprint as blueprint; #[gadget_sdk::main(env)] async fn main() { - let client = env.client().await.map_err(|e| eyre!(e))?; - let signer = env.first_sr25519_signer().map_err(|e| eyre!(e))?; + let x_square = blueprint::XsquareEventHandler::new(&env, blueprint::MyContext).await?; - info!("Starting the event watcher for {} ...", signer.account_id()); - - let x_square = blueprint::XsquareEventHandler { - service_id: env.service_id().expect("No service ID found"), - context: blueprint::MyContext, - client, - signer, - }; + info!( + "Starting the event watcher for {} ...", + x_square.signer.account_id() + ); info!("~~~ Executing the incredible squaring blueprint ~~~"); let tangle_config = TangleConfig::default(); diff --git a/blueprints/periodic-web-poller/Cargo.toml b/blueprints/periodic-web-poller/Cargo.toml deleted file mode 100644 index b83aef24..00000000 --- a/blueprints/periodic-web-poller/Cargo.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "periodic-web-poller-blueprint" -version = "0.1.1" -description = "A Simple Blueprint to demo how to run blueprints dependent on an arbitrary events" -authors.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true -publish = false - -[dependencies] -tracing = { workspace = true } -async-trait = { workspace = true } -gadget-sdk = { workspace = true, features = ["std"] } -color-eyre = { workspace = true } -lock_api = { workspace = true } -tokio = { workspace = true, default-features = false, features = ["full"] } -tokio-util = { workspace = true } -sp-core = { workspace = true } -subxt-signer = { workspace = true, features = ["sr25519", "subxt", "std"] } -parking_lot = { workspace = true } -ed25519-zebra = { workspace = true, features = ["pkcs8", "default", "der", "std", "serde", "pem"] } -hex = { workspace = true } -k256 = { workspace = true } -serde_json = { workspace = true } -reqwest = { workspace = true } - -[build-dependencies] -blueprint-metadata = { workspace = true } - -[features] -default = ["std"] -std = [] diff --git a/blueprints/periodic-web-poller/build.rs b/blueprints/periodic-web-poller/build.rs deleted file mode 100644 index ebfbe1a3..00000000 --- a/blueprints/periodic-web-poller/build.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=src/*"); - println!("cargo:rerun-if-changed=src/lib.rs"); - println!("cargo:rerun-if-changed=src/main.rs"); - blueprint_metadata::generate_json(); -} diff --git a/blueprints/periodic-web-poller/src/main.rs b/blueprints/periodic-web-poller/src/main.rs deleted file mode 100644 index b24a7e1a..00000000 --- a/blueprints/periodic-web-poller/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -use color_eyre::Result; -use gadget_sdk::info; -use gadget_sdk::runners::BlueprintRunner; -use periodic_web_poller_blueprint as blueprint; - -#[gadget_sdk::main(env)] -async fn main() { - let web_poller = blueprint::WebPollerEventHandler { - client: reqwest::Client::new(), - }; - - info!("~~~ Executing the periodic web poller ~~~"); - BlueprintRunner::new((), env).job(web_poller).run().await?; - - info!("Exiting..."); - Ok(()) -} diff --git a/blueprints/tangle-raw-event-listener/Cargo.toml b/blueprints/tangle-raw-event-listener/Cargo.toml deleted file mode 100644 index f02ba81d..00000000 --- a/blueprints/tangle-raw-event-listener/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "tangle-raw-event-listener-blueprint" -version = "0.1.1" -description = "A Simple Blueprint to demo how to listen to raw events from Tangle" -authors.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true -publish = false - -[dependencies] -gadget-sdk = { workspace = true, features = ["std"] } -color-eyre = { workspace = true } -tracing = { workspace = true } - -[build-dependencies] -blueprint-metadata = { workspace = true } - -[features] -default = ["std"] -std = [] diff --git a/blueprints/tangle-raw-event-listener/src/lib.rs b/blueprints/tangle-raw-event-listener/src/lib.rs deleted file mode 100644 index 1ee1ee64..00000000 --- a/blueprints/tangle-raw-event-listener/src/lib.rs +++ /dev/null @@ -1,24 +0,0 @@ -use gadget_sdk::event_listener::tangle::{TangleEvent, TangleEventListener}; -use gadget_sdk::job; -use gadget_sdk::tangle_subxt::tangle_testnet_runtime::api; - -#[derive(Clone)] -pub struct MyContext; - -#[job( - id = 0, - event_listener( - listener = TangleEventListener, - ), -)] -pub fn raw(event: TangleEvent, context: MyContext) -> Result { - if let Some(balance_transfer) = event - .evt - .as_event::() - .ok() - .flatten() - { - gadget_sdk::info!("Found a balance transfer: {balance_transfer:?}"); - } - Ok(0) -} diff --git a/blueprints/tangle-raw-event-listener/src/main.rs b/blueprints/tangle-raw-event-listener/src/main.rs index 16b74e63..ebf72897 100644 --- a/blueprints/tangle-raw-event-listener/src/main.rs +++ b/blueprints/tangle-raw-event-listener/src/main.rs @@ -1,4 +1,4 @@ -use color_eyre::{eyre::eyre, Result}; +use color_eyre::Result; use gadget_sdk::info; use gadget_sdk::runners::{tangle::TangleConfig, BlueprintRunner}; use gadget_sdk::tangle_subxt::subxt::tx::Signer; @@ -6,21 +6,13 @@ use tangle_raw_event_listener_blueprint as blueprint; #[gadget_sdk::main(env)] async fn main() { - let client = env.client().await.map_err(|e| eyre!(e))?; - let signer = env.first_sr25519_signer().map_err(|e| eyre!(e))?; - - info!("Starting the event watcher for {} ...", signer.account_id()); - - let x_square = blueprint::RawEventHandler { - service_id: env.service_id().expect("No service ID found"), - context: blueprint::MyContext, - client, - signer, - }; - + let x_square = blueprint::RawEventHandler::new(&env, blueprint::MyContext).await?; let tangle_config = TangleConfig::default(); - info!("~~~ Executing the incredible squaring blueprint ~~~"); + info!( + "~~~ Executing the incredible squaring blueprint for {:?} ~~~", + x_square.signer.address() + ); BlueprintRunner::new(tangle_config, env) .job(x_square) .run() diff --git a/blueprints/tangle-raw/Cargo.toml b/blueprints/tangle-raw/Cargo.toml deleted file mode 100644 index 6cbb694e..00000000 --- a/blueprints/tangle-raw/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "tangle-raw-blueprint" -version = "0.1.1" -description = "A Simple Blueprint to demo how to listen to raw events from Tangle" -authors.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true -publish = false - -[dependencies] -gadget-sdk = { workspace = true, features = ["std"] } -color-eyre = { workspace = true } -tracing = { workspace = true } - -[build-dependencies] -blueprint-metadata = { workspace = true } - -[features] -default = ["std"] -std = [] \ No newline at end of file diff --git a/blueprints/tangle-raw/build.rs b/blueprints/tangle-raw/build.rs deleted file mode 100644 index acb638b3..00000000 --- a/blueprints/tangle-raw/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=src/lib.rs"); - println!("cargo:rerun-if-changed=src/main.rs"); - blueprint_metadata::generate_json(); -} diff --git a/blueprints/tangle-raw/src/lib.rs b/blueprints/tangle-raw/src/lib.rs deleted file mode 100644 index 1ee1ee64..00000000 --- a/blueprints/tangle-raw/src/lib.rs +++ /dev/null @@ -1,24 +0,0 @@ -use gadget_sdk::event_listener::tangle::{TangleEvent, TangleEventListener}; -use gadget_sdk::job; -use gadget_sdk::tangle_subxt::tangle_testnet_runtime::api; - -#[derive(Clone)] -pub struct MyContext; - -#[job( - id = 0, - event_listener( - listener = TangleEventListener, - ), -)] -pub fn raw(event: TangleEvent, context: MyContext) -> Result { - if let Some(balance_transfer) = event - .evt - .as_event::() - .ok() - .flatten() - { - gadget_sdk::info!("Found a balance transfer: {balance_transfer:?}"); - } - Ok(0) -} diff --git a/blueprints/tangle-raw/src/main.rs b/blueprints/tangle-raw/src/main.rs deleted file mode 100644 index 85869285..00000000 --- a/blueprints/tangle-raw/src/main.rs +++ /dev/null @@ -1,37 +0,0 @@ -use color_eyre::{eyre::eyre, Result}; -use gadget_sdk::config::protocol::TangleInstanceSettings; -use gadget_sdk::info; -use gadget_sdk::runners::tangle::TangleConfig; -use gadget_sdk::runners::BlueprintRunner; -use gadget_sdk::tangle_subxt::subxt::tx::Signer; -use tangle_raw_blueprint as blueprint; - -#[gadget_sdk::main(env)] -async fn main() { - let client = env.client().await.map_err(|e| eyre!(e))?; - let signer = env.first_sr25519_signer().map_err(|e| eyre!(e))?; - let tangle_config = TangleConfig { - price_targets: Default::default(), - }; - - info!("Starting the event watcher for {} ...", signer.account_id()); - - let tangle_settings = env.protocol_specific.tangle()?; - let TangleInstanceSettings { service_id, .. } = tangle_settings; - - let x_square = blueprint::RawEventHandler { - service_id: *service_id, - context: blueprint::MyContext, - client, - signer, - }; - - info!("~~~ Executing the incredible squaring blueprint ~~~"); - BlueprintRunner::new(tangle_config, env) - .job(x_square) - .run() - .await?; - - info!("Exiting..."); - Ok(()) -} diff --git a/macros/blueprint-proc-macro/src/event_listener/tangle.rs b/macros/blueprint-proc-macro/src/event_listener/tangle.rs deleted file mode 100644 index 8196ef70..00000000 --- a/macros/blueprint-proc-macro/src/event_listener/tangle.rs +++ /dev/null @@ -1,51 +0,0 @@ -use crate::job::{declared_params_to_field_types, EventListenerArgs}; -use indexmap::IndexMap; -use proc_macro2::TokenStream; -use quote::quote; -use syn::{Ident, Type}; - -#[allow(clippy::too_many_arguments)] -pub(crate) fn generate_additional_tangle_logic(struct_name: &Ident) -> TokenStream { - quote! { - #[automatically_derived] - impl gadget_sdk::event_listener::markers::IsTangle for #struct_name {} - } -} - -pub(crate) fn get_tangle_job_processor_wrapper( - params: &[Ident], - param_types: &IndexMap, - event_listeners: &EventListenerArgs, - ordered_inputs: &mut Vec, - fn_name_ident: &Ident, - call_id_static_name: &Ident, - asyncness: &TokenStream, -) -> TokenStream { - let params = - declared_params_to_field_types(params, param_types).expect("Failed to generate params"); - let params_tokens = event_listeners.get_param_name_tokenstream(¶ms, true); - - let job_processor_call = if params_tokens.is_empty() { - let second_param = ordered_inputs.pop().expect("Expected a context"); - quote! { - // If no args are specified, assume this job has no parameters and thus takes in the raw event - #fn_name_ident (param0, #second_param) #asyncness .map_err(|err| gadget_sdk::Error::Other(err.to_string())) - } - } else { - quote! { - let mut args_iter = param0.args.clone().into_iter(); - #(#params_tokens)* - #fn_name_ident (#(#ordered_inputs)*) #asyncness .map_err(|err| gadget_sdk::Error::Other(err.to_string())) - } - }; - - quote! { - move |param0: gadget_sdk::event_listener::tangle::TangleEvent<_, _>| async move { - if let Some(call_id) = param0.call_id { - #call_id_static_name.store(call_id, std::sync::atomic::Ordering::Relaxed); - } - - #job_processor_call - } - } -} diff --git a/macros/blueprint-proc-macro/src/job.rs b/macros/blueprint-proc-macro/src/job.rs index 3c8d59e4..429dbe85 100644 --- a/macros/blueprint-proc-macro/src/job.rs +++ b/macros/blueprint-proc-macro/src/job.rs @@ -1,10 +1,10 @@ -use crate::event_listener::evm::{ - generate_evm_event_handler, get_evm_instance_data, get_evm_job_processor_wrapper, +use crate::shared::{pascal_case, type_to_field_type}; +use crate::special_impls::evm::{ + generate_evm_specific_impl, get_evm_instance_data, get_evm_job_processor_wrapper, }; -use crate::event_listener::tangle::{ - generate_additional_tangle_logic, get_tangle_job_processor_wrapper, +use crate::special_impls::tangle::{ + generate_tangle_specific_impl, get_tangle_job_processor_wrapper, }; -use crate::shared::{pascal_case, type_to_field_type}; use gadget_blueprint_proc_macro_core::{FieldType, JobDefinition, JobMetadata}; use indexmap::{IndexMap, IndexSet}; use proc_macro::TokenStream; @@ -77,7 +77,13 @@ pub(crate) fn job_impl(args: &JobArgs, input: &ItemFn) -> syn::Result proc_macro2::TokenStream { #[allow(clippy::too_many_lines)] pub fn generate_additional_logic( input: &ItemFn, - job_args: &JobArgs, + event_listener_args: &EventListenerArgs, suffix: &str, + param_map: &IndexMap, + job_params: &[Ident], ) -> proc_macro2::TokenStream { let (_fn_name, _fn_name_string, struct_name) = generate_fn_name_and_struct(input, suffix); - let event_listener_args = &job_args.event_listener; - match job_args.event_listener.get_event_listener().listener_type { - ListenerType::Evm => generate_evm_event_handler(&struct_name, event_listener_args), + match event_listener_args.get_event_listener().listener_type { + ListenerType::Evm => { + generate_evm_specific_impl(&struct_name, event_listener_args, param_map, job_params) + } - ListenerType::Tangle => generate_additional_tangle_logic(&struct_name), + ListenerType::Tangle => { + generate_tangle_specific_impl(&struct_name, param_map, job_params, event_listener_args) + } ListenerType::Custom => proc_macro2::TokenStream::default(), } @@ -1014,7 +1025,11 @@ impl EventListenerArgs { let index = Index::from(i); match self.get_event_listener().listener_type { ListenerType::Tangle => { - crate::tangle::field_type_to_param_token(&ident, t, panic_on_decode_fail) + crate::special_impls::tangle::field_type_to_param_token( + &ident, + t, + panic_on_decode_fail, + ) } ListenerType::Evm => { quote! { diff --git a/macros/blueprint-proc-macro/src/lib.rs b/macros/blueprint-proc-macro/src/lib.rs index 64a56a96..6cf373a7 100644 --- a/macros/blueprint-proc-macro/src/lib.rs +++ b/macros/blueprint-proc-macro/src/lib.rs @@ -26,10 +26,7 @@ mod report; /// Shared utilities for the Blueprint Macros mod shared; -mod event_listener; - -/// Utilities for Tangle Blueprint macro generation -mod tangle; +mod special_impls; mod sdk_main; diff --git a/macros/blueprint-proc-macro/src/report.rs b/macros/blueprint-proc-macro/src/report.rs index 0f9ed4ed..e88c630b 100644 --- a/macros/blueprint-proc-macro/src/report.rs +++ b/macros/blueprint-proc-macro/src/report.rs @@ -1,6 +1,7 @@ use crate::job::{ - declared_params_to_field_types, generate_autogen_struct, get_current_call_id_field_name, - get_job_id_field_name, get_result_type, EventListenerArgs, ResultsKind, + declared_params_to_field_types, generate_additional_logic, generate_autogen_struct, + get_current_call_id_field_name, get_job_id_field_name, get_result_type, EventListenerArgs, + ResultsKind, }; use crate::shared::{pascal_case, type_to_field_type}; use gadget_blueprint_proc_macro_core::{ @@ -131,15 +132,20 @@ pub(crate) fn report_impl(args: &ReportArgs, input: &ItemFn) -> syn::Result syn::Result syn::Result { } } -#[allow(dead_code)] -pub fn parse_struct_fields(fields: &syn::Fields) -> syn::Result> { - fields - .iter() - .map(|field| { - let name = field - .ident - .as_ref() - .ok_or_else(|| syn::Error::new_spanned(field, "Unnamed fields are not supported"))? - .to_string(); - let field_type = type_to_field_type(&field.ty)?; - Ok((name, field_type)) - }) - .collect() +/// Returns the set of arguments which are not job-related arguments. These typically go into the +/// autogenerated job struct +pub fn get_non_job_arguments( + param_map: &IndexMap, + job_params: &[Ident], +) -> IndexMap { + param_map + .clone() + .into_iter() + .filter(|r| !job_params.contains(&r.0)) + .collect::>() } #[cfg(test)] diff --git a/macros/blueprint-proc-macro/src/event_listener/evm.rs b/macros/blueprint-proc-macro/src/special_impls/evm.rs similarity index 71% rename from macros/blueprint-proc-macro/src/event_listener/evm.rs rename to macros/blueprint-proc-macro/src/special_impls/evm.rs index 59ce68f0..0e3eb153 100644 --- a/macros/blueprint-proc-macro/src/event_listener/evm.rs +++ b/macros/blueprint-proc-macro/src/special_impls/evm.rs @@ -4,6 +4,7 @@ use quote::{format_ident, quote}; use syn::{Ident, Type}; use crate::job::{declared_params_to_field_types, EventListenerArgs}; +use crate::shared::get_non_job_arguments; pub(crate) fn get_evm_instance_data( event_handler: &EventListenerArgs, @@ -21,18 +22,59 @@ pub(crate) fn get_evm_instance_data( ) } -pub(crate) fn generate_evm_event_handler( +pub(crate) fn generate_evm_specific_impl( struct_name: &Ident, - event_handler: &EventListenerArgs, + event_listener_args: &EventListenerArgs, + param_map: &IndexMap, + job_params: &[Ident], ) -> TokenStream { - let abi_string = event_handler + let abi_string = event_listener_args .get_event_listener() .evm_args .as_ref() .and_then(|r| r.abi.clone()) .expect("ABI String must exist"); + let non_job_param_map = get_non_job_arguments(param_map, job_params); + let mut new_function_signature = vec![]; + let mut constructor_args = vec![]; + + let (_, _, _, instance_name) = get_evm_instance_data(event_listener_args); + + // Push in the contract + new_function_signature.push(quote! { + contract: #instance_name, + }); + constructor_args.push(quote! { + contract, + contract_instance: Default::default(), + }); + + for (field_name, ty) in non_job_param_map { + new_function_signature.push(quote! { + #field_name: #ty, + }); + constructor_args.push(quote! { + #field_name, + }) + } + + let struct_name_as_literal = struct_name.to_string(); + quote! { + impl #struct_name { + /// Create a new + #[doc = "[`"] + #[doc = #struct_name_as_literal] + #[doc = "`]"] + /// instance + pub fn new(#(#new_function_signature)*) -> Self { + Self { + #(#constructor_args)* + } + } + } + impl Deref for #struct_name { type Target = gadget_sdk::event_listener::evm::contracts::AlloyContractInstance; diff --git a/macros/blueprint-proc-macro/src/event_listener/mod.rs b/macros/blueprint-proc-macro/src/special_impls/mod.rs similarity index 100% rename from macros/blueprint-proc-macro/src/event_listener/mod.rs rename to macros/blueprint-proc-macro/src/special_impls/mod.rs diff --git a/macros/blueprint-proc-macro/src/tangle/mod.rs b/macros/blueprint-proc-macro/src/special_impls/tangle.rs similarity index 67% rename from macros/blueprint-proc-macro/src/tangle/mod.rs rename to macros/blueprint-proc-macro/src/special_impls/tangle.rs index 77e96337..88f37704 100644 --- a/macros/blueprint-proc-macro/src/tangle/mod.rs +++ b/macros/blueprint-proc-macro/src/special_impls/tangle.rs @@ -1,13 +1,122 @@ +use crate::job::{declared_params_to_field_types, EventListenerArgs}; +use crate::shared::get_non_job_arguments; use gadget_blueprint_proc_macro_core::FieldType; +use indexmap::IndexMap; +use proc_macro2::TokenStream; use quote::{format_ident, quote}; -use syn::Ident; +use syn::{Ident, Type}; + +#[allow(clippy::too_many_arguments)] +pub(crate) fn generate_tangle_specific_impl( + struct_name: &Ident, + param_map: &IndexMap, + job_params: &[Ident], + event_listener_args: &EventListenerArgs, +) -> TokenStream { + let mut non_job_param_map = get_non_job_arguments(param_map, job_params); + let mut new_function_signature = vec![]; + let mut constructor_args = vec![]; + + if event_listener_args.get_event_listener().is_raw() { + // TODO: task 001: find better way to identify which ident is the raw event + // remove the 0th element + let _ = non_job_param_map.shift_remove_index(0); + } + + // Push the expected types + new_function_signature.push(quote! { + env: &gadget_sdk::config::gadget_config::GadgetConfiguration, + }); + + constructor_args.push(quote! { + client, + signer, + service_id, + }); + + for (param_name, param_type) in non_job_param_map { + new_function_signature.push(quote! { + #param_name: #param_type, + }); + + constructor_args.push(quote! { + #param_name, + }); + } + + let struct_name_as_literal = struct_name.to_string(); + + quote! { + impl #struct_name { + /// Create a new + #[doc = "[`"] + #[doc = #struct_name_as_literal] + #[doc = "`]"] + /// instance + /// # Errors + /// + /// - `gadget_sdk::Error`: if the client fails to connect, the signer is not found, or + /// the service ID is not found. + pub async fn new(#(#new_function_signature)*) -> Result { + let client = env.client().await?; + let signer = env.first_sr25519_signer()?; + let service_id = env.service_id().ok_or_else(|| gadget_sdk::Error::Other("No service ID found in ENV".to_string()))?; + + Ok(Self { + #(#constructor_args)* + }) + } + } + + #[automatically_derived] + impl gadget_sdk::event_listener::markers::IsTangle for #struct_name {} + } +} + +pub(crate) fn get_tangle_job_processor_wrapper( + job_params: &[Ident], + param_map: &IndexMap, + event_listeners: &EventListenerArgs, + ordered_inputs: &mut Vec, + fn_name_ident: &Ident, + call_id_static_name: &Ident, + asyncness: &TokenStream, +) -> TokenStream { + let params = + declared_params_to_field_types(job_params, param_map).expect("Failed to generate params"); + let params_tokens = event_listeners.get_param_name_tokenstream(¶ms, true); + + let job_processor_call = if params_tokens.is_empty() { + let second_param = ordered_inputs.pop().expect("Expected a context"); + quote! { + // If no args are specified, assume this job has no parameters and thus takes in the raw event + #fn_name_ident (param0, #second_param) #asyncness .map_err(|err| gadget_sdk::Error::Other(err.to_string())) + } + } else { + quote! { + let mut args_iter = param0.args.clone().into_iter(); + #(#params_tokens)* + #fn_name_ident (#(#ordered_inputs)*) #asyncness .map_err(|err| gadget_sdk::Error::Other(err.to_string())) + } + }; + + quote! { + move |param0: gadget_sdk::event_listener::tangle::TangleEvent<_, _>| async move { + if let Some(call_id) = param0.call_id { + #call_id_static_name.store(call_id, std::sync::atomic::Ordering::Relaxed); + } + + #job_processor_call + } + } +} #[allow(clippy::too_many_lines)] pub fn field_type_to_param_token( ident: &Ident, t: &FieldType, panic_on_decode_fail: bool, -) -> proc_macro2::TokenStream { +) -> TokenStream { let else_block = if panic_on_decode_fail { quote! { panic!("Failed to decode the field"); @@ -131,7 +240,7 @@ pub fn field_type_to_param_token( .collect(); quote! { - let Some(gadget_sdk::tangle_subxt::tangle_testnet_runtime::api::runtime_types::tangle_primitives::services::field::Field::Struct(#ident)) = args_iter.next() else { #else_block }; + let Some(gadget_sdk::tangle_subxt::tangle_testnet_runtime::api::runtime_types::tangle_primitives::services::field::Field::Struct(#ident, ..)) = args_iter.next() else { #else_block }; let mut #ident = #ident.into_iter(); #(#field_tokens)* let #ident = #struct_ident { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 488461ae..16c91143 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,5 @@ [toolchain] -#channel = "stable" -channel = "nightly" +channel = "nightly-2024-10-13" components = ["rustfmt", "clippy", "rust-src"] targets = ["wasm32-unknown-unknown"] profile = "minimal" diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 6fec8836..49bc0558 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -28,6 +28,7 @@ clap = { workspace = true, features = ["derive", "wrap_help"] } url = { workspace = true, features = ["serde"] } uuid = { workspace = true } failure = { workspace = true } +num-bigint = { workspace = true } # Keystore deps ed25519-zebra = { workspace = true } diff --git a/sdk/README.md b/sdk/README.md index edc237df..9a3b85b7 100644 --- a/sdk/README.md +++ b/sdk/README.md @@ -4,11 +4,13 @@ Development tools for Gadgets targeting Tangle or EigenLayer. ## Table of Contents -1. [Overview](#overview) -2. [Installation](#installation) -3. [Features](#features) -4. [Examples](#examples) -5. [Building and Deploying Blueprints](#building-and-deploying-blueprints) +- [Gadget SDK](#gadget-sdk) + - [Table of Contents](#table-of-contents) + - [Overview](#overview) + - [Features](#features) + - [Installation](#installation) + - [Examples](#examples) + - [Building and Deploying Blueprints](#building-and-deploying-blueprints) ## Overview @@ -41,8 +43,8 @@ gadget-sdk = { git = "https://github.com/tangle-network/gadget" } Example Blueprints can be found [here](./../blueprints): - [Incredible Squaring](./../blueprints/incredible-squaring) -- [ECDSA Threshold MPC](./../blueprints/ecdsa-threshold-mpc) -- [Tangle AVS](./../blueprints/tangle-avs-blueprint) +- [Incredible Squaring Eigenlayer](./../blueprints/incredible-squaring-eigenlayer) +- [Incredible Squaring Symbiotic](./../blueprints/incredible-squaring-symbiotic) ## Building and Deploying Blueprints diff --git a/sdk/src/event_utils/evm.rs b/sdk/src/event_utils/evm.rs deleted file mode 100644 index c484a0f1..00000000 --- a/sdk/src/event_utils/evm.rs +++ /dev/null @@ -1,52 +0,0 @@ -use alloy_network::{Ethereum, EthereumWallet}; -use alloy_provider::{ - fillers::{ChainIdFiller, FillProvider, GasFiller, JoinFill, NonceFiller, WalletFiller}, - Identity, Provider, RootProvider, -}; -use alloy_sol_types::SolEvent; -use alloy_transport::Transport; -use alloy_transport_http::{Client, Http}; -use std::ops::Deref; - -pub trait Config: Send + Sync + Clone + 'static { - type TH: Transport + Clone + Send + Sync; - type PH: Provider + Clone + Send + Sync; -} - -#[derive(Debug, Copy, Clone)] -pub struct DefaultNodeConfig {} - -impl Config for DefaultNodeConfig { - type TH = Http; - type PH = FillProvider< - JoinFill< - JoinFill, NonceFiller>, ChainIdFiller>, - WalletFiller, - >, - RootProvider>, - Http, - Ethereum, - >; -} - -pub trait EvmContract: - Deref> - + Send - + Clone - + Sync - + 'static -{ -} -impl< - T: Config, - X: Deref> - + Send - + Clone - + Sync - + 'static, - > EvmContract for X -{ -} - -pub trait EvmEvent: SolEvent + Clone + Send + Sync + 'static {} -impl EvmEvent for X {} diff --git a/sdk/src/event_utils/mod.rs b/sdk/src/event_utils/mod.rs index b39fabb6..538bb003 100644 --- a/sdk/src/event_utils/mod.rs +++ b/sdk/src/event_utils/mod.rs @@ -1,8 +1,5 @@ use async_trait::async_trait; -#[cfg(feature = "std")] -pub mod evm; - #[async_trait] pub trait InitializableEventHandler { async fn init_event_handler(