diff --git a/.github/workflows/pull-request-main-ci.yml b/.github/workflows/pull-request-main-ci.yml index 0acc756..063383d 100644 --- a/.github/workflows/pull-request-main-ci.yml +++ b/.github/workflows/pull-request-main-ci.yml @@ -25,10 +25,6 @@ jobs: build-units-engine: uses: ./.github/workflows/task-build-units-engine.yml - # Build Madara binary - build-madara: - uses: ./.github/workflows/task-build-madara.yml - # Run linters for code style and quality lint-code-style: uses: ./.github/workflows/task-lint-code-style.yml @@ -39,9 +35,8 @@ jobs: # Run Units Engine tests and generate coverage reports test-units-engine: - needs: [build-units-engine, build-madara] + needs: [build-units-engine] uses: ./.github/workflows/task-test-coverage.yml with: units-engine-binary-hash: ${{ needs.build-units-engine.outputs.units-engine-binary-hash }} - madara-binary-hash: ${{ needs.build-madara.outputs.madara-binary-hash }} secrets: inherit diff --git a/.github/workflows/task-build-madara.yml b/.github/workflows/task-build-madara.yml deleted file mode 100644 index dacd4e9..0000000 --- a/.github/workflows/task-build-madara.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Task - Build all - -# This workflow builds the main madara binary so that it can be used during tests -# It also caches the build artifacts for other workflows to use -on: - workflow_dispatch: - workflow_call: - outputs: - madara-binary-hash: - description: "Hash of the built madara binary" - value: ${{ jobs.build-binaries.outputs.madara-binary-hash }} - -jobs: - build-binaries: - permissions: - pull-requests: write - runs-on: ubuntu-latest - outputs: - madara-binary-hash: ${{ steps.generate-binary-hash.outputs.madara-hash }} - - steps: - - uses: actions/checkout@v4 - # Setup the environment with all necessary dependencies - - uses: ./.github/actions/load-env - - - uses: ./.github/actions/setup - with: - cache-key: ${{ env.BUILD_RUST_CACHE_KEY }} - rust-version: ${{ env.BUILD_RUST_VERSION }} - scarb-version: ${{ env.BUILD_SCARB_VERSION }} - install-mold: true - - # Build madara - # TODO: Remove this once we have a proper binary releases - # This binary is from commit 0f36a01b5c9aa157c483a8e0b8dba5757eebb664 - - name: Download binary - run: | - mkdir -p target/release && wget https://units-engine-ci.s3.us-east-1.amazonaws.com/madara -O target/release/madara - - # Generate hash for the madara binary - - name: Generate binary hashes - id: generate-binary-hash - run: | - # Get current Unix timestamp for uniqueness - TIMESTAMP=$(date +%s) - - # Path to the compiled madara binary - BINARY_PATH=./target/release/madara - HASH=$(echo "$TIMESTAMP" | cat - $BINARY_PATH | sha256sum | awk '{ print $1 }') - echo "madara-hash=$HASH" >> $GITHUB_OUTPUT - echo "Hash of the madara is: $HASH (with timestamp: $TIMESTAMP)" - - # Upload madara binary as artifact - - name: Upload madara binary - uses: actions/upload-artifact@v4 - with: - name: madara-binary-${{ steps.generate-binary-hash.outputs.madara-hash }} - path: target/release/madara - retention-days: 1 - - # Keep the cache operations for runners of the same type - - name: Cache madara binary - uses: actions/cache/save@v4 - with: - path: target/release/madara - key: ${{ runner.os }}-${{ env.BUILD_ACTION_CACHE_PREFIX }}-bin-${{ steps.generate-binary-hash.outputs.madara-hash }} - - - name: Display hashes - run: | - echo "madara-binary-hash: ${{ steps.generate-binary-hash.outputs.madara-hash }}" diff --git a/.github/workflows/task-test-coverage.yml b/.github/workflows/task-test-coverage.yml index 1407916..94fce5e 100644 --- a/.github/workflows/task-test-coverage.yml +++ b/.github/workflows/task-test-coverage.yml @@ -10,10 +10,6 @@ on: description: "Hash used to retrieve the artifact" required: true type: string - madara-binary-hash: - description: "Hash used to retrieve the artifact" - required: true - type: string jobs: test-with-coverage: @@ -45,12 +41,6 @@ jobs: with: name: units-engine-binary-${{ inputs.units-engine-binary-hash }} path: target/release/ - - name: Download Madara binary - uses: actions/download-artifact@v4 - with: - name: madara-binary-${{ inputs.madara-binary-hash }} - path: crates/handlers/starknet/src/tests/build/ - - run: chmod +x crates/handlers/starknet/src/tests/build/madara - name: Run tests with coverage run: | diff --git a/Cargo.lock b/Cargo.lock index 56640ac..d08c131 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -198,7 +198,7 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper 1.0.2", + "sync_wrapper", "tower 0.5.2", "tower-layer", "tower-service", @@ -219,7 +219,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.2", + "sync_wrapper", "tower-layer", "tower-service", ] @@ -266,12 +266,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.9.0" @@ -290,6 +284,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -347,6 +350,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.40" @@ -644,7 +653,7 @@ dependencies = [ "hex", "hmac", "pbkdf2", - "rand", + "rand 0.8.5", "scrypt", "serde", "serde_json", @@ -694,7 +703,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", - "rand", + "rand 0.8.5", "rustc-hex", "static_assertions", ] @@ -880,9 +889,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -1176,6 +1187,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.2", "tower-service", + "webpki-roots", ] [[package]] @@ -1546,7 +1558,7 @@ dependencies = [ "tokio-util", "tracing", "url", - "webpki-roots 0.26.8", + "webpki-roots", ] [[package]] @@ -1564,8 +1576,8 @@ dependencies = [ "jsonrpsee-types", "parking_lot", "pin-project", - "rand", - "rustc-hash", + "rand 0.8.5", + "rustc-hash 1.1.0", "serde", "serde_json", "thiserror 1.0.69", @@ -1680,11 +1692,13 @@ dependencies = [ [[package]] name = "lambdaworks-crypto" -version = "0.10.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc2a4da0d9e52ccfe6306801a112e81a8fc0c76aa3e4449fefeda7fef72bb34" +checksum = "58b1a1c1102a5a7fbbda117b79fb3a01e033459c738a3c1642269603484fd1c1" dependencies = [ "lambdaworks-math", + "rand 0.8.5", + "rand_chacha 0.3.1", "serde", "sha2", "sha3", @@ -1692,10 +1706,14 @@ dependencies = [ [[package]] name = "lambdaworks-math" -version = "0.10.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1bd2632acbd9957afc5aeec07ad39f078ae38656654043bf16e046fa2730e23" +checksum = "018a95aa873eb49896a858dee0d925c33f3978d073c64b08dd4f2c9b35a017c6" dependencies = [ + "getrandom 0.2.15", + "num-bigint", + "num-traits", + "rand 0.8.5", "serde", "serde_json", ] @@ -1740,6 +1758,12 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "matchers" version = "0.1.0" @@ -1894,7 +1918,7 @@ version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ - "bitflags 2.9.0", + "bitflags", "cfg-if", "foreign-types", "libc", @@ -2008,7 +2032,7 @@ dependencies = [ "once_cell", "opentelemetry", "percent-encoding", - "rand", + "rand 0.8.5", "serde_json", "thiserror 1.0.69", "tokio", @@ -2194,6 +2218,61 @@ dependencies = [ "syn", ] +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.1", + "rustls 0.23.25", + "socket2", + "thiserror 2.0.12", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "getrandom 0.3.2", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash 2.1.1", + "rustls 0.23.25", + "rustls-pki-types", + "slab", + "thiserror 2.0.12", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "quote" version = "1.0.40" @@ -2222,8 +2301,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -2233,7 +2322,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -2245,13 +2344,22 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", +] + [[package]] name = "redox_syscall" version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 2.9.0", + "bitflags", ] [[package]] @@ -2304,47 +2412,6 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.32", - "hyper-rustls 0.24.2", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration 0.5.1", - "tokio", - "tokio-rustls 0.24.1", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 0.25.4", - "winreg", -] - [[package]] name = "reqwest" version = "0.12.15" @@ -2372,20 +2439,25 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "quinn", + "rustls 0.23.25", "rustls-pemfile 2.2.0", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.2", - "system-configuration 0.6.1", + "sync_wrapper", + "system-configuration", "tokio", "tokio-native-tls", + "tokio-rustls 0.26.2", "tower 0.5.2", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots", "windows-registry", ] @@ -2471,6 +2543,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -2492,7 +2570,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" dependencies = [ - "bitflags 2.9.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -2532,6 +2610,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ "once_cell", + "ring", "rustls-pki-types", "rustls-webpki 0.103.1", "subtle", @@ -2586,6 +2665,9 @@ name = "rustls-pki-types" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +dependencies = [ + "web-time", +] [[package]] name = "rustls-webpki" @@ -2683,7 +2765,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.0", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -2892,7 +2974,7 @@ dependencies = [ "http 0.2.12", "httparse", "log", - "rand", + "rand 0.8.5", "sha-1", ] @@ -2904,13 +2986,13 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "starknet" -version = "0.13.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc9b221c99a1ea1d65fb130e5b0dbaa6d362698430232902ebeb2a898a1ab531" +checksum = "f5ed01c14136e56dcdf21385d20c4a6fdd3509947cb56cca45fc765ef5809add" dependencies = [ "starknet-accounts", "starknet-contract", - "starknet-core 0.12.2", + "starknet-core", "starknet-core-derive", "starknet-crypto", "starknet-macros", @@ -2920,13 +3002,13 @@ dependencies = [ [[package]] name = "starknet-accounts" -version = "0.12.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3fc4364f5684e4a5dcb100847a9ea023deae3815f45526721a6fa94ab595651" +checksum = "4f7c118729bcdcfa1610844047cbdb23090fb1d4172a36bb97a663be8d022d1a" dependencies = [ "async-trait", "auto_impl", - "starknet-core 0.12.2", + "starknet-core", "starknet-crypto", "starknet-providers", "starknet-signers", @@ -2935,47 +3017,24 @@ dependencies = [ [[package]] name = "starknet-contract" -version = "0.12.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2102b8f763477a1bdece683da51514bc73829d5dcc3bbe75ff1b6aca6d4e02" +checksum = "ccb64331b72caf51c0d8b684b62012f9a771015b4cf5e52cba9bf61be8384ad3" dependencies = [ "serde", "serde_json", "serde_with", "starknet-accounts", - "starknet-core 0.12.2", + "starknet-core", "starknet-providers", "thiserror 1.0.69", ] [[package]] name = "starknet-core" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab44b2157b7f4697d58375cc8b8dbac8dfb6be79f13fd80c9f59634d2ac972c7" -dependencies = [ - "base64 0.21.7", - "crypto-bigint", - "flate2", - "foldhash", - "hex", - "indexmap 2.8.0", - "num-traits", - "serde", - "serde_json", - "serde_json_pythonic", - "serde_with", - "sha3", - "starknet-core-derive", - "starknet-crypto", - "starknet-types-core", -] - -[[package]] -name = "starknet-core" -version = "0.13.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b53a16799e4a75173839d868a1a48ff5d3e10456febd4dec91b04ba6521741d5" +checksum = "efb7212226769766c1c7d79b70f9242ffbd213290a41604ecc7e78faa0ed0deb" dependencies = [ "base64 0.21.7", "crypto-bigint", @@ -3007,9 +3066,9 @@ dependencies = [ [[package]] name = "starknet-crypto" -version = "0.7.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "039a3bad70806b494c9e6b21c5238a6c8a373d66a26071859deb0ccca6f93634" +checksum = "1004a16c25dc6113c19d4f9d0c19ff97d85804829894bba22c0d0e9e7b249812" dependencies = [ "crypto-bigint", "hex", @@ -3026,28 +3085,28 @@ dependencies = [ [[package]] name = "starknet-curve" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcde6bd74269b8161948190ace6cf069ef20ac6e79cd2ba09b320efa7500b6de" +checksum = "22c898ae81b6409532374cf237f1bd752d068b96c6ad500af9ebbd0d9bb712f6" dependencies = [ "starknet-types-core", ] [[package]] name = "starknet-macros" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb14b6714e7625aca063e91022e574ee0bca863df98071dd7191e24919a367b0" +checksum = "6d59e1eb22f4366385b132ba7016faa5a6457f1f23f896f737a06da626455e7b" dependencies = [ - "starknet-core 0.13.0", + "starknet-core", "syn", ] [[package]] name = "starknet-providers" -version = "0.12.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9256247f718564b3e4c73cc941735012691c14903fbc25cea306745bcbfa384" +checksum = "15fc3d94cc008cea64e291b261e8349065424ee7491e5dd0fa9bd688818bece1" dependencies = [ "async-trait", "auto_impl", @@ -3055,44 +3114,48 @@ dependencies = [ "flate2", "getrandom 0.2.15", "log", - "reqwest 0.11.27", + "reqwest", "serde", "serde_json", "serde_with", - "starknet-core 0.12.2", + "starknet-core", "thiserror 1.0.69", "url", ] [[package]] name = "starknet-signers" -version = "0.10.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518c7de189cd4158d45d33067c580094ad5cd2f027a90ac76d49a81c89fa37bc" +checksum = "d839b06d899ef3a0de11b1e9a91a14c118b1ed36830ec8e59d9fbc9a1e51976b" dependencies = [ "async-trait", "auto_impl", "crypto-bigint", "eth-keystore", "getrandom 0.2.15", - "rand", - "starknet-core 0.12.2", + "rand 0.8.5", + "starknet-core", "starknet-crypto", "thiserror 1.0.69", ] [[package]] name = "starknet-types-core" -version = "0.1.7" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1b9e01ccb217ab6d475c5cda05dbb22c30029f7bb52b192a010a00d77a3d74" +checksum = "90d23b1bc014ee4cce40056ab3114bcbcdc2dbc1e845bbfb1f8bd0bab63507d4" dependencies = [ + "blake2", + "digest 0.10.7", "lambdaworks-crypto", "lambdaworks-math", "num-bigint", "num-integer", "num-traits", + "rand 0.9.2", "serde", + "zeroize", ] [[package]] @@ -3124,12 +3187,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "sync_wrapper" version = "1.0.2" @@ -3150,36 +3207,15 @@ dependencies = [ "syn", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys 0.5.0", -] - [[package]] name = "system-configuration" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.0", + "bitflags", "core-foundation", - "system-configuration-sys 0.6.0", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", + "system-configuration-sys", ] [[package]] @@ -3313,6 +3349,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.38.1" @@ -3467,7 +3518,7 @@ dependencies = [ "indexmap 1.9.3", "pin-project", "pin-project-lite", - "rand", + "rand 0.8.5", "slab", "tokio", "tokio-util", @@ -3485,7 +3536,7 @@ dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 1.0.2", + "sync_wrapper", "tokio", "tower-layer", "tower-service", @@ -3497,7 +3548,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.9.0", + "bitflags", "bytes", "futures-core", "futures-util", @@ -3653,7 +3704,7 @@ version = "0.1.0" dependencies = [ "anyhow", "once_cell", - "reqwest 0.12.15", + "reqwest", "rstest", "serde_json", "starknet", @@ -3725,7 +3776,7 @@ dependencies = [ "futures", "hex", "once_cell", - "reqwest 0.12.15", + "reqwest", "rstest", "serde_json", "starknet", @@ -3810,7 +3861,7 @@ version = "0.1.0" dependencies = [ "anyhow", "once_cell", - "reqwest 0.12.15", + "reqwest", "rstest", "serde_json", "tokio", @@ -4025,12 +4076,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "webpki-roots" version = "0.26.8" @@ -4327,23 +4372,13 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "wit-bindgen-rt" version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.0", + "bitflags", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c729a23..d56dc32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,8 +71,8 @@ hyper-util = "0.1.9" tower = { version = "0.4", features = ["util"] } tower-http = { version = "0.4", features = ["cors"] } thiserror = "2.0" -starknet = "0.13.0" -starknet-crypto = "0.7.4" +starknet = "0.17.0" +starknet-crypto = "0.8.1" reqwest = "0.12" uuid = { version = "1.16", features = ["v4"] } once_cell = "1.21" diff --git a/crates/engine/src/service/rpc/server.rs b/crates/engine/src/service/rpc/server.rs index ac32fc3..e128c8d 100644 --- a/crates/engine/src/service/rpc/server.rs +++ b/crates/engine/src/service/rpc/server.rs @@ -269,7 +269,7 @@ pub(crate) fn try_into_cors( pub(crate) fn format_cors(maybe_cors: Option<&Vec>) -> String { if let Some(cors) = maybe_cors { - format!("{:?}", cors) + format!("{cors:?}") } else { format!("{:?}", ["*"]) } diff --git a/crates/handlers/starknet/src/lib.rs b/crates/handlers/starknet/src/lib.rs index 27b8264..8d21fdc 100644 --- a/crates/handlers/starknet/src/lib.rs +++ b/crates/handlers/starknet/src/lib.rs @@ -6,9 +6,8 @@ use starknet::{ accounts::{Account, ExecutionEncoding, SingleOwnerAccount}, core::{ types::{ - BlockId, BlockTag, BroadcastedDeclareTransaction, BroadcastedDeclareTransactionV3, - BroadcastedDeployAccountTransaction, BroadcastedDeployAccountTransactionV3, - BroadcastedInvokeTransaction, BroadcastedInvokeTransactionV3, Call, + BlockId, BlockTag, BroadcastedDeclareTransactionV3, + BroadcastedDeployAccountTransactionV3, BroadcastedInvokeTransactionV3, Call, DataAvailabilityMode, ExecutionResult, Felt, FlattenedSierraClass, FunctionCall, ResourceBounds, ResourceBoundsMapping, TransactionFinalityStatus, }, @@ -120,6 +119,9 @@ impl ChainHandler for StarknetContext { ) -> Result { let class: FlattenedSierraClass = serde_json::from_value(params.program.clone()) .map_err(|e| ChainHandlerError::InvalidProgram(e.to_string()))?; + + // We don't call `estimate_fee` here because UNITS allows to declare programs multiple times with + // different visibility levels. So, if we call `estimate_fee` here, the 2nd call to `declare_program` will fail. let declare_class_transaction = BroadcastedDeclareTransactionV3 { sender_address: params.account_address.to_felt()?, compiled_class_hash: params @@ -134,12 +136,16 @@ impl ChainHandler for StarknetContext { account_deployment_data: vec![], resource_bounds: ResourceBoundsMapping { l1_gas: ResourceBounds { - max_amount: 0, - max_price_per_unit: 0, + max_amount: params.resource_bounds.l1_gas.max_amount, + max_price_per_unit: params.resource_bounds.l1_gas.max_price_per_unit, + }, + l1_data_gas: ResourceBounds { + max_amount: params.resource_bounds.l1_data_gas.max_amount, + max_price_per_unit: params.resource_bounds.l1_data_gas.max_price_per_unit, }, l2_gas: ResourceBounds { - max_amount: 0, - max_price_per_unit: 0, + max_amount: params.resource_bounds.l2_gas.max_amount, + max_price_per_unit: params.resource_bounds.l2_gas.max_price_per_unit, }, }, tip: 0, @@ -151,7 +157,7 @@ impl ChainHandler for StarknetContext { let result = self .starknet_provider - .add_declare_transaction(BroadcastedDeclareTransaction::V3(declare_class_transaction)) + .add_declare_transaction(declare_class_transaction) .await .map_err(|e| ChainHandlerError::ProviderError(e.to_string()))?; Ok(result.transaction_hash.into()) @@ -169,12 +175,16 @@ impl ChainHandler for StarknetContext { account_deployment_data: vec![], resource_bounds: ResourceBoundsMapping { l1_gas: ResourceBounds { - max_amount: 0, - max_price_per_unit: 0, + max_amount: params.resource_bounds.l1_gas.max_amount, + max_price_per_unit: params.resource_bounds.l1_gas.max_price_per_unit, + }, + l1_data_gas: ResourceBounds { + max_amount: params.resource_bounds.l1_data_gas.max_amount, + max_price_per_unit: params.resource_bounds.l1_data_gas.max_price_per_unit, }, l2_gas: ResourceBounds { - max_amount: 0, - max_price_per_unit: 0, + max_amount: params.resource_bounds.l2_gas.max_amount, + max_price_per_unit: params.resource_bounds.l2_gas.max_price_per_unit, }, }, tip: 0, @@ -186,9 +196,7 @@ impl ChainHandler for StarknetContext { let result = self .starknet_provider - .add_invoke_transaction(BroadcastedInvokeTransaction::V3( - send_transaction_transaction, - )) + .add_invoke_transaction(send_transaction_transaction) .await .map_err(|e| ChainHandlerError::ProviderError(e.to_string()))?; @@ -209,12 +217,16 @@ impl ChainHandler for StarknetContext { class_hash: params.program_hash.to_felt()?, resource_bounds: ResourceBoundsMapping { l1_gas: ResourceBounds { - max_amount: 0, - max_price_per_unit: 0, + max_amount: params.resource_bounds.l1_gas.max_amount, + max_price_per_unit: params.resource_bounds.l1_gas.max_price_per_unit, + }, + l1_data_gas: ResourceBounds { + max_amount: params.resource_bounds.l1_data_gas.max_amount, + max_price_per_unit: params.resource_bounds.l1_data_gas.max_price_per_unit, }, l2_gas: ResourceBounds { - max_amount: 0, - max_price_per_unit: 0, + max_amount: params.resource_bounds.l2_gas.max_amount, + max_price_per_unit: params.resource_bounds.l2_gas.max_price_per_unit, }, }, tip: 0, @@ -225,9 +237,7 @@ impl ChainHandler for StarknetContext { }; let result = self .starknet_provider - .add_deploy_account_transaction(BroadcastedDeployAccountTransaction::V3( - deploy_account_transaction, - )) + .add_deploy_account_transaction(deploy_account_transaction) .await .map_err(|e| ChainHandlerError::ProviderError(e.to_string()))?; Ok(DeployAccountResult { @@ -242,7 +252,7 @@ impl ChainHandler for StarknetContext { ) -> Result { match self .starknet_provider - .get_class(BlockId::Tag(BlockTag::Pending), class_hash.to_felt()?) + .get_class(BlockId::Tag(BlockTag::PreConfirmed), class_hash.to_felt()?) .await .map_err(|e| ChainHandlerError::ProviderError(e.to_string())) { @@ -257,7 +267,7 @@ impl ChainHandler for StarknetContext { async fn get_nonce(&self, address: Bytes32) -> Result { let nonce = self .starknet_provider - .get_nonce(BlockId::Tag(BlockTag::Pending), address.to_felt()?) + .get_nonce(BlockId::Tag(BlockTag::PreConfirmed), address.to_felt()?) .await .map_err(|e| ChainHandlerError::ProviderError(e.to_string()))?; Ok(nonce.try_into().map_err(|_| { @@ -289,6 +299,7 @@ impl ChainHandler for StarknetContext { let finality_status = match receipt.receipt.finality_status() { TransactionFinalityStatus::AcceptedOnL2 => FinalityStatus::AcceptedOnUnits, TransactionFinalityStatus::AcceptedOnL1 => FinalityStatus::AcceptedOnProofStore, + TransactionFinalityStatus::PreConfirmed => FinalityStatus::AcceptedOnUnits, }; let execution_status = match receipt.receipt.execution_result() { @@ -339,7 +350,7 @@ impl ChainHandler for StarknetContext { ] .concat(), }, - BlockId::Tag(BlockTag::Pending), + BlockId::Tag(BlockTag::PreConfirmed), ) .await .map_err(|e| ChainHandlerError::ProviderError(e.to_string()))?; @@ -367,7 +378,7 @@ impl ChainHandler for StarknetContext { entry_point_selector: GET_KEY_SELECTOR, calldata: vec![account_address.to_felt()?], }, - BlockId::Tag(BlockTag::Pending), + BlockId::Tag(BlockTag::PreConfirmed), ) .await .map_err(|e| ChainHandlerError::ProviderError(e.to_string()))?; @@ -413,7 +424,7 @@ impl ChainHandler for StarknetContext { let has_selector = contract_address_has_selector( self.starknet_provider.clone(), contract_address.to_felt()?, - BlockId::Tag(BlockTag::Pending), + BlockId::Tag(BlockTag::PreConfirmed), get_selector_from_name(function_name.as_str()) .map_err(|e| ChainHandlerError::InvalidFunctionName(e.to_string()))?, ) @@ -479,8 +490,6 @@ impl ChainHandler for StarknetContext { sender_address.to_felt()?, ], }]) - .gas(0) - .gas_price(0) .send() .await .map_err(|e| ChainHandlerError::ProviderError(e.to_string()))? @@ -502,7 +511,7 @@ impl ChainHandler for StarknetContext { entry_point_selector: selector!("get_visibility"), calldata: vec![class_hash.to_felt()?], }, - BlockId::Tag(BlockTag::Pending), + BlockId::Tag(BlockTag::PreConfirmed), ) .await .map_err(|e| ChainHandlerError::ProviderError(e.to_string()))? @@ -528,7 +537,7 @@ impl ChainHandler for StarknetContext { entry_point_selector: function_name.to_felt()?, calldata: calldata.to_felt()?, }, - BlockId::Tag(BlockTag::Pending), + BlockId::Tag(BlockTag::PreConfirmed), ) .await .map_err(|e| ChainHandlerError::ProviderError(e.to_string()))?; diff --git a/crates/handlers/starknet/src/tests/call/mod.rs b/crates/handlers/starknet/src/tests/call/mod.rs index 3173220..ea5d909 100644 --- a/crates/handlers/starknet/src/tests/call/mod.rs +++ b/crates/handlers/starknet/src/tests/call/mod.rs @@ -55,8 +55,6 @@ async fn test_counter_increment( selector: selector!("increment"), calldata: vec![], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); @@ -107,8 +105,6 @@ async fn test_counter_increment( selector: selector!("decrement"), calldata: vec![], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); @@ -261,8 +257,6 @@ async fn test_read_with_approval( selector: selector!("add_approved_user"), calldata: vec![user_account.address()], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); diff --git a/crates/handlers/starknet/src/tests/declare_program/mod.rs b/crates/handlers/starknet/src/tests/declare_program/mod.rs index 2a3ea1d..823c5fe 100644 --- a/crates/handlers/starknet/src/tests/declare_program/mod.rs +++ b/crates/handlers/starknet/src/tests/declare_program/mod.rs @@ -1,7 +1,10 @@ use rstest::*; use starknet::{ accounts::Account, - core::types::{BlockId, BlockTag, FunctionCall}, + core::{ + types::{BlockId, BlockTag, FunctionCall}, + utils::get_selector_from_name, + }, }; use crate::utils::WaitForReceipt; @@ -14,7 +17,6 @@ use crate::{ }, StarknetContext, }; -use starknet::macros::selector; use std::sync::Arc; use units_primitives::{ context::GlobalContext, @@ -28,8 +30,10 @@ use units_handlers_common::declare_program::declare_program; #[cfg(feature = "testing")] mod tests { + #![allow(unsafe_code, unsafe_op_in_unsafe_fn)] use starknet::accounts::ConnectedAccount; + use units_primitives::rpc::ResourceBoundsMappingParams; use crate::tests::utils::scarb::Artifacts; @@ -99,7 +103,7 @@ mod tests { // Verify the class was declared by retrieving it let declared_class = provider .get_class( - BlockId::Tag(BlockTag::Pending), + BlockId::Tag(BlockTag::PreConfirmed), starknet_declare_txn.class_hash, ) .await @@ -119,15 +123,15 @@ mod tests { .get_declare_acl_address() .try_into() .unwrap(), - entry_point_selector: selector!("get_visibility"), + entry_point_selector: get_selector_from_name("get_visibility").unwrap(), calldata: vec![starknet_declare_txn.class_hash], }, - BlockId::Tag(BlockTag::Pending), + BlockId::Tag(BlockTag::PreConfirmed), ) .await .unwrap(); - assert_eq!(visibility, vec![ClassVisibility::Acl.into()]); + assert_eq!(visibility, vec![Felt::from(ClassVisibility::Acl)]); // Wait for a new block to be sure the ACL transaction from previous // declare is on chain (otherwise we get a nonce issue) @@ -175,7 +179,7 @@ mod tests { break; } if start_time.elapsed() >= timeout { - panic!("Block not found after {:?} timeout", timeout); + panic!("Block not found after {timeout:?} timeout"); } tokio::time::sleep(retry_delay).await; } @@ -189,14 +193,14 @@ mod tests { .get_declare_acl_address() .try_into() .unwrap(), - entry_point_selector: selector!("get_visibility"), + entry_point_selector: get_selector_from_name("get_visibility").unwrap(), calldata: vec![starknet_declare_txn.class_hash], }, - BlockId::Tag(BlockTag::Pending), + BlockId::Tag(BlockTag::PreConfirmed), ) .await .unwrap(); - assert_eq!(visibility, vec![ClassVisibility::Public.into()]); + assert_eq!(visibility, vec![Felt::from(ClassVisibility::Public)]); } async fn build_declare_txn( @@ -206,19 +210,31 @@ mod tests { ) -> DeclareProgramParams { let provider = account.account.provider(); let nonce = provider - .get_nonce(BlockId::Tag(BlockTag::Pending), account.account.address()) + .get_nonce( + BlockId::Tag(BlockTag::PreConfirmed), + account.account.address(), + ) .await .unwrap(); - + // Not doing a fee estimate here because UNITS allows to declare programs multiple times with + // different visibility levels. So, a 2nd call to `build_declare_txn` in the test case will + // fail if we call `estimate_fee` + let mut resource_bounds = ResourceBoundsMappingParams::default(); + resource_bounds.l2_gas.max_amount = 10000000; // uses 9278720, so proving a little extra let declare_tx = account .account .declare_v3( Arc::new(artifact.contract_class.clone().flatten().unwrap()), artifact.compiled_class_hash, ) - .gas(0) - .gas_price(0) .nonce(nonce) + .l1_gas_price(resource_bounds.l1_gas.max_price_per_unit) + .l1_gas(resource_bounds.l1_gas.max_amount) + .l2_gas_price(resource_bounds.l2_gas.max_price_per_unit) + .l2_gas(resource_bounds.l2_gas.max_amount) + .l1_data_gas_price(resource_bounds.l1_data_gas.max_price_per_unit) + .l1_data_gas(resource_bounds.l1_data_gas.max_amount) + .tip(0) .prepared() .unwrap(); let tx_hash = declare_tx.transaction_hash(false); @@ -232,6 +248,7 @@ mod tests { program: serde_json::to_value(flattened_contract_class.clone()).unwrap(), compiled_program_hash: Some(artifact.compiled_class_hash.into()), class_visibility, + resource_bounds, } } } diff --git a/crates/handlers/starknet/src/tests/deploy_account.rs b/crates/handlers/starknet/src/tests/deploy_account.rs index 8fecda8..0620819 100644 --- a/crates/handlers/starknet/src/tests/deploy_account.rs +++ b/crates/handlers/starknet/src/tests/deploy_account.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use crate::tests::utils::{ madara::{madara_node, MadaraRunner}, - starknet::{ProviderToDummyGlobalContext, PREDEPLOYED_ACCOUNT_CLASS_HASH}, + starknet::{fund_account_devnet, ProviderToDummyGlobalContext, PREDEPLOYED_ACCOUNT_CLASS_HASH}, }; use crate::utils::wait_for_receipt; use crate::StarknetProvider; @@ -37,11 +37,22 @@ async fn test_add_deploy_account_transaction( .unwrap(); let salt = Felt::ONE; let account_address = account_factory.deploy_v3(salt).address(); + let fee_estimate = account_factory + .deploy_v3(salt) + .nonce(Felt::ZERO) + .estimate_fee() + .await + .unwrap(); let prepared_deployment = account_factory .deploy_v3(salt) - .gas(0) - .gas_price(0) .nonce(Felt::ZERO) + .l1_gas_price(fee_estimate.l1_gas_price) + .l1_gas(fee_estimate.l1_gas_consumed) + .l2_gas_price(fee_estimate.l2_gas_price) + .l2_gas(fee_estimate.l2_gas_consumed) + .l1_data_gas_price(fee_estimate.l1_data_gas_price) + .l1_data_gas(fee_estimate.l1_data_gas_consumed) + .tip(0) .prepared() .unwrap(); let tx_hash = prepared_deployment.transaction_hash(false); @@ -52,8 +63,12 @@ async fn test_add_deploy_account_transaction( account_address_salt: salt.into(), constructor_calldata: vec![verifying_key.scalar().into()], program_hash: Felt::from_hex_unchecked(PREDEPLOYED_ACCOUNT_CLASS_HASH).into(), + resource_bounds: fee_estimate.into(), }; + fund_account_devnet(starknet_provider.clone(), account_address) + .await + .unwrap(); let result = deploy_account(global_ctx, deploy_account_transaction) .await .unwrap(); @@ -62,7 +77,7 @@ async fn test_add_deploy_account_transaction( .await .unwrap(); let class_hash_at = starknet_provider - .get_class_hash_at(BlockId::Tag(BlockTag::Pending), account_address) + .get_class_hash_at(BlockId::Tag(BlockTag::PreConfirmed), account_address) .await .unwrap(); assert_eq!( diff --git a/crates/handlers/starknet/src/tests/get_program/mod.rs b/crates/handlers/starknet/src/tests/get_program/mod.rs index 93a6295..72d7edb 100644 --- a/crates/handlers/starknet/src/tests/get_program/mod.rs +++ b/crates/handlers/starknet/src/tests/get_program/mod.rs @@ -100,8 +100,6 @@ async fn test_get_program( owner_account.address(), ], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap() @@ -137,8 +135,6 @@ async fn test_get_program( owner_account.address(), ], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap() @@ -185,8 +181,6 @@ async fn test_get_program( owner_account.address(), ], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap() diff --git a/crates/handlers/starknet/src/tests/get_transaction_receipt/mod.rs b/crates/handlers/starknet/src/tests/get_transaction_receipt/mod.rs index 16d1660..855a593 100644 --- a/crates/handlers/starknet/src/tests/get_transaction_receipt/mod.rs +++ b/crates/handlers/starknet/src/tests/get_transaction_receipt/mod.rs @@ -26,6 +26,28 @@ use crate::tests::utils::starknet::ProviderToDummyGlobalContext; use units_handlers_common::get_transaction_receipt::GetTransactionReceiptError; use units_primitives::rpc::ExecutionStatus; +use crate::tests::utils::starknet::STRK_TOKEN_ADDRESS; + +/// Helper function to assert that a fee transfer event is present +/// The fee transfer event should be the last event in the events array +fn assert_fee_transfer_event(events: &[units_primitives::rpc::Event]) { + assert!( + !events.is_empty(), + "Expected at least one event (fee transfer)" + ); + let last_event = &events[events.len() - 1]; + assert_eq!( + last_event.keys[0], + selector!("Transfer").into(), + "Last event should be a Transfer event" + ); + assert_eq!( + last_event.from_address, + Felt::from_hex_unchecked(STRK_TOKEN_ADDRESS).into(), + "Fee transfer should be from STRK token address" + ); +} + #[rstest] #[tokio::test] #[cfg(feature = "testing")] @@ -58,8 +80,6 @@ async fn test_get_receipt_fails_with_different_sender( selector: selector!("emit_event"), calldata: vec![], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); @@ -132,8 +152,6 @@ async fn test_get_receipt_fails_with_invalid_read_signature( selector: selector!("emit_event"), calldata: vec![], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); @@ -221,8 +239,6 @@ async fn test_get_receipt_without_can_read_event( selector: selector!("emit_event"), calldata: vec![], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); @@ -259,12 +275,15 @@ async fn test_get_receipt_without_can_read_event( .await .unwrap(); - // Since contract doesn't implement can_read_event, receipt should have one event - assert_eq!(receipt.events.len(), 1); + // Since contract doesn't implement can_read_event, receipt should have two events (one `TestEvent` and one fee `Transfer` event) + assert_eq!(receipt.events.len(), 2); assert_eq!(receipt.events[0].data[0], Felt::from(1).into()); // TestEvent data assert_eq!(receipt.events[0].keys[0], selector!("TestEvent").into()); assert_matches!(receipt.execution_status, ExecutionStatus::Succeeded); assert_eq!(receipt.transaction_hash, result.transaction_hash.into()); + + // Check that the fee transfer event is present + assert_fee_transfer_event(&receipt.events); } #[rstest] @@ -302,8 +321,6 @@ async fn test_get_receipt_with_can_read_event( selector: selector!("emit_event_one"), calldata: vec![], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); @@ -340,7 +357,9 @@ async fn test_get_receipt_with_can_read_event( .await .unwrap(); - assert_eq!(receipt.events.len(), 0); + // Should have 1 event (fee transfer) since we haven't given permission for contract events + assert_eq!(receipt.events.len(), 1); + assert_fee_transfer_event(&receipt.events); // Update ACL to allow reading TestEventOne let result = account_with_private_key @@ -353,8 +372,6 @@ async fn test_get_receipt_with_can_read_event( account_with_private_key.account.address(), ], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); @@ -364,7 +381,7 @@ async fn test_get_receipt_with_can_read_event( .await .unwrap(); - // Get receipt again - should now have the event + // Get receipt again - should now have the event plus fee transfer let receipt = get_transaction_receipt( global_ctx.clone(), GetTransactionReceiptParams { @@ -375,9 +392,10 @@ async fn test_get_receipt_with_can_read_event( .await .unwrap(); - assert_eq!(receipt.events.len(), 1); + assert_eq!(receipt.events.len(), 2); assert_eq!(receipt.events[0].data[0], Felt::from(1).into()); // TestEventOne data assert_eq!(receipt.events[0].keys[0], selector!("TestEventOne").into()); + assert_fee_transfer_event(&receipt.events); // Call emit_event_one_and_two let emit_one_and_two_result = account_with_private_key @@ -387,8 +405,6 @@ async fn test_get_receipt_with_can_read_event( selector: selector!("emit_event_one_and_two"), calldata: vec![], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); @@ -414,7 +430,7 @@ async fn test_get_receipt_with_can_read_event( .await .unwrap(); - // Get receipt - should only have TestEventOne since we only have permission for it + // Get receipt - should have TestEventOne and fee transfer since we only have permission for TestEventOne let receipt = get_transaction_receipt( global_ctx.clone(), GetTransactionReceiptParams { @@ -425,9 +441,10 @@ async fn test_get_receipt_with_can_read_event( .await .unwrap(); - assert_eq!(receipt.events.len(), 1); + assert_eq!(receipt.events.len(), 2); assert_eq!(receipt.events[0].data[0], Felt::from(1).into()); // TestEventOne data assert_eq!(receipt.events[0].keys[0], selector!("TestEventOne").into()); + assert_fee_transfer_event(&receipt.events); // Update ACL to allow reading TestEventTwo let result = account_with_private_key @@ -440,8 +457,6 @@ async fn test_get_receipt_with_can_read_event( account_with_private_key.account.address(), ], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); @@ -451,7 +466,7 @@ async fn test_get_receipt_with_can_read_event( .await .unwrap(); - // Get receipt again - should now have both events + // Get receipt again - should now have both contract events plus fee transfer let receipt = get_transaction_receipt( global_ctx.clone(), GetTransactionReceiptParams { @@ -462,11 +477,12 @@ async fn test_get_receipt_with_can_read_event( .await .unwrap(); - assert_eq!(receipt.events.len(), 2); + assert_eq!(receipt.events.len(), 3); assert_eq!(receipt.events[0].data[0], Felt::from(1).into()); // TestEventOne data assert_eq!(receipt.events[0].keys[0], selector!("TestEventOne").into()); assert_eq!(receipt.events[1].data[0], Felt::from(2).into()); // TestEventTwo data assert_eq!(receipt.events[1].keys[0], selector!("TestEventTwo").into()); + assert_fee_transfer_event(&receipt.events); } #[rstest] @@ -482,7 +498,7 @@ async fn test_get_receipt_reverted_transaction( Vec, ), ) { - use units_primitives::rpc::ExecutionStatus; + use units_primitives::rpc::{ExecutionStatus, ResourceBoundsMappingParams}; let (_runner, provider, accounts_with_private_key) = madara_node_with_accounts.await; let account_with_private_key = &accounts_with_private_key[0]; @@ -499,15 +515,21 @@ async fn test_get_receipt_reverted_transaction( .await; // Call panic function to generate a reverted transaction - let result = account_with_private_key - .account - .execute_v3(vec![Call { - to: contract_address, - selector: selector!("panic"), - calldata: vec![], - }]) - .gas(0) - .gas_price(0) + let execution = account_with_private_key.account.execute_v3(vec![Call { + to: contract_address, + selector: selector!("panic"), + calldata: vec![], + }]); + // submit default resource bounds to avoud a fee estimate because it would fail + let resource_bounds_default = ResourceBoundsMappingParams::default(); + let result = execution + .l1_gas_price(resource_bounds_default.l1_gas.max_price_per_unit) + .l1_gas(resource_bounds_default.l1_gas.max_amount) + .l2_gas_price(resource_bounds_default.l2_gas.max_price_per_unit) + .l2_gas(600000) // the txn uses 590720, so proving a little extra + .l1_data_gas_price(resource_bounds_default.l1_data_gas.max_price_per_unit) + .l1_data_gas(resource_bounds_default.l1_data_gas.max_amount) + .tip(0) .send() .await .unwrap(); @@ -544,9 +566,11 @@ async fn test_get_receipt_reverted_transaction( .await .unwrap(); - // Receipt should have no events since transaction reverted + // Receipt should have one event (fee transfer) since transaction reverted assert_matches!(receipt.execution_status, ExecutionStatus::Reverted { .. }); - assert_eq!(receipt.events.len(), 0); + assert_eq!(receipt.events.len(), 1); + assert_fee_transfer_event(&receipt.events); + assert_eq!(receipt.transaction_hash, result.transaction_hash.into()); } #[rstest] @@ -603,9 +627,10 @@ async fn test_get_receipt_declare_transaction( .await .unwrap(); - // Declare transaction should have no events + // Declare transaction should have one event (fee transfer) assert_matches!(receipt.execution_status, ExecutionStatus::Succeeded); - assert_eq!(receipt.events.len(), 0); + assert_eq!(receipt.events.len(), 1); + assert_fee_transfer_event(&receipt.events); assert_eq!( receipt.transaction_hash, declare_result.transaction_hash.into() @@ -661,11 +686,13 @@ async fn test_get_receipt_deploy_account_transaction( .await .unwrap(); - // Declare transaction should have no events + // Deploy account transaction should have OwnerAdded event and fee transfer event assert_matches!(receipt.execution_status, ExecutionStatus::Succeeded); - assert_eq!(receipt.events.len(), 1); + assert_eq!(receipt.events.len(), 2); // OwnerAdded event assert_eq!(receipt.events[0].keys[0], selector!("OwnerAdded").into()); + // Fee transfer event + assert_fee_transfer_event(&receipt.events); } #[rstest] @@ -705,8 +732,6 @@ async fn test_get_receipt_missing_required_read_type( selector: selector!("emit_event"), calldata: vec![], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); diff --git a/crates/handlers/starknet/src/tests/read_data/mod.rs b/crates/handlers/starknet/src/tests/read_data/mod.rs index eb2f74a..68fadb1 100644 --- a/crates/handlers/starknet/src/tests/read_data/mod.rs +++ b/crates/handlers/starknet/src/tests/read_data/mod.rs @@ -2,7 +2,7 @@ use assert_matches::assert_matches; use rstest::*; use starknet::{ accounts::Account, - core::types::{BlockId, BlockTag, BlockWithTxHashes, MaybePendingBlockWithTxHashes}, + core::types::{BlockId, BlockTag, BlockWithTxHashes, MaybePreConfirmedBlockWithTxHashes}, }; use crate::tests::utils::{ @@ -188,10 +188,10 @@ mod tests { .await { Ok(block) => match block { - MaybePendingBlockWithTxHashes::PendingBlock(_) => { + MaybePreConfirmedBlockWithTxHashes::PreConfirmedBlock(_) => { unreachable!("Asked for latest but received pending block") } - MaybePendingBlockWithTxHashes::Block(block) => { + MaybePreConfirmedBlockWithTxHashes::Block(block) => { if block.block_number >= block_number { return Ok(block); } @@ -279,8 +279,6 @@ mod tests { purpose, // purposes ], }]) - .gas(0) - .gas_price(0) .send() .await .unwrap(); diff --git a/crates/handlers/starknet/src/tests/send_transaction/mod.rs b/crates/handlers/starknet/src/tests/send_transaction/mod.rs index fd0b553..08ace02 100644 --- a/crates/handlers/starknet/src/tests/send_transaction/mod.rs +++ b/crates/handlers/starknet/src/tests/send_transaction/mod.rs @@ -58,7 +58,7 @@ async fn test_add_invoke_transaction( // Sign the message let nonce = provider .get_nonce( - BlockId::Tag(BlockTag::Pending), + BlockId::Tag(BlockTag::PreConfirmed), accounts[0].account.address(), ) .await @@ -68,11 +68,19 @@ async fn test_add_invoke_transaction( selector: selector!("hello_world"), calldata: vec![], }]; + + let execution = accounts[0].account.execute_v3(calls.clone()); + let fee_estimate = execution.estimate_fee().await.unwrap(); let txn_hash = accounts[0] .account .execute_v3(calls.clone()) - .gas(0) - .gas_price(0) + .l1_gas_price(fee_estimate.l1_gas_price) + .l1_gas(fee_estimate.l1_gas_consumed) + .l2_gas_price(fee_estimate.l2_gas_price) + .l2_gas(fee_estimate.l2_gas_consumed) + .l1_data_gas_price(fee_estimate.l1_data_gas_price) + .l1_data_gas(fee_estimate.l1_data_gas_consumed) + .tip(0) .nonce(nonce) .prepared() .unwrap() @@ -89,6 +97,7 @@ async fn test_add_invoke_transaction( .into_iter() .map(|x| x.into()) .collect(), + resource_bounds: fee_estimate.into(), }, ) .await diff --git a/crates/handlers/starknet/src/tests/utils/madara.rs b/crates/handlers/starknet/src/tests/utils/madara.rs index 6c4a6eb..d948f3a 100644 --- a/crates/handlers/starknet/src/tests/utils/madara.rs +++ b/crates/handlers/starknet/src/tests/utils/madara.rs @@ -1,7 +1,5 @@ #![allow(clippy::print_stdout, clippy::print_stderr)] -use super::starknet::PREDEPLOYED_ACCOUNT_CLASS_HASH; -use crate::utils::{deploy_account, BuildAccount}; use crate::{StarknetProvider, StarknetWallet}; use anyhow::{anyhow, Result}; use reqwest::Client; @@ -22,16 +20,16 @@ use std::{ use tokio::time::sleep; use units_tests_utils::port::{get_free_port, PortAllocation}; use units_tests_utils::units::ChainBackend; -use units_tests_utils::workspace::WORKSPACE_ROOT; use url::Url; use uuid::Uuid; -const MADARA_BINARY_PATH: &str = "crates/handlers/starknet/src/tests/build/madara"; +const MADARA_DOCKER_IMAGE: &str = "ghcr.io/madara-alliance/madara:manual-2ba7dbd"; pub struct MadaraRunner { port_allocation: Option, process: Option, temp_dir: Option, + container_id: Option, } impl MadaraRunner { @@ -40,6 +38,7 @@ impl MadaraRunner { port_allocation: None, process: None, temp_dir: None, + container_id: None, }) } @@ -52,27 +51,50 @@ impl MadaraRunner { let temp_dir = std::env::temp_dir().join(format!("madara-{}", Uuid::new_v4())); fs::create_dir_all(&temp_dir)?; - // Get binary path from workspace root - let madara_path = WORKSPACE_ROOT.join(MADARA_BINARY_PATH); - println!("madara_path: {}", madara_path.display()); + // Pull the latest Madara Docker image + println!("Pulling Madara Docker image: {MADARA_DOCKER_IMAGE}"); + let pull_output = Command::new("docker") + .arg("pull") + .arg("--platform") + .arg("amd64") + .arg(MADARA_DOCKER_IMAGE) + .output()?; - // Start the Madara process - let mut process = Command::new(madara_path) + if !pull_output.status.success() { + return Err(anyhow!( + "Failed to pull Madara Docker image: {}", + String::from_utf8_lossy(&pull_output.stderr) + )); + } + + // Generate a unique container name + let container_name = format!("madara-test-{}", Uuid::new_v4()); + + // Start the Madara Docker container + let mut process = Command::new("docker") + .arg("run") + .arg("--rm") + .arg("--name") + .arg(&container_name) + .arg("-p") + .arg(format!("{port}:9944")) + .arg("-v") + .arg(format!("{}:/data", temp_dir.to_str().unwrap())) + .arg(MADARA_DOCKER_IMAGE) .arg("--devnet") .arg("--rpc-port") - .arg(port.to_string()) + .arg("9944") + .arg("--rpc-external") // Use the internal port, Docker will map it .arg("--base-path") - .arg(temp_dir.to_str().unwrap()) - .arg("--gas-price") - .arg("0") + .arg("/data") + .arg("--l1-gas-price") + .arg("1") .arg("--blob-gas-price") - .arg("0") - .arg("--strk-gas-price") - .arg("0") - .arg("--strk-blob-gas-price") - .arg("0") + .arg("1") + .arg("--strk-per-eth") + .arg("1") .arg("--chain-config-override") - .arg("pending_block_update_time=200ms,block_time=2s") + .arg("block_time=2s,l2_gas_price.type=fixed,l2_gas_price.price=2500") .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn()?; @@ -85,31 +107,33 @@ impl MadaraRunner { thread::spawn(move || { let reader = BufReader::new(stdout); for line in reader.lines().map_while(Result::ok) { - println!("[MADARA] {}", line); + println!("[MADARA] {line}"); } }); thread::spawn(move || { let reader = BufReader::new(stderr); for line in reader.lines().map_while(Result::ok) { - eprintln!("[MADARA] {}", line); + eprintln!("[MADARA] {line}"); } }); self.process = Some(process); self.port_allocation = Some(port_allocation); self.temp_dir = Some(temp_dir); + self.container_id = Some(container_name); // Wait for Madara to be ready by polling the health endpoint let client = Client::new(); - let url = format!("http://localhost:{}/health", port); + let url = format!("http://localhost:{port}/health"); let mut attempts = 0; - const MAX_ATTEMPTS: u32 = 10; + const MAX_ATTEMPTS: u32 = 10; // Increased timeout for Docker startup while attempts < MAX_ATTEMPTS { match client.get(&url).send().await { Ok(response) if response.status().is_success() => { + println!("Madara is ready on port {port}"); return Ok(()); } _ => { @@ -120,8 +144,7 @@ impl MadaraRunner { } Err(anyhow!( - "Madara failed to start after {} seconds", - MAX_ATTEMPTS + "Madara failed to start after {MAX_ATTEMPTS} seconds", )) } @@ -140,11 +163,21 @@ impl MadaraRunner { impl Drop for MadaraRunner { fn drop(&mut self) { + // Stop the Docker container + if let Some(container_id) = self.container_id.take() { + println!("Stopping Madara container: {container_id}"); + let _ = Command::new("docker") + .arg("stop") + .arg(&container_id) + .output(); + } + if let Some(mut process) = self.process.take() { // Try to kill the process gracefully let _ = process.kill(); let _ = process.wait(); // Wait for the process to be killed } + // Clean up the temporary directory if let Some(temp_dir) = self.temp_dir.take() { let _ = fs::remove_dir_all(temp_dir); @@ -194,6 +227,7 @@ impl StarknetWalletWithPrivateKey { /// Returns a running Madara node, configured Starknet provider, and a vector of deployed accounts #[fixture] +#[cfg(test)] pub async fn madara_node_with_accounts( #[default(1)] num_accounts: u32, ) -> ( @@ -201,6 +235,9 @@ pub async fn madara_node_with_accounts( Arc, Vec, ) { + use super::starknet::PREDEPLOYED_ACCOUNT_CLASS_HASH; + use crate::utils::{deploy_account, BuildAccount}; + let (runner, provider) = madara_node().await; let mut accounts = Vec::new(); diff --git a/crates/handlers/starknet/src/tests/utils/scarb.rs b/crates/handlers/starknet/src/tests/utils/scarb.rs index 8cb936b..e25c080 100644 --- a/crates/handlers/starknet/src/tests/utils/scarb.rs +++ b/crates/handlers/starknet/src/tests/utils/scarb.rs @@ -45,10 +45,7 @@ pub async fn scarb_build(#[default(".")] path: impl AsRef) -> ArtifactsMap if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr); let stdout = String::from_utf8_lossy(&output.stdout); - eprintln!( - "Scarb build failed!\nStdout: {}\nStderr: {}", - stdout, stderr - ); + eprintln!("Scarb build failed!\nStdout: {stdout}\nStderr: {stderr}",); panic!("Scarb build failed"); } @@ -157,7 +154,7 @@ impl Artifacts { let class_hash = self.class_hash; if account .provider() - .get_class(BlockId::Tag(BlockTag::Pending), class_hash) + .get_class(BlockId::Tag(BlockTag::PreConfirmed), class_hash) .await .is_ok() { diff --git a/crates/handlers/starknet/src/tests/utils/starknet.rs b/crates/handlers/starknet/src/tests/utils/starknet.rs index 968acc1..056c1c1 100644 --- a/crates/handlers/starknet/src/tests/utils/starknet.rs +++ b/crates/handlers/starknet/src/tests/utils/starknet.rs @@ -1,13 +1,14 @@ -use crate::utils::{deploy_account, wait_for_receipt, BuildAccount}; +use crate::utils::wait_for_receipt; use crate::{StarknetContext, StarknetProvider, StarknetWallet}; +use anyhow::Context; +use starknet::providers::Provider; use starknet::{ accounts::{Account, ConnectedAccount, ExecutionEncoding, SingleOwnerAccount}, core::types::{ - Call, CallType, ComputationResources, ContractClass, DataAvailabilityResources, - DataResources, DeclareTransactionTrace, DeployAccountTransactionTrace, EntryPointType, - ExecuteInvocation, ExecutionResources, Felt, FlattenedSierraClass, FunctionInvocation, - InvokeTransactionResult, InvokeTransactionTrace, L1HandlerTransactionTrace, - TransactionReceiptWithBlockInfo, + Call, CallType, ContractClass, DeclareTransactionTrace, DeployAccountTransactionTrace, + EntryPointType, ExecuteInvocation, ExecutionResources, Felt, FlattenedSierraClass, + FunctionInvocation, InnerCallExecutionResources, InvokeTransactionResult, + InvokeTransactionTrace, L1HandlerTransactionTrace, TransactionReceiptWithBlockInfo, }, macros::selector, providers::jsonrpc::HttpTransport, @@ -19,75 +20,65 @@ use url::Url; pub const PREDEPLOYED_ACCOUNT_CLASS_HASH: &str = "0x00e2eb8f5672af4e6a4e8a8f1b44989685e668489b0a25437733756c5a34a1d6"; -pub const ETH_TOKEN_ADDRESS: &str = - "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"; +pub const STRK_TOKEN_ADDRESS: &str = + "0x04718f5a0Fc34cC1AF16A1cdee98fFB20C31f5cD61D6Ab07201858f4287c938D"; pub const PREDEPLOYED_ACCOUNT_ADDRESS: &str = "0x055be462e718c4166d656d11f89e341115b8bc82389c3762a10eade04fcb225d"; - -pub async fn deploy_dummy_account( - provider: Arc, -) -> anyhow::Result> { - let private_key = Felt::ONE; - deploy_account( - provider.clone(), - private_key, - Felt::from_hex_unchecked(PREDEPLOYED_ACCOUNT_CLASS_HASH), - ) - .await - .expect("Failed to deploy account") - .wait_for_receipt_and_build_account(provider.clone(), private_key) - .await -} +pub const PREDEPLOYED_ACCOUNT_PRIVATE_KEY: &str = + "0x077e56c6dc32d40a67f6f7e6625c8dc5e570abe49c0a24e9202e4ae906abcc07"; pub async fn dummy_transfer( wallet: Arc, Arc>>, + recipient: Felt, + amount: Felt, ) -> anyhow::Result<(InvokeTransactionResult, TransactionReceiptWithBlockInfo)> { let txn = wallet .execute_v3(vec![Call { - to: Felt::from_hex_unchecked(ETH_TOKEN_ADDRESS), + to: Felt::from_hex_unchecked(STRK_TOKEN_ADDRESS), selector: selector!("transfer"), calldata: vec![ - Felt::from_hex_unchecked("0x1"), // recipient - Felt::from_hex_unchecked("0x0"), // amount_low + recipient, // recipient + amount, // amount_low Felt::from_hex_unchecked("0x0"), // amount_high ], }]) - .gas(0) - .gas_price(0) .send() - .await?; + .await + .context("Failed to transfer")?; let receipt = wait_for_receipt(wallet.provider().clone(), txn.transaction_hash, None).await?; Ok((txn, receipt)) } -pub fn build_computation_resources() -> ComputationResources { - ComputationResources { - steps: 0, - memory_holes: None, - range_check_builtin_applications: None, - pedersen_builtin_applications: None, - poseidon_builtin_applications: None, - ec_op_builtin_applications: None, - ecdsa_builtin_applications: None, - bitwise_builtin_applications: None, - keccak_builtin_applications: None, - segment_arena_builtin: None, - } -} - -pub fn build_data_resources() -> DataResources { - DataResources { - data_availability: DataAvailabilityResources { - l1_gas: 0, - l1_data_gas: 0, - }, - } +pub async fn fund_account_devnet( + provider: Arc, + account_address: Felt, +) -> anyhow::Result<()> { + // Funding account using predeployed devnet account + let signer = + SigningKey::from_secret_scalar(Felt::from_hex_unchecked(PREDEPLOYED_ACCOUNT_PRIVATE_KEY)); + let local_wallet = Arc::new(LocalWallet::from(signer)); + let predeployed_account_devnet = SingleOwnerAccount::new( + provider.clone(), + local_wallet, + Felt::from_hex_unchecked(PREDEPLOYED_ACCOUNT_ADDRESS), + provider.chain_id().await?, + ExecutionEncoding::New, + ); + dummy_transfer( + Arc::new(predeployed_account_devnet), + account_address, + Felt::from_dec_str("1000000000000000000").unwrap(), // 10^18 + ) + .await + .context("Failed to fund account")?; + Ok(()) } pub fn build_execution_resources() -> ExecutionResources { ExecutionResources { - computation_resources: build_computation_resources(), - data_resources: build_data_resources(), + l1_gas: 0, + l1_data_gas: 0, + l2_gas: 0, } } @@ -104,7 +95,11 @@ pub fn build_function_invocation() -> FunctionInvocation { calls: vec![], events: vec![], messages: vec![], - execution_resources: build_computation_resources(), + execution_resources: InnerCallExecutionResources { + l1_gas: 0, + l2_gas: 0, + }, + is_reverted: false, } } @@ -139,7 +134,7 @@ pub fn build_deploy_account_trace() -> DeployAccountTransactionTrace { pub fn build_l1_handler_trace() -> L1HandlerTransactionTrace { L1HandlerTransactionTrace { - function_invocation: build_function_invocation(), + function_invocation: ExecuteInvocation::Success(build_function_invocation()), state_diff: None, execution_resources: build_execution_resources(), } diff --git a/crates/handlers/starknet/src/utils.rs b/crates/handlers/starknet/src/utils.rs index 04b6a02..b1c0767 100644 --- a/crates/handlers/starknet/src/utils.rs +++ b/crates/handlers/starknet/src/utils.rs @@ -4,20 +4,17 @@ use std::{ }; use starknet::{ - accounts::{ - Account, AccountFactory, ExecutionEncoding, OpenZeppelinAccountFactory, SingleOwnerAccount, - }, + accounts::{Account, ExecutionEncoding, SingleOwnerAccount}, contract::ContractFactory, core::{ crypto::compute_hash_on_elements, types::{ - BlockId, BlockTag, BroadcastedInvokeTransaction, BroadcastedInvokeTransactionV3, - BroadcastedTransaction, Call, ContractClass, DataAvailabilityMode, DeclareTransaction, - DeclareTransactionResult, DeployAccountTransaction, DeployAccountTransactionResult, - ExecuteInvocation, Felt, FlattenedSierraClass, FunctionInvocation, InvokeTransaction, - InvokeTransactionResult, NonZeroFelt, OrderedEvent, ResourceBounds, - ResourceBoundsMapping, SimulatedTransaction, SimulationFlag, Transaction, - TransactionReceiptWithBlockInfo, TransactionTrace, + BlockId, BlockTag, BroadcastedInvokeTransactionV3, BroadcastedTransaction, Call, + ContractClass, DataAvailabilityMode, DeclareTransaction, DeclareTransactionResult, + DeployAccountTransaction, DeployAccountTransactionResult, ExecuteInvocation, Felt, + FlattenedSierraClass, FunctionInvocation, InvokeTransaction, InvokeTransactionResult, + NonZeroFelt, OrderedEvent, ResourceBounds, ResourceBoundsMapping, SimulatedTransaction, + SimulationFlag, Transaction, TransactionReceiptWithBlockInfo, TransactionTrace, }, }, providers::{Provider, ProviderError}, @@ -83,9 +80,15 @@ impl GetExecutionResult for SimulatedTransaction { } TransactionTrace::L1Handler(l1_handler_transaction) => { // L1 Handler transactions won't exist on the chain if they failed - Ok(ExecuteInvocation::Success( - l1_handler_transaction.function_invocation.clone(), - )) + // Extract FunctionInvocation from ExecuteInvocation + match l1_handler_transaction.function_invocation.clone() { + ExecuteInvocation::Success(function_invocation) => { + Ok(ExecuteInvocation::Success(function_invocation)) + } + ExecuteInvocation::Reverted(reverted_invocation) => { + Ok(ExecuteInvocation::Reverted(reverted_invocation)) + } + } } } } @@ -145,28 +148,6 @@ pub async fn wait_for_receipt( } } -pub async fn deploy_account( - provider: Arc, - private_key: Felt, - class_hash: Felt, -) -> anyhow::Result { - let signer = Arc::new(LocalWallet::from(SigningKey::from_secret_scalar( - private_key, - ))); - let chain_id = provider.chain_id().await?; - let account_factory = - OpenZeppelinAccountFactory::new(class_hash, chain_id, signer.clone(), provider.clone()) - .await?; - - // Create a deploy account transaction - Ok(account_factory - .deploy_v3(Felt::ONE) - .gas(0) - .gas_price(0) - .send() - .await?) -} - #[allow(async_fn_in_trait)] pub trait BuildAccount: WaitForReceipt { async fn build_account( @@ -203,7 +184,7 @@ impl BuildAccount for DeployAccountTransactionResult { chain_id, ExecutionEncoding::New, ); - account.set_block_id(BlockId::Tag(BlockTag::Pending)); + account.set_block_id(BlockId::Tag(BlockTag::PreConfirmed)); Ok(Arc::new(account)) } @@ -216,8 +197,6 @@ pub async fn declare_contract( ) -> anyhow::Result { Ok(account .declare_v3(contract_class, compiled_class_hash) - .gas(0) - .gas_price(0) .send() .await?) } @@ -229,11 +208,9 @@ pub async fn deploy_contract( salt: Felt, unique: bool, ) -> anyhow::Result<(InvokeTransactionResult, Felt)> { + #[allow(deprecated)] let contract_factory = ContractFactory::new(class_hash, account.clone()); - let deployment = contract_factory - .deploy_v3(constructor_calldata, salt, unique) - .gas(0) - .gas_price(0); + let deployment = contract_factory.deploy_v3(constructor_calldata, salt, unique); let deployed_address = deployment.deployed_address(); let invoke_result = deployment.send().await?; @@ -289,7 +266,7 @@ pub async fn build_invoke_simulate_transaction( provider: Arc, ) -> Result { let nonce = provider - .get_nonce(BlockId::Tag(BlockTag::Pending), account_address) + .get_nonce(BlockId::Tag(BlockTag::PreConfirmed), account_address) .await?; Ok(BroadcastedInvokeTransactionV3 { @@ -306,6 +283,10 @@ pub async fn build_invoke_simulate_transaction( max_amount: 0, max_price_per_unit: 0, }, + l1_data_gas: ResourceBounds { + max_amount: 0, + max_price_per_unit: 0, + }, }, // Fee market has not been been activated yet so it's hard-coded to be 0 tip: 0, @@ -342,8 +323,8 @@ pub async fn simulate_calls( let simulated_txn = provider .simulate_transaction( - BlockId::Tag(BlockTag::Pending), - BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction::V3(simulation)), + BlockId::Tag(BlockTag::PreConfirmed), + BroadcastedTransaction::Invoke(simulation), vec![SimulationFlag::SkipFeeCharge, SimulationFlag::SkipValidate], ) .await?; @@ -517,6 +498,33 @@ impl ToFelt, ChainHandlerError> for Vec { } } +#[cfg(test)] +pub async fn deploy_account( + provider: Arc, + private_key: Felt, + class_hash: Felt, +) -> anyhow::Result { + use starknet::accounts::{AccountFactory, OpenZeppelinAccountFactory}; + + use crate::tests::utils::starknet::fund_account_devnet; + + let signer = Arc::new(LocalWallet::from(SigningKey::from_secret_scalar( + private_key, + ))); + let chain_id = provider.chain_id().await?; + let account_factory = + OpenZeppelinAccountFactory::new(class_hash, chain_id, signer.clone(), provider.clone()) + .await?; + let account_deployment = account_factory.deploy_v3(Felt::ONE); + let account_address = account_deployment.address(); + + // Funding account before deployment + fund_account_devnet(provider.clone(), account_address).await?; + + // Create a deploy account transaction + Ok(account_deployment.send().await?) +} + #[cfg(test)] mod tests { use super::*; @@ -535,8 +543,7 @@ mod tests { use starknet::{ accounts::Account, core::types::{ - BlockTag, ExecutionResult, FeeEstimate, InvokeTransactionTrace, PriceUnit, - RevertedInvocation, + BlockTag, ExecutionResult, FeeEstimate, InvokeTransactionTrace, RevertedInvocation, }, macros::selector, }; @@ -550,13 +557,13 @@ mod tests { match get_contract_class( provider.clone(), Felt::from_hex_unchecked(PREDEPLOYED_ACCOUNT_ADDRESS), - BlockId::Tag(BlockTag::Latest), + BlockId::Tag(BlockTag::PreConfirmed), ) .await { Ok(_) => {} Err(e) => { - panic!("Failed to get contract class: {:?}", e); + panic!("Failed to get contract class: {e:?}"); } } } @@ -572,7 +579,7 @@ mod tests { let contract_class = get_contract_class( provider.clone(), Felt::from_hex_unchecked(PREDEPLOYED_ACCOUNT_ADDRESS), - BlockId::Tag(BlockTag::Latest), + BlockId::Tag(BlockTag::PreConfirmed), ) .await .unwrap(); @@ -598,7 +605,7 @@ mod tests { assert!(contract_address_has_selector( provider.clone(), Felt::from_hex_unchecked(PREDEPLOYED_ACCOUNT_ADDRESS), - BlockId::Tag(BlockTag::Latest), + BlockId::Tag(BlockTag::PreConfirmed), execute_selector ) .await @@ -609,7 +616,7 @@ mod tests { assert!(!contract_address_has_selector( provider.clone(), Felt::from_hex_unchecked(PREDEPLOYED_ACCOUNT_ADDRESS), - BlockId::Tag(BlockTag::Latest), + BlockId::Tag(BlockTag::PreConfirmed), random_selector ) .await @@ -635,12 +642,13 @@ mod tests { let simulated_transaction = SimulatedTransaction { transaction_trace: trace, fee_estimation: FeeEstimate { - gas_consumed: 0.into(), - gas_price: 0.into(), - data_gas_consumed: 0.into(), - data_gas_price: 0.into(), - overall_fee: 0.into(), - unit: PriceUnit::Wei, + l1_gas_consumed: 0, + l1_gas_price: 0, + l2_gas_consumed: 0, + l2_gas_price: 0, + l1_data_gas_consumed: 0, + l1_data_gas_price: 0, + overall_fee: 0, }, }; @@ -655,12 +663,13 @@ mod tests { let simulated_transaction = SimulatedTransaction { transaction_trace: trace, fee_estimation: FeeEstimate { - gas_consumed: 0.into(), - gas_price: 0.into(), - data_gas_consumed: 0.into(), - data_gas_price: 0.into(), - overall_fee: 0.into(), - unit: PriceUnit::Wei, + l1_gas_consumed: 0, + l1_gas_price: 0, + l2_gas_consumed: 0, + l2_gas_price: 0, + l1_data_gas_consumed: 0, + l1_data_gas_price: 0, + overall_fee: 0, }, }; @@ -678,12 +687,13 @@ mod tests { let simulated_transaction = SimulatedTransaction { transaction_trace: trace, fee_estimation: FeeEstimate { - gas_consumed: 0.into(), - gas_price: 0.into(), - data_gas_consumed: 0.into(), - data_gas_price: 0.into(), - overall_fee: 0.into(), - unit: PriceUnit::Wei, + l1_gas_consumed: 0, + l1_gas_price: 0, + l2_gas_consumed: 0, + l2_gas_price: 0, + l1_data_gas_consumed: 0, + l1_data_gas_price: 0, + overall_fee: 0, }, }; @@ -698,26 +708,25 @@ mod tests { #[test] fn test_get_execution_result_l1_handler() { let l1_handler_trace = build_l1_handler_trace(); - let function_invocation = l1_handler_trace.function_invocation.clone(); + let expected_invocation = l1_handler_trace.function_invocation.clone(); let trace = TransactionTrace::L1Handler(l1_handler_trace); let simulated_transaction = SimulatedTransaction { transaction_trace: trace, fee_estimation: FeeEstimate { - gas_consumed: 0.into(), - gas_price: 0.into(), - data_gas_consumed: 0.into(), - data_gas_price: 0.into(), - overall_fee: 0.into(), - unit: PriceUnit::Wei, + l1_gas_consumed: 0, + l1_gas_price: 0, + l2_gas_consumed: 0, + l2_gas_price: 0, + l1_data_gas_consumed: 0, + l1_data_gas_price: 0, + overall_fee: 0, }, }; let result = simulated_transaction.get_execution_result(); assert!(result.is_ok()); - assert_eq!( - result.unwrap(), - ExecuteInvocation::Success(function_invocation) - ); + // The result should match the expected ExecuteInvocation + assert_eq!(result.unwrap(), expected_invocation); } #[rstest] @@ -733,7 +742,9 @@ mod tests { let account = accounts_with_private_key[0].account.clone(); // Do a simple transfer - let (execution, _) = dummy_transfer(account.clone()).await.unwrap(); + let (execution, _) = dummy_transfer(account.clone(), Felt::ONE, Felt::ZERO) + .await + .unwrap(); // Wait for receipt let receipt = wait_for_receipt(provider, execution.transaction_hash, None) @@ -789,7 +800,7 @@ mod tests { // Verify the deployment by checking the class hash at the deployed address let deployed_class_hash = provider - .get_class_hash_at(BlockId::Tag(BlockTag::Pending), account.address()) + .get_class_hash_at(BlockId::Tag(BlockTag::PreConfirmed), account.address()) .await .expect("Failed to get class hash"); diff --git a/crates/primitives/src/rpc.rs b/crates/primitives/src/rpc.rs index 234ca20..8ebe5fe 100644 --- a/crates/primitives/src/rpc.rs +++ b/crates/primitives/src/rpc.rs @@ -3,6 +3,7 @@ use std::{fmt::Display, str::FromStr}; use crate::{read_data::SignedReadData, types::ClassVisibility}; use serde::{Deserialize, Serialize}; +use starknet::core::types::FeeEstimate; use starknet_crypto::Felt; // TODO: Move away from using Felt and standardize on Bytes32 throughout the codebase. @@ -34,7 +35,7 @@ impl Bytes32 { let hex_str = hex_str.strip_prefix("0x").unwrap_or(hex_str); // If hex string has odd length, prefix with '0' to make it even let hex_str = if hex_str.len() % 2 != 0 { - format!("0{}", hex_str) + format!("0{hex_str}") } else { hex_str.to_string() }; @@ -168,6 +169,7 @@ pub struct DeclareProgramParams { pub program: serde_json::Value, pub compiled_program_hash: Option, pub class_visibility: ClassVisibility, + pub resource_bounds: ResourceBoundsMappingParams, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -177,6 +179,60 @@ pub struct DeclareTransactionResult { pub acl_updated: bool, } +/// Resource bounds for a transaction +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct ResourceBoundsParams { + pub max_amount: u64, + pub max_price_per_unit: u128, +} + +/// Resource bounds mapping for L1 gas, L1 data gas, and L2 gas +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct ResourceBoundsMappingParams { + pub l1_gas: ResourceBoundsParams, + pub l1_data_gas: ResourceBoundsParams, + pub l2_gas: ResourceBoundsParams, +} + +impl Default for ResourceBoundsMappingParams { + fn default() -> Self { + Self { + l1_gas: ResourceBoundsParams { + max_amount: 10000, + max_price_per_unit: 1, + }, + l1_data_gas: ResourceBoundsParams { + max_amount: 10000, + max_price_per_unit: 1, + }, + l2_gas: ResourceBoundsParams { + max_amount: 520000, + max_price_per_unit: 2500, + }, + } + } +} + +impl From for ResourceBoundsMappingParams { + fn from(fee_estimate: FeeEstimate) -> Self { + Self { + l1_gas: ResourceBoundsParams { + max_amount: fee_estimate.l1_gas_consumed, + max_price_per_unit: fee_estimate.l1_gas_price, + }, + + l1_data_gas: ResourceBoundsParams { + max_amount: fee_estimate.l1_data_gas_consumed, + max_price_per_unit: fee_estimate.l1_data_gas_price, + }, + l2_gas: ResourceBoundsParams { + max_amount: fee_estimate.l2_gas_consumed, + max_price_per_unit: fee_estimate.l2_gas_price, + }, + } + } +} + /// Parameters and result for deploying an account #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct DeployAccountParams { @@ -185,6 +241,7 @@ pub struct DeployAccountParams { pub constructor_calldata: Vec, pub program_hash: Bytes32, pub account_address_salt: Bytes32, + pub resource_bounds: ResourceBoundsMappingParams, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -200,6 +257,7 @@ pub struct SendTransactionParams { pub signature: Vec, pub nonce: Nonce, pub calldata: Vec, + pub resource_bounds: ResourceBoundsMappingParams, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -312,7 +370,7 @@ mod tests { Err(error) => match (error, expected_error) { (Bytes32Error::TooLong, Bytes32Error::TooLong) => (), (Bytes32Error::InvalidHex(e1), Bytes32Error::InvalidHex(e2)) => { - assert_eq!(format!("{:?}", e1), format!("{:?}", e2)) + assert_eq!(format!("{e1:?}"), format!("{:?}", e2)) } _ => panic!("Unexpected error"), }, diff --git a/crates/proc-macros/src/lib.rs b/crates/proc-macros/src/lib.rs index 7868c55..e871b22 100644 --- a/crates/proc-macros/src/lib.rs +++ b/crates/proc-macros/src/lib.rs @@ -38,8 +38,8 @@ //! **Arguments:** //! - `name`: rpc method name, must not be a duplicate in the current namespace. //! - `and_versions`: implementations of this method will also work for the -//! supplied versions. Note that these versions must not already contain -//! a method with the same name. +//! supplied versions. Note that these versions must not already contain +//! a method with the same name. //! //! # Example: //! @@ -291,7 +291,7 @@ pub fn versioned_rpc(attr: TokenStream, input: TokenStream) -> TokenStream { if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(version), attrs }) = elem { let version_str = version.value(); validate_version(&version_str)?; - let method_with_version = format!("{namespace}_{}_{method}", version_str); + let method_with_version = format!("{namespace}_{version_str}_{method}"); let lit = syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(syn::LitStr::new(&method_with_version, version.span())), diff --git a/crates/rpc/src/lib.rs b/crates/rpc/src/lib.rs index 2aa0c36..ef8e337 100644 --- a/crates/rpc/src/lib.rs +++ b/crates/rpc/src/lib.rs @@ -3,7 +3,6 @@ use std::sync::Arc; use jsonrpsee::RpcModule; use units_primitives::context::GlobalContext; -mod starknet; mod units; /// A Starknet RPC server for Madara @@ -22,17 +21,6 @@ impl RpcContext { pub fn rpc_api_user(rpc_ctx: &RpcContext) -> anyhow::Result> { let mut rpc_api = RpcModule::new(()); - // Starknet - rpc_api.merge(starknet::v0_7_1::StarknetReadRpcApiV0_7_1Server::into_rpc( - rpc_ctx.clone(), - ))?; - rpc_api.merge(starknet::v0_7_1::StarknetWriteRpcApiV0_7_1Server::into_rpc( - rpc_ctx.clone(), - ))?; - rpc_api.merge(starknet::v0_7_1::StarknetTraceRpcApiV0_7_1Server::into_rpc( - rpc_ctx.clone(), - ))?; - // Units rpc_api.merge(units::v0_1_0::UnitsReadRpcApiV0_1_0Server::into_rpc( rpc_ctx.clone(), diff --git a/crates/rpc/src/starknet/errors.rs b/crates/rpc/src/starknet/errors.rs deleted file mode 100644 index 803de0f..0000000 --- a/crates/rpc/src/starknet/errors.rs +++ /dev/null @@ -1,208 +0,0 @@ -use jsonrpsee::core::Cow; -use serde_json::json; -use starknet::providers::ProviderError; -use units_primitives::context::ChainHandlerError; - -// Comes from the RPC Spec: -// https://github.com/starkware-libs/starknet-specs/blob/0e859ff905795f789f1dfd6f7340cdaf5015acc8/api/starknet_write_api.json#L227 -#[cfg_attr(test, derive(PartialEq, Eq))] -#[derive(thiserror::Error, Debug)] -pub enum StarknetRpcApiError { - #[error("Failed to write transaction")] - FailedToReceiveTxn { err: Option> }, - #[error("Contract not found")] - ContractNotFound, - #[error("Block not found")] - BlockNotFound, - #[error("Invalid transaction hash")] - InvalidTxnHash, - #[error("Invalid tblock hash")] - InvalidBlockHash, - #[error("Invalid transaction index in a block")] - InvalidTxnIndex, - #[error("Class hash not found")] - ClassHashNotFound, - #[error("Transaction hash not found")] - TxnHashNotFound, - #[error("Requested page size is too big")] - PageSizeTooBig, - #[error("There are no blocks")] - NoBlocks, - #[error("The supplied continuation token is invalid or unknown")] - InvalidContinuationToken, - #[error("Too many keys provided in a filter")] - TooManyKeysInFilter, - #[error("Failed to fetch pending transactions")] - FailedToFetchPendingTransactions, - #[error("Contract error")] - ContractError, - #[error("Transaction execution error")] - TxnExecutionError { tx_index: usize, error: String }, - #[error("Invalid contract class")] - InvalidContractClass, - #[error("Class already declared")] - ClassAlreadyDeclared, - #[error("Invalid transaction nonce")] - InvalidTxnNonce, - #[error("Max fee is smaller than the minimal transaction cost (validation plus fee transfer)")] - InsufficientMaxFee, - #[error("Account balance is smaller than the transaction's max_fee")] - InsufficientAccountBalance, - #[error("Account validation failed")] - ValidationFailure { error: Cow<'static, str> }, - #[error("Compilation failed")] - CompilationFailed, - #[error("Contract class size is too large")] - ContractClassSizeTooLarge, - #[error("Sender address is not an account contract")] - NonAccount, - #[error("A transaction with the same hash already exists in the mempool")] - DuplicateTxn, - #[error("The compiled class hash did not match the one supplied in the transaction")] - CompiledClassHashMismatch, - #[error("The transaction version is not supported")] - UnsupportedTxnVersion, - #[error("The contract class version is not supported")] - UnsupportedContractClassVersion, - #[error("An unexpected error occurred")] - ErrUnexpectedError { data: String }, - #[error("Internal server error")] - InternalServerError, - #[error("Unimplemented method")] - UnimplementedMethod, -} - -impl From<&StarknetRpcApiError> for i32 { - fn from(err: &StarknetRpcApiError) -> Self { - match err { - StarknetRpcApiError::FailedToReceiveTxn { .. } => 1, - StarknetRpcApiError::ContractNotFound => 20, - StarknetRpcApiError::BlockNotFound => 24, - StarknetRpcApiError::InvalidTxnHash => 25, - StarknetRpcApiError::InvalidBlockHash => 26, - StarknetRpcApiError::InvalidTxnIndex => 27, - StarknetRpcApiError::ClassHashNotFound => 28, - StarknetRpcApiError::TxnHashNotFound => 29, - StarknetRpcApiError::PageSizeTooBig => 31, - StarknetRpcApiError::NoBlocks => 32, - StarknetRpcApiError::InvalidContinuationToken => 33, - StarknetRpcApiError::TooManyKeysInFilter => 34, - StarknetRpcApiError::FailedToFetchPendingTransactions => 38, - StarknetRpcApiError::ContractError => 40, - StarknetRpcApiError::TxnExecutionError { .. } => 41, - StarknetRpcApiError::InvalidContractClass => 50, - StarknetRpcApiError::ClassAlreadyDeclared => 51, - StarknetRpcApiError::InvalidTxnNonce => 52, - StarknetRpcApiError::InsufficientMaxFee => 53, - StarknetRpcApiError::InsufficientAccountBalance => 54, - StarknetRpcApiError::ValidationFailure { .. } => 55, - StarknetRpcApiError::CompilationFailed => 56, - StarknetRpcApiError::ContractClassSizeTooLarge => 57, - StarknetRpcApiError::NonAccount => 58, - StarknetRpcApiError::DuplicateTxn => 59, - StarknetRpcApiError::CompiledClassHashMismatch => 60, - StarknetRpcApiError::UnsupportedTxnVersion => 61, - StarknetRpcApiError::UnsupportedContractClassVersion => 62, - StarknetRpcApiError::ErrUnexpectedError { .. } => 63, - StarknetRpcApiError::InternalServerError => 500, - StarknetRpcApiError::UnimplementedMethod => 501, - } - } -} - -impl StarknetRpcApiError { - pub fn data(&self) -> Option { - match self { - StarknetRpcApiError::ErrUnexpectedError { data } => Some(json!(data)), - StarknetRpcApiError::ValidationFailure { error } => Some(json!(error)), - StarknetRpcApiError::FailedToReceiveTxn { err } => err.as_ref().map(|err| json!(err)), - StarknetRpcApiError::TxnExecutionError { tx_index, error } => Some(json!({ - "transaction_index": tx_index, - "execution_error": error, - })), - _ => None, - } - } -} - -impl From for jsonrpsee::types::ErrorObjectOwned { - fn from(err: StarknetRpcApiError) -> Self { - jsonrpsee::types::ErrorObjectOwned::owned((&err).into(), err.to_string(), err.data()) - } -} - -impl From for StarknetRpcApiError { - fn from(err: ProviderError) -> Self { - use starknet::core::types::StarknetError; - - match err { - ProviderError::StarknetError(starknet_err) => match starknet_err { - StarknetError::TransactionHashNotFound => StarknetRpcApiError::TxnHashNotFound, - StarknetError::ContractNotFound => StarknetRpcApiError::ContractNotFound, - StarknetError::BlockNotFound => StarknetRpcApiError::BlockNotFound, - StarknetError::ClassHashNotFound => StarknetRpcApiError::ClassHashNotFound, - StarknetError::InvalidTransactionNonce => StarknetRpcApiError::InvalidTxnNonce, - StarknetError::InsufficientMaxFee => StarknetRpcApiError::InsufficientMaxFee, - StarknetError::InsufficientAccountBalance => { - StarknetRpcApiError::InsufficientAccountBalance - } - StarknetError::ValidationFailure(err) => { - StarknetRpcApiError::ValidationFailure { error: err.into() } - } - StarknetError::CompilationFailed => StarknetRpcApiError::CompilationFailed, - StarknetError::NonAccount => StarknetRpcApiError::NonAccount, - StarknetError::CompiledClassHashMismatch => { - StarknetRpcApiError::CompiledClassHashMismatch - } - StarknetError::UnsupportedContractClassVersion => { - StarknetRpcApiError::UnsupportedContractClassVersion - } - StarknetError::UnexpectedError(err) => { - StarknetRpcApiError::ErrUnexpectedError { data: err } - } - StarknetError::FailedToReceiveTransaction => { - StarknetRpcApiError::FailedToReceiveTxn { err: None } - } - StarknetError::InvalidTransactionIndex => StarknetRpcApiError::InvalidTxnIndex, - StarknetError::PageSizeTooBig => StarknetRpcApiError::PageSizeTooBig, - StarknetError::NoBlocks => StarknetRpcApiError::NoBlocks, - StarknetError::InvalidContinuationToken => { - StarknetRpcApiError::InvalidContinuationToken - } - StarknetError::TooManyKeysInFilter => StarknetRpcApiError::TooManyKeysInFilter, - StarknetError::ContractError(_) => StarknetRpcApiError::ContractError, - StarknetError::TransactionExecutionError(err) => { - StarknetRpcApiError::TxnExecutionError { - tx_index: err.transaction_index as usize, - error: err.execution_error, - } - } - StarknetError::DuplicateTx => StarknetRpcApiError::DuplicateTxn, - StarknetError::UnsupportedTxVersion => StarknetRpcApiError::UnsupportedTxnVersion, - StarknetError::ClassAlreadyDeclared => StarknetRpcApiError::ClassAlreadyDeclared, - StarknetError::ContractClassSizeIsTooLarge => { - StarknetRpcApiError::ContractClassSizeTooLarge - } - StarknetError::NoTraceAvailable(_) => StarknetRpcApiError::InternalServerError, - }, - ProviderError::RateLimited => StarknetRpcApiError::ErrUnexpectedError { - data: "Rate limited".to_string(), - }, - ProviderError::ArrayLengthMismatch => StarknetRpcApiError::ErrUnexpectedError { - data: "Array length mismatch".to_string(), - }, - ProviderError::Other(err) => StarknetRpcApiError::ErrUnexpectedError { - data: err.to_string(), - }, - } - } -} - -// Not optimising for this at the moment as the plan is to deprecate Starknet RPC anyways -impl From for StarknetRpcApiError { - fn from(err: ChainHandlerError) -> Self { - StarknetRpcApiError::ErrUnexpectedError { - data: err.to_string(), - } - } -} diff --git a/crates/rpc/src/starknet/mod.rs b/crates/rpc/src/starknet/mod.rs deleted file mode 100644 index f208a91..0000000 --- a/crates/rpc/src/starknet/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod errors; -pub mod v0_7_1; diff --git a/crates/rpc/src/starknet/v0_7_1/api.rs b/crates/rpc/src/starknet/v0_7_1/api.rs deleted file mode 100644 index 81fba5d..0000000 --- a/crates/rpc/src/starknet/v0_7_1/api.rs +++ /dev/null @@ -1,137 +0,0 @@ -use jsonrpsee::core::RpcResult; -use starknet::core::types::{ - BlockHashAndNumber, BlockId, BroadcastedDeclareTransaction, - BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction, - ContractClass, DeclareTransactionResult, DeployAccountTransactionResult, EventFilterWithPage, - EventsPage, FeeEstimate, Felt, FunctionCall, InvokeTransactionResult, MsgFromL1, - SimulatedTransaction, SimulationFlag, SimulationFlagForEstimateFee, SyncStatusType, - Transaction, TransactionStatus, TransactionTrace, -}; -use units_proc_macros::versioned_rpc; - -// Starknet RPC API trait and types -// -// Starkware maintains [a description of the Starknet API](https://github.com/starkware-libs/starknet-specs/blob/master/api/starknet_api_openrpc.json) -// using the openRPC specification. -// This crate uses `jsonrpsee` to define such an API in Rust terms. - -#[versioned_rpc("V0_7_1", "starknet")] -pub trait StarknetWriteRpcApi { - /// Submit a new transaction to be added to the chain - #[method(name = "addInvokeTransaction", and_versions = ["V0_8_0"])] - async fn add_invoke_transaction( - &self, - invoke_transaction: BroadcastedInvokeTransaction, - ) -> RpcResult; - - /// Submit a new deploy account transaction - #[method(name = "addDeployAccountTransaction", and_versions = ["V0_8_0"])] - async fn add_deploy_account_transaction( - &self, - deploy_account_transaction: BroadcastedDeployAccountTransaction, - ) -> RpcResult; - - /// Submit a new class declaration transaction - #[method(name = "addDeclareTransaction", and_versions = ["V0_8_0"])] - async fn add_declare_transaction( - &self, - declare_transaction: BroadcastedDeclareTransaction, - ) -> RpcResult; -} - -#[versioned_rpc("V0_7_1", "starknet")] -pub trait StarknetReadRpcApi { - /// Get the Version of the StarkNet JSON-RPC Specification Being Used - #[method(name = "specVersion")] - fn spec_version(&self) -> RpcResult; - - /// Get the most recent accepted block number - #[method(name = "blockNumber", and_versions = ["V0_8_0"])] - fn block_number(&self) -> RpcResult; - - // Get the most recent accepted block hash and number - #[method(name = "blockHashAndNumber", and_versions = ["V0_8_0"])] - fn block_hash_and_number(&self) -> RpcResult; - - /// Call a contract function at a given block id - #[method(name = "call", and_versions = ["V0_8_0"])] - fn call(&self, request: FunctionCall, block_id: BlockId) -> RpcResult>; - - /// Get the chain id - #[method(name = "chainId", and_versions = ["V0_8_0"])] - async fn chain_id(&self) -> RpcResult; - - /// Estimate the fee associated with transaction - #[method(name = "estimateFee", and_versions = ["V0_8_0"])] - async fn estimate_fee( - &self, - request: Vec, - simulation_flags: Vec, - block_id: BlockId, - ) -> RpcResult>; - - /// Estimate the L2 fee of a message sent on L1 - #[method(name = "estimateMessageFee", and_versions = ["V0_8_0"])] - async fn estimate_message_fee( - &self, - message: MsgFromL1, - block_id: BlockId, - ) -> RpcResult; - - /// Get the contract class at a given contract address for a given block id - #[method(name = "getClassAt", and_versions = ["V0_8_0"])] - fn get_class_at(&self, block_id: BlockId, contract_address: Felt) -> RpcResult; - - /// Get the contract class hash in the given block for the contract deployed at the given - /// address - #[method(name = "getClassHashAt", and_versions = ["V0_8_0"])] - fn get_class_hash_at(&self, block_id: BlockId, contract_address: Felt) -> RpcResult; - - /// Get the contract class definition in the given block associated with the given hash - #[method(name = "getClass", and_versions = ["V0_8_0"])] - fn get_class(&self, block_id: BlockId, class_hash: Felt) -> RpcResult; - - /// Returns all events matching the given filter - #[method(name = "getEvents", and_versions = ["V0_8_0"])] - async fn get_events(&self, filter: EventFilterWithPage) -> RpcResult; - - /// Get the nonce associated with the given address at the given block - #[method(name = "getNonce", and_versions = ["V0_8_0"])] - async fn get_nonce(&self, block_id: BlockId, contract_address: Felt) -> RpcResult; - - /// Get the details of a transaction by a given block id and index - #[method(name = "getTransactionByBlockIdAndIndex", and_versions = ["V0_8_0"])] - fn get_transaction_by_block_id_and_index( - &self, - block_id: BlockId, - index: u64, - ) -> RpcResult; - - /// Returns the information about a transaction by transaction hash. - #[method(name = "getTransactionByHash", and_versions = ["V0_8_0"])] - fn get_transaction_by_hash(&self, transaction_hash: Felt) -> RpcResult; - - /// Gets the Transaction Status, Including Mempool Status and Execution Details - #[method(name = "getTransactionStatus", and_versions = ["V0_8_0"])] - fn get_transaction_status(&self, transaction_hash: Felt) -> RpcResult; - - /// Get an object about the sync status, or false if the node is not syncing - #[method(name = "syncing", and_versions = ["V0_8_0"])] - async fn syncing(&self) -> RpcResult; -} - -#[versioned_rpc("V0_7_1", "starknet")] -pub trait StarknetTraceRpcApi { - /// Returns the execution trace of a transaction by simulating it in the runtime. - #[method(name = "simulateTransactions", and_versions = ["V0_8_0"])] - async fn simulate_transactions( - &self, - block_id: BlockId, - transactions: Vec, - simulation_flags: Vec, - ) -> RpcResult>; - - #[method(name = "traceTransaction", and_versions = ["V0_8_0"])] - /// Returns the execution trace of a transaction - async fn trace_transaction(&self, transaction_hash: Felt) -> RpcResult; -} diff --git a/crates/rpc/src/starknet/v0_7_1/methods/mod.rs b/crates/rpc/src/starknet/v0_7_1/methods/mod.rs deleted file mode 100644 index 7d8625f..0000000 --- a/crates/rpc/src/starknet/v0_7_1/methods/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod read; -pub mod trace; -pub mod write; diff --git a/crates/rpc/src/starknet/v0_7_1/methods/read/lib.rs b/crates/rpc/src/starknet/v0_7_1/methods/read/lib.rs deleted file mode 100644 index 52e55d1..0000000 --- a/crates/rpc/src/starknet/v0_7_1/methods/read/lib.rs +++ /dev/null @@ -1,157 +0,0 @@ -use jsonrpsee::core::{async_trait, RpcResult}; -use starknet::core::types::{ - BlockHashAndNumber, BlockId, BroadcastedTransaction, ContractClass, EntryPointsByType, - EventFilterWithPage, EventsPage, FeeEstimate, Felt, FlattenedSierraClass, FunctionCall, - InvokeTransactionV1, MsgFromL1, SimulationFlagForEstimateFee, SyncStatusType, Transaction, - TransactionStatus, -}; - -use crate::starknet::v0_7_1::StarknetReadRpcApiV0_7_1Server; -use crate::RpcContext; - -#[async_trait] -impl StarknetReadRpcApiV0_7_1Server for RpcContext { - fn spec_version(&self) -> RpcResult { - Ok("0.7.1".to_string()) - } - - fn block_number(&self) -> RpcResult { - Ok(0) - } - - fn block_hash_and_number(&self) -> RpcResult { - Ok(BlockHashAndNumber { - block_hash: Felt::from(0), - block_number: 0, - }) - } - - fn call(&self, _request: FunctionCall, _block_id: BlockId) -> RpcResult> { - Ok(vec![]) - } - - async fn chain_id(&self) -> RpcResult { - todo!() - // Ok( - // units_handlers_common::chain_id::chain_id(self.global_ctx.clone()) - // .await - // .map_err(StarknetRpcApiError::from)?, - // ) - } - - async fn estimate_fee( - &self, - _request: Vec, - _simulation_flags: Vec, - _block_id: BlockId, - ) -> RpcResult> { - Ok(vec![]) - } - - async fn estimate_message_fee( - &self, - _message: MsgFromL1, - _block_id: BlockId, - ) -> RpcResult { - Ok(FeeEstimate { - gas_consumed: Felt::from(0), - gas_price: Felt::from(0), - overall_fee: Felt::from(0), - data_gas_consumed: Felt::from(0), - data_gas_price: Felt::from(0), - unit: starknet::core::types::PriceUnit::Wei, - }) - } - - fn get_class_at( - &self, - _block_id: BlockId, - _contract_address: Felt, - ) -> RpcResult { - Ok(ContractClass::Sierra(FlattenedSierraClass { - abi: "".to_string(), - contract_class_version: "0.1.0".to_string(), - entry_points_by_type: EntryPointsByType { - constructor: vec![], - external: vec![], - l1_handler: vec![], - }, - sierra_program: vec![], - })) - } - - fn get_class_hash_at(&self, _block_id: BlockId, _contract_address: Felt) -> RpcResult { - Ok(Felt::from(0)) - } - - fn get_class(&self, _block_id: BlockId, _class_hash: Felt) -> RpcResult { - Ok(ContractClass::Sierra(FlattenedSierraClass { - abi: "".to_string(), - contract_class_version: "0.1.0".to_string(), - entry_points_by_type: EntryPointsByType { - constructor: vec![], - external: vec![], - l1_handler: vec![], - }, - sierra_program: vec![], - })) - } - - async fn get_events(&self, _filter: EventFilterWithPage) -> RpcResult { - Ok(EventsPage { - events: vec![], - continuation_token: None, - }) - } - - async fn get_nonce(&self, _block_id: BlockId, _contract_address: Felt) -> RpcResult { - todo!() - // Ok(units_handlers_common::nonce::get_nonce( - // self.global_ctx.clone(), - // _block_id, - // _contract_address, - // None, - // ) - // .await - // .map_err(ProviderError::from) - // .map_err(StarknetRpcApiError::from)?) - } - - fn get_transaction_by_block_id_and_index( - &self, - _block_id: BlockId, - _index: u64, - ) -> RpcResult { - Ok(Transaction::Invoke( - starknet::core::types::InvokeTransaction::V1(InvokeTransactionV1 { - calldata: vec![], - max_fee: Felt::from(0), - signature: vec![], - transaction_hash: Felt::from(0), - sender_address: Felt::from(0), - nonce: Felt::from(0), - }), - )) - } - - fn get_transaction_by_hash(&self, _transaction_hash: Felt) -> RpcResult { - Ok(Transaction::Invoke( - starknet::core::types::InvokeTransaction::V1(InvokeTransactionV1 { - calldata: vec![], - max_fee: Felt::from(0), - signature: vec![], - transaction_hash: Felt::from(0), - sender_address: Felt::from(0), - nonce: Felt::from(0), - }), - )) - } - - fn get_transaction_status(&self, _transaction_hash: Felt) -> RpcResult { - Ok(TransactionStatus::Received) - } - - async fn syncing(&self) -> RpcResult { - Ok(SyncStatusType::NotSyncing) - } -} diff --git a/crates/rpc/src/starknet/v0_7_1/methods/read/mod.rs b/crates/rpc/src/starknet/v0_7_1/methods/read/mod.rs deleted file mode 100644 index 965f28e..0000000 --- a/crates/rpc/src/starknet/v0_7_1/methods/read/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod lib; diff --git a/crates/rpc/src/starknet/v0_7_1/methods/trace/lib.rs b/crates/rpc/src/starknet/v0_7_1/methods/trace/lib.rs deleted file mode 100644 index 6b3b60e..0000000 --- a/crates/rpc/src/starknet/v0_7_1/methods/trace/lib.rs +++ /dev/null @@ -1,72 +0,0 @@ -use crate::{starknet::v0_7_1::StarknetTraceRpcApiV0_7_1Server, RpcContext}; -use jsonrpsee::core::{async_trait, RpcResult}; -use starknet::core::types::{ - BlockId, BroadcastedTransaction, ComputationResources, DataAvailabilityResources, - DataResources, ExecuteInvocation, ExecutionResources, Felt, FunctionInvocation, - InvokeTransactionTrace, SimulatedTransaction, SimulationFlag, TransactionTrace, -}; - -#[async_trait] -impl StarknetTraceRpcApiV0_7_1Server for RpcContext { - async fn simulate_transactions( - &self, - _block_id: BlockId, - _transactions: Vec, - _simulation_flags: Vec, - ) -> RpcResult> { - Ok(vec![]) - } - - async fn trace_transaction(&self, _transaction_hash: Felt) -> RpcResult { - Ok(TransactionTrace::Invoke(InvokeTransactionTrace { - validate_invocation: None, - execute_invocation: ExecuteInvocation::Success(FunctionInvocation { - contract_address: Felt::from(0), - entry_point_selector: Felt::from(0), - calldata: vec![], - caller_address: Felt::from(0), - class_hash: Felt::from(0), - entry_point_type: starknet::core::types::EntryPointType::External, - call_type: starknet::core::types::CallType::Call, - result: vec![], - calls: vec![], - events: vec![], - messages: vec![], - execution_resources: ComputationResources { - steps: 0, - memory_holes: None, - range_check_builtin_applications: None, - pedersen_builtin_applications: None, - poseidon_builtin_applications: None, - ec_op_builtin_applications: None, - ecdsa_builtin_applications: None, - bitwise_builtin_applications: None, - keccak_builtin_applications: None, - segment_arena_builtin: None, - }, - }), - fee_transfer_invocation: None, - state_diff: None, - execution_resources: ExecutionResources { - computation_resources: ComputationResources { - steps: 0, - memory_holes: None, - range_check_builtin_applications: None, - pedersen_builtin_applications: None, - poseidon_builtin_applications: None, - ec_op_builtin_applications: None, - ecdsa_builtin_applications: None, - bitwise_builtin_applications: None, - keccak_builtin_applications: None, - segment_arena_builtin: None, - }, - data_resources: DataResources { - data_availability: DataAvailabilityResources { - l1_gas: 0, - l1_data_gas: 0, - }, - }, - }, - })) - } -} diff --git a/crates/rpc/src/starknet/v0_7_1/methods/trace/mod.rs b/crates/rpc/src/starknet/v0_7_1/methods/trace/mod.rs deleted file mode 100644 index 965f28e..0000000 --- a/crates/rpc/src/starknet/v0_7_1/methods/trace/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod lib; diff --git a/crates/rpc/src/starknet/v0_7_1/methods/write/lib.rs b/crates/rpc/src/starknet/v0_7_1/methods/write/lib.rs deleted file mode 100644 index 411d184..0000000 --- a/crates/rpc/src/starknet/v0_7_1/methods/write/lib.rs +++ /dev/null @@ -1,119 +0,0 @@ -use crate::{starknet::v0_7_1::StarknetWriteRpcApiV0_7_1Server, RpcContext}; -use jsonrpsee::core::{async_trait, RpcResult}; -use starknet::core::types::{ - BroadcastedDeclareTransaction, BroadcastedDeployAccountTransaction, - BroadcastedInvokeTransaction, DeclareTransactionResult, DeployAccountTransactionResult, Felt, - InvokeTransactionResult, -}; - -#[async_trait] -impl StarknetWriteRpcApiV0_7_1Server for RpcContext { - /// Submit a new declare transaction to be added to the chain - /// - /// # Arguments - /// - /// * `declare_transaction` - the declare transaction to be added to the chain - /// - /// # Returns - /// - /// * `declare_transaction_result` - the result of the declare transaction - async fn add_declare_transaction( - &self, - _declare_transaction: BroadcastedDeclareTransaction, - ) -> RpcResult { - todo!() - // let declare_transaction = match declare_transaction { - // BroadcastedDeclareTransaction::V3(declare_transaction) => declare_transaction, - // _ => { - // return Err(StarknetRpcApiError::UnsupportedTxnVersion.into()); - // } - // }; - // let result = units_handlers_common::declare_class::declare_class( - // self.global_ctx.clone(), - // declare_transaction, - // ClassVisibility::Public, - // ) - // .await - // .map_err(ProviderError::from) - // .map_err(StarknetRpcApiError::from)?; - - // // It's possible that the transaction hash is not available as the class - // // was already declared. - // let transaction_hash = if let Some(transaction_hash) = result.transaction_hash { - // transaction_hash - // } else { - // return Err(StarknetRpcApiError::ClassAlreadyDeclared.into()); - // }; - - // // Convert Strings to Felts - // let class_hash = - // result - // .class_hash - // .try_into() - // .map_err(|e| StarknetRpcApiError::ErrUnexpectedError { - // data: format!("Failed to convert class hash to felt: {}", e), - // })?; - // let transaction_hash = - // transaction_hash - // .try_into() - // .map_err(|e| StarknetRpcApiError::ErrUnexpectedError { - // data: format!("Failed to convert transaction hash to felt: {}", e), - // })?; - - // Ok(DeclareTransactionResult { - // class_hash, - // transaction_hash, - // }) - } - - /// Add an Deploy Account Transaction - /// - /// # Arguments - /// - /// * `deploy account transaction` - - /// - /// # Returns - /// - /// * `transaction_hash` - transaction hash corresponding to the invocation - /// * `contract_address` - address of the deployed contract account - async fn add_deploy_account_transaction( - &self, - _deploy_account_transaction: BroadcastedDeployAccountTransaction, - ) -> RpcResult { - todo!() - // let deploy_account_transaction = match deploy_account_transaction { - // BroadcastedDeployAccountTransaction::V3(deploy_account_transaction) => { - // deploy_account_transaction - // } - // _ => { - // return Err(StarknetRpcApiError::UnsupportedTxnVersion.into()); - // } - // }; - // Ok( - // units_handlers_common::deploy_account::add_deploy_account_transaction( - // self.global_ctx.clone(), - // deploy_account_transaction, - // ) - // .await - // .map_err(StarknetRpcApiError::from)?, - // ) - } - - /// Add an Invoke Transaction to invoke a contract function - /// - /// # Arguments - /// - /// * `invoke tx` - - /// - /// # Returns - /// - /// * `transaction_hash` - transaction hash corresponding to the invocation - async fn add_invoke_transaction( - &self, - _invoke_transaction: BroadcastedInvokeTransaction, - ) -> RpcResult { - Ok(InvokeTransactionResult { - transaction_hash: Felt::from(0), - }) - } -} diff --git a/crates/rpc/src/starknet/v0_7_1/methods/write/mod.rs b/crates/rpc/src/starknet/v0_7_1/methods/write/mod.rs deleted file mode 100644 index 965f28e..0000000 --- a/crates/rpc/src/starknet/v0_7_1/methods/write/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod lib; diff --git a/crates/rpc/src/starknet/v0_7_1/mod.rs b/crates/rpc/src/starknet/v0_7_1/mod.rs deleted file mode 100644 index 414e5ac..0000000 --- a/crates/rpc/src/starknet/v0_7_1/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod api; -mod methods; -pub use api::*; diff --git a/crates/telemetery/src/lib.rs b/crates/telemetery/src/lib.rs index 50a3de7..50b5561 100644 --- a/crates/telemetery/src/lib.rs +++ b/crates/telemetery/src/lib.rs @@ -332,7 +332,7 @@ struct ValueVisitor { impl Visit for ValueVisitor { fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { if field.name() == self.field_name { - self.value = format!("{:?}", value); + self.value = format!("{value:?}"); } } diff --git a/crates/utils/src/url.rs b/crates/utils/src/url.rs index abbfd42..508950b 100644 --- a/crates/utils/src/url.rs +++ b/crates/utils/src/url.rs @@ -20,7 +20,7 @@ mod tests { #[case("://invalid.com", false)] fn test_parse_url(#[case] url: &str, #[case] should_pass: bool) { let result = parse_url(url); - assert_eq!(result.is_ok(), should_pass, "URL: {}", url); + assert_eq!(result.is_ok(), should_pass, "URL: {url}"); if should_pass { let parsed_url = result.unwrap(); diff --git a/e2e-starknet-tests/src/chain_id.rs b/e2e-starknet-tests/src/chain_id.rs index c7c60f6..45112a2 100644 --- a/e2e-starknet-tests/src/chain_id.rs +++ b/e2e-starknet-tests/src/chain_id.rs @@ -20,7 +20,7 @@ async fn test_chain_id( runner.run().await?; let url = runner.rpc_url().unwrap(); - println!("Units URL: {}", url); + println!("Units URL: {url}"); // Make JSON-RPC request to get chain ID let client = reqwest::Client::new(); diff --git a/js-scripts/.env b/js-scripts/.env index fae8f1a..df977e6 100644 --- a/js-scripts/.env +++ b/js-scripts/.env @@ -1,12 +1,13 @@ # Default predeployed account in devnet -UNITS_RPC=https://finternet-sandbox.karnot.xyz +UNITS_RPC=http://localhost:9945 +MADARA_RPC=http://localhost:9944 IDENTITY_REGISTRY=0xae19129cdcbb65bf8e49a8b046a6a7e1943671fab0866a0c627c2fa398e3c6 COMPLIANCE_MODULE=0x056036a162d4ba9b3062ca103bf73d9899a7b9ab2ab206a9a4d3812f018bd9cd TOKEN=0x0589f8496d8ab7124c3070e4143cce51ff5e77557661177b773a656beb34eb78 # Owner account -ACCOUNT_ADDRESS=0x031d9bcc8fba75775914c9ab3f8212343dd5057262fe475969644ca9b45b2767 -PRIVATE_KEY=0x7464448773d5f90338960824f619c62abb442db2c42e3c5701c0e9a30b887d +ACCOUNT_ADDRESS=0x055be462e718c4166d656d11f89e341115b8bc82389c3762a10eade04fcb225d +PRIVATE_KEY=0x077e56c6dc32d40a67f6f7e6625c8dc5e570abe49c0a24e9202e4ae906abcc07 # Recepient account # ACCOUNT_ADDRESS=0x023826a570b143057d324d98a74b6eac29e93c0f7cd8ae2860fe043566fcff36 diff --git a/js-scripts/package-lock.json b/js-scripts/package-lock.json index 0e45092..ae1397d 100644 --- a/js-scripts/package-lock.json +++ b/js-scripts/package-lock.json @@ -11,20 +11,21 @@ "dependencies": { "@types/node": "^22.15.3", "dotenv": "^16.5.0", - "starknet": "^6.24.1" + "starknet": "next" }, "devDependencies": { "tsx": "^4.19.4" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz", - "integrity": "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "aix" @@ -34,13 +35,14 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.3.tgz", - "integrity": "sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -50,13 +52,14 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.3.tgz", - "integrity": "sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -66,13 +69,14 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.3.tgz", - "integrity": "sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -82,13 +86,14 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.3.tgz", - "integrity": "sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -98,13 +103,14 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.3.tgz", - "integrity": "sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -114,13 +120,14 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.3.tgz", - "integrity": "sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -130,13 +137,14 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.3.tgz", - "integrity": "sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -146,13 +154,14 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.3.tgz", - "integrity": "sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -162,13 +171,14 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.3.tgz", - "integrity": "sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -178,13 +188,14 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.3.tgz", - "integrity": "sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -194,13 +205,14 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.3.tgz", - "integrity": "sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", "cpu": [ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -210,13 +222,14 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.3.tgz", - "integrity": "sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", "cpu": [ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -226,13 +239,14 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.3.tgz", - "integrity": "sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -242,13 +256,14 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.3.tgz", - "integrity": "sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -258,13 +273,14 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.3.tgz", - "integrity": "sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -274,13 +290,14 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.3.tgz", - "integrity": "sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -290,13 +307,14 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.3.tgz", - "integrity": "sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -306,13 +324,14 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.3.tgz", - "integrity": "sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -322,13 +341,14 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.3.tgz", - "integrity": "sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -338,13 +358,14 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.3.tgz", - "integrity": "sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -353,14 +374,32 @@ "node": ">=18" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.3.tgz", - "integrity": "sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" @@ -370,13 +409,14 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.3.tgz", - "integrity": "sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -386,13 +426,14 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.3.tgz", - "integrity": "sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -402,13 +443,14 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz", - "integrity": "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -421,6 +463,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.7.0.tgz", "integrity": "sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==", + "license": "MIT", "dependencies": { "@noble/hashes": "1.6.0" }, @@ -431,10 +474,23 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@noble/hashes": { + "node_modules/@noble/curves/node_modules/@noble/hashes": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.0.tgz", "integrity": "sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.1.tgz", + "integrity": "sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==", + "license": "MIT", "engines": { "node": "^14.21.3 || >=16" }, @@ -443,9 +499,10 @@ } }, "node_modules/@scure/base": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.1.tgz", - "integrity": "sha512-DGmGtC8Tt63J5GfHgfl5CuAXh96VF/LD8K9Hr/Gv0J2lAoRGlPOMpqMpMbCTOoOJMZCk2Xt+DskdDyn6dEFdzQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" } @@ -454,6 +511,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@scure/starknet/-/starknet-1.1.0.tgz", "integrity": "sha512-83g3M6Ix2qRsPN4wqLDqiRZ2GBNbjVWfboJE/9UjfG+MHr6oDSu/CWgy8hsBSJejr09DkkL+l0Ze4KVrlCIdtQ==", + "license": "MIT", "dependencies": { "@noble/curves": "~1.7.0", "@noble/hashes": "~1.6.0" @@ -462,10 +520,25 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@starknet-io/starknet-types-08": { + "name": "@starknet-io/types-js", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/@starknet-io/types-js/-/types-js-0.8.4.tgz", + "integrity": "sha512-0RZ3TZHcLsUTQaq1JhDSCM8chnzO4/XNsSCozwDET64JK5bjFDIf2ZUkta+tl5Nlbf4usoU7uZiDI/Q57kt2SQ==", + "license": "MIT" + }, + "node_modules/@starknet-io/starknet-types-09": { + "name": "@starknet-io/types-js", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@starknet-io/types-js/-/types-js-0.9.2.tgz", + "integrity": "sha512-vWOc0FVSn+RmabozIEWcEny1I73nDGTvOrLYJsR1x7LGA3AZmqt4i/aW69o/3i2NN5CVP8Ok6G1ayRQJKye3Wg==", + "license": "MIT" + }, "node_modules/@types/node": { - "version": "22.15.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.3.tgz", - "integrity": "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==", + "version": "22.19.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz", + "integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==", + "license": "MIT", "dependencies": { "undici-types": "~6.21.0" } @@ -474,6 +547,7 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/abi-wan-kanabi/-/abi-wan-kanabi-2.2.4.tgz", "integrity": "sha512-0aA81FScmJCPX+8UvkXLki3X1+yPQuWxEkqXBVKltgPAK79J+NB+Lp5DouMXa7L6f+zcRlIA/6XO7BN/q9fnvg==", + "license": "ISC", "dependencies": { "ansicolors": "^0.3.2", "cardinal": "^2.1.1", @@ -488,6 +562,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -496,6 +571,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -509,12 +585,14 @@ "node_modules/ansicolors": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==" + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "license": "MIT" }, "node_modules/cardinal": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "license": "MIT", "dependencies": { "ansicolors": "~0.3.2", "redeyed": "~2.1.0" @@ -527,6 +605,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -540,6 +619,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -550,12 +630,14 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, "node_modules/dotenv": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", - "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -566,14 +648,16 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" }, "node_modules/esbuild": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.3.tgz", - "integrity": "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -581,37 +665,39 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.3", - "@esbuild/android-arm": "0.25.3", - "@esbuild/android-arm64": "0.25.3", - "@esbuild/android-x64": "0.25.3", - "@esbuild/darwin-arm64": "0.25.3", - "@esbuild/darwin-x64": "0.25.3", - "@esbuild/freebsd-arm64": "0.25.3", - "@esbuild/freebsd-x64": "0.25.3", - "@esbuild/linux-arm": "0.25.3", - "@esbuild/linux-arm64": "0.25.3", - "@esbuild/linux-ia32": "0.25.3", - "@esbuild/linux-loong64": "0.25.3", - "@esbuild/linux-mips64el": "0.25.3", - "@esbuild/linux-ppc64": "0.25.3", - "@esbuild/linux-riscv64": "0.25.3", - "@esbuild/linux-s390x": "0.25.3", - "@esbuild/linux-x64": "0.25.3", - "@esbuild/netbsd-arm64": "0.25.3", - "@esbuild/netbsd-x64": "0.25.3", - "@esbuild/openbsd-arm64": "0.25.3", - "@esbuild/openbsd-x64": "0.25.3", - "@esbuild/sunos-x64": "0.25.3", - "@esbuild/win32-arm64": "0.25.3", - "@esbuild/win32-ia32": "0.25.3", - "@esbuild/win32-x64": "0.25.3" + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" } }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -620,6 +706,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -628,19 +715,11 @@ "node": ">=4" } }, - "node_modules/fetch-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-3.0.1.tgz", - "integrity": "sha512-ZGXe8Y5Z/1FWqQ9q/CrJhkUD73DyBU9VF0hBQmEO/wPHe4A9PKTjplFDLeFX8aOsYypZUcX5Ji/eByn3VCVO3Q==", - "dependencies": { - "set-cookie-parser": "^2.4.8", - "tough-cookie": "^4.0.0" - } - }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -656,6 +735,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -668,15 +748,17 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-tsconfig": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", - "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", "dev": true, + "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -687,29 +769,23 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "dependencies": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -718,62 +794,22 @@ } }, "node_modules/lossless-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/lossless-json/-/lossless-json-4.0.2.tgz", - "integrity": "sha512-+z0EaLi2UcWi8MZRxA5iTb6m4Ys4E80uftGY+yG5KNFJb5EceQXOhdW/pWJZ8m97s26u7yZZAYMcKWNztSZssA==" - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lossless-json/-/lossless-json-4.3.0.tgz", + "integrity": "sha512-ToxOC+SsduRmdSuoLZLYAr5zy1Qu7l5XhmPWM3zefCZ5IcrzW/h108qbJUKfOlDlhvhjUK84+8PSVX0kxnit0g==", + "license": "MIT" }, "node_modules/pako": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" - }, - "node_modules/psl": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", - "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", - "dependencies": { - "punycode": "^2.3.1" - }, - "funding": { - "url": "https://github.com/sponsors/lupomontero" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" }, "node_modules/redeyed": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "license": "MIT", "dependencies": { "esprima": "~4.0.0" } @@ -782,57 +818,47 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==" - }, "node_modules/starknet": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/starknet/-/starknet-6.24.1.tgz", - "integrity": "sha512-g7tiCt73berhcNi41otlN3T3kxZnIvZhMi8WdC21Y6GC6zoQgbI2z1t7JAZF9c4xZiomlanwVnurcpyfEdyMpg==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/starknet/-/starknet-8.9.0.tgz", + "integrity": "sha512-uhXSCKW0SMBGckd4yVlscVz4DMkQqZ+/RTpfxZ5J46e6AuCUHOqGKv61tqgUP9GhdvgHV/XyN+kdmlyZn3rXjA==", + "license": "MIT", "dependencies": { - "@noble/curves": "1.7.0", - "@noble/hashes": "1.6.0", - "@scure/base": "1.2.1", + "@noble/curves": "~1.7.0", + "@noble/hashes": "~1.6.0", + "@scure/base": "~1.2.1", "@scure/starknet": "1.1.0", - "abi-wan-kanabi": "^2.2.3", - "fetch-cookie": "~3.0.0", - "isomorphic-fetch": "~3.0.0", - "lossless-json": "^4.0.1", + "@starknet-io/starknet-types-08": "npm:@starknet-io/types-js@~0.8.4", + "@starknet-io/starknet-types-09": "npm:@starknet-io/types-js@~0.9.1", + "abi-wan-kanabi": "2.2.4", + "lossless-json": "^4.2.0", "pako": "^2.0.4", - "starknet-types-07": "npm:@starknet-io/types-js@^0.7.10", "ts-mixer": "^6.0.3" + }, + "engines": { + "node": ">=22" } }, - "node_modules/starknet-types-07": { - "name": "@starknet-io/types-js", - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@starknet-io/types-js/-/types-js-0.7.10.tgz", - "integrity": "sha512-1VtCqX4AHWJlRRSYGSn+4X1mqolI1Tdq62IwzoU2vUuEE72S1OlEeGhpvd6XsdqXcfHmVzYfj8k1XtKBQqwo9w==" - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -846,6 +872,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -853,43 +880,18 @@ "node": ">=8" } }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "node_modules/ts-mixer": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", - "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==" + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==", + "license": "MIT" }, "node_modules/tsx": { - "version": "4.19.4", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.4.tgz", - "integrity": "sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==", + "version": "4.20.6", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz", + "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" @@ -907,48 +909,23 @@ "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", "engines": { "node": ">= 10.0.0" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -965,6 +942,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", "engines": { "node": ">=10" } @@ -973,6 +951,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -990,6 +969,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", "engines": { "node": ">=12" } diff --git a/js-scripts/package.json b/js-scripts/package.json index 6d063ef..ea4083c 100644 --- a/js-scripts/package.json +++ b/js-scripts/package.json @@ -12,7 +12,7 @@ "dependencies": { "@types/node": "^22.15.3", "dotenv": "^16.5.0", - "starknet": "^6.24.1" + "starknet": "next" }, "type": "module", "devDependencies": { diff --git a/js-scripts/src/account.ts b/js-scripts/src/account.ts index 73080fe..4c568e6 100644 --- a/js-scripts/src/account.ts +++ b/js-scripts/src/account.ts @@ -10,13 +10,15 @@ import { ec, selector, constants, - transaction, + Deployer, + legacyDeployer, } from "starknet"; import { ClassVisibility, hashReadData, ReadData, ReadType, + ResourceBoundsMapping, SignedReadData, TransactionReceipt, UnitsProvider, @@ -28,6 +30,42 @@ type DeployAccountParams = { constructorArgs: string[]; }; +// Helper function to get default resource bounds +function getDefaultResourceBounds(): ResourceBoundsMapping { + return { + l1_gas: { + max_amount: 10000, + max_price_per_unit: 200, + }, + l1_data_gas: { + max_amount: 10000, + max_price_per_unit: 200, + }, + l2_gas: { + max_amount: 10000000, + max_price_per_unit: 2500, + }, + }; +} + +// Helper function to convert ResourceBoundsMapping to BigInt format for starknet.js +function convertResourceBoundsToBigInt(resourceBounds: ResourceBoundsMapping) { + return { + l1_gas: { + max_amount: BigInt(resourceBounds.l1_gas.max_amount), + max_price_per_unit: BigInt(resourceBounds.l1_gas.max_price_per_unit), + }, + l1_data_gas: { + max_amount: BigInt(resourceBounds.l1_data_gas.max_amount), + max_price_per_unit: BigInt(resourceBounds.l1_data_gas.max_price_per_unit), + }, + l2_gas: { + max_amount: BigInt(resourceBounds.l2_gas.max_amount), + max_price_per_unit: BigInt(resourceBounds.l2_gas.max_price_per_unit), + }, + }; +} + class UnitsAccount { private unitsProvider: UnitsProvider; private address: string; @@ -73,13 +111,13 @@ class UnitsAccount { let provider = new Provider({ nodeUrl: "", }); - this.starknetAccount = new Account( + this.starknetAccount = new Account({ provider, - this.address, - this.privateKey, - "1", - "0x3", - ); + address: this.address, + signer: this.privateKey, + cairoVersion: "1", + transactionVersion: "0x3", + }); } getProvider(): UnitsProvider { @@ -91,21 +129,13 @@ class UnitsAccount { } async buildInvokeSignerDetails( + resourceBounds: ResourceBoundsMapping, nonce?: number, ): Promise { return { version: "0x3", nonce: nonce !== undefined ? nonce : await this.getNonce(), - resourceBounds: { - l1_gas: { - max_amount: "0", - max_price_per_unit: "0", - }, - l2_gas: { - max_amount: "0", - max_price_per_unit: "0", - }, - }, + resourceBounds: convertResourceBoundsToBigInt(resourceBounds), tip: "0", paymasterData: [], accountDeploymentData: [], @@ -128,8 +158,10 @@ class UnitsAccount { program: any, compiledProgramHash: string, visibility: ClassVisibility, + resourceBounds?: ResourceBoundsMapping, ): Promise<{ transaction_hash: string }> { - const signerDetails = await this.buildInvokeSignerDetails(); + const bounds = resourceBounds || getDefaultResourceBounds(); + const signerDetails = await this.buildInvokeSignerDetails(bounds); const declarePayload = await this.starknetAccount.buildDeclarePayload( { contract: program, @@ -151,6 +183,7 @@ class UnitsAccount { }, visibility, compiledProgramHash, + bounds, ); return programId; } @@ -159,10 +192,12 @@ class UnitsAccount { programHash: string, constructorArgs: string[], salt: string, + resourceBounds?: ResourceBoundsMapping, ): Promise<{ transaction_hash: string; program_address: string }> { const unique = true; - const udcDeployPayload = transaction.buildUDCCall( + const deployer = legacyDeployer; + const udcDeployPayload = deployer.buildDeployerCall( { classHash: programHash, constructorCalldata: constructorArgs, @@ -173,6 +208,7 @@ class UnitsAccount { ); const sendTransactionResponse = await this.sendTransaction( udcDeployPayload.calls, + resourceBounds, ); const receipt = await this.waitForTransaction( @@ -187,8 +223,10 @@ class UnitsAccount { async sendTransaction( calldata: Array, + resourceBounds?: ResourceBoundsMapping, ): Promise<{ transaction_hash: string }> { - const signerDetails = await this.buildInvokeSignerDetails(); + const bounds = resourceBounds || getDefaultResourceBounds(); + const signerDetails = await this.buildInvokeSignerDetails(bounds); const invocation = await this.starknetAccount.buildInvocation( calldata, signerDetails, @@ -205,12 +243,14 @@ class UnitsAccount { buildSignature(invocation.signature), Number(signerDetails.nonce), calldataString, + bounds, ); return sendTransactionResponse; } - async deploySelf() { - const signerDetails = await this.buildInvokeSignerDetails(0); + async deploySelf(resourceBounds?: ResourceBoundsMapping) { + const bounds = resourceBounds || getDefaultResourceBounds(); + const signerDetails = await this.buildInvokeSignerDetails(bounds, 0); const deloyAccountPayload = await this.starknetAccount.buildAccountDeployPayload( { @@ -227,6 +267,7 @@ class UnitsAccount { this.deployAccountParams.constructorArgs, this.deployAccountParams.programHash, this.deployAccountParams.salt, + bounds, ); return deployAccountResponse; @@ -340,4 +381,4 @@ function buildSignature(signature?: Signature) { : [toHex(signature.r), toHex(signature.s)]; } -export { UnitsAccount }; +export { UnitsAccount, getDefaultResourceBounds }; diff --git a/js-scripts/src/contracts/.tool-versions b/js-scripts/src/contracts/.tool-versions new file mode 100644 index 0000000..ffeefbf --- /dev/null +++ b/js-scripts/src/contracts/.tool-versions @@ -0,0 +1 @@ +scarb 2.9.4 \ No newline at end of file diff --git a/js-scripts/src/init_units.ts b/js-scripts/src/init_units.ts new file mode 100644 index 0000000..5b01890 --- /dev/null +++ b/js-scripts/src/init_units.ts @@ -0,0 +1,52 @@ +import * as starknet from "starknet"; +import dotenv from "dotenv"; +import { readFileSync } from "fs"; +import { resolve, dirname } from "path"; +import { fileURLToPath } from "url"; + +dotenv.config(); + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const provider = new starknet.RpcProvider({ + nodeUrl: process.env.MADARA_RPC, +}); +const account = new starknet.Account({ + provider, + address: process.env.ACCOUNT_ADDRESS, + signer: process.env.PRIVATE_KEY, + cairoVersion: "1", + transactionVersion: "0x3", + // Madara still used legacy UDC + deployer: starknet.legacyDeployer, +}); + +async function deploy_declare_acl() { + const sierraPath = resolve( + __dirname, + "../../crates/handlers/starknet/src/tests/get_program/test_contracts/target/dev/get_nonce_test_contracts_DeclareAclContract.contract_class.json", + ); + const casmPath = resolve( + __dirname, + "../../crates/handlers/starknet/src/tests/get_program/test_contracts/target/dev/get_nonce_test_contracts_DeclareAclContract.compiled_contract_class.json", + ); + + const sierra = JSON.parse(readFileSync(sierraPath, "utf-8")); + const casm = JSON.parse(readFileSync(casmPath, "utf-8")); + + try { + const declareAndDeployResult = await account.declareAndDeploy({ + contract: sierra, + casm: casm, + }); + console.log( + "This is the declare and deploy result - ", + declareAndDeployResult, + ); + } catch (err) { + console.log("Error declaring and deploying contract - ", err); + } +} + +deploy_declare_acl(); diff --git a/js-scripts/src/provider.ts b/js-scripts/src/provider.ts index c8d9440..16b7def 100644 --- a/js-scripts/src/provider.ts +++ b/js-scripts/src/provider.ts @@ -71,6 +71,17 @@ export interface TransactionReceipt { export type ClassVisibility = "PUBLIC" | "ACL"; +export interface ResourceBounds { + max_amount: number; + max_price_per_unit: number; +} + +export interface ResourceBoundsMapping { + l1_gas: ResourceBounds; + l1_data_gas: ResourceBounds; + l2_gas: ResourceBounds; +} + class UnitsProvider { private rpcUrl: string; @@ -107,7 +118,8 @@ class UnitsProvider { nonce: Nonce, program: any, visibility: ClassVisibility, - compiledProgramHash?: Bytes32, + compiledProgramHash: Bytes32 | undefined, + resourceBounds: ResourceBoundsMapping, ): Promise<{ transaction_hash: Bytes32 }> { return this.makeRequest("declareProgram", { declare_program: { @@ -117,6 +129,7 @@ class UnitsProvider { program: program, compiled_program_hash: compiledProgramHash, class_visibility: visibility, + resource_bounds: resourceBounds, }, }); } @@ -126,6 +139,7 @@ class UnitsProvider { signature: Bytes32[], nonce: Nonce, calldata: Bytes32[], + resourceBounds: ResourceBoundsMapping, ): Promise<{ transaction_hash: Bytes32 }> { return this.makeRequest("sendTransaction", { send_transaction: { @@ -133,6 +147,7 @@ class UnitsProvider { signature: signature, nonce: nonce, calldata: calldata, + resource_bounds: resourceBounds, }, }); } @@ -143,6 +158,7 @@ class UnitsProvider { constructorCalldata: Bytes32[], programHash: Bytes32, accountAddressSalt: Bytes32, + resourceBounds: ResourceBoundsMapping, ): Promise<{ transaction_hash: Bytes32 }> { return this.makeRequest("deployAccount", { deploy_account: { @@ -151,6 +167,7 @@ class UnitsProvider { constructor_calldata: constructorCalldata, program_hash: programHash, account_address_salt: accountAddressSalt, + resource_bounds: resourceBounds, }, }); } diff --git a/js-scripts/src/scripts/chain_id.ts b/js-scripts/src/scripts/chain_id.ts new file mode 100644 index 0000000..81195ff --- /dev/null +++ b/js-scripts/src/scripts/chain_id.ts @@ -0,0 +1,16 @@ +import { UnitsProvider } from "../provider"; +import dotenv from "dotenv"; + +dotenv.config(); + +async function get_chain_id() { + const unitsProvider = new UnitsProvider(process.env.UNITS_RPC); + + const chainId = await unitsProvider.getChainId(); + + console.log("✅ Chain ID: ", chainId); +} + +/// CLI HELPERS + +get_chain_id(); diff --git a/js-scripts/src/scripts/declare_program.ts b/js-scripts/src/scripts/declare_program.ts old mode 100644 new mode 100755 index 2a25730..6a7193b --- a/js-scripts/src/scripts/declare_program.ts +++ b/js-scripts/src/scripts/declare_program.ts @@ -1,5 +1,5 @@ import { hash } from "starknet"; -import { UnitsAccount } from "../account"; +import { getDefaultResourceBounds, UnitsAccount } from "../account"; import { UnitsProvider } from "../provider"; import dotenv from "dotenv"; import fs from "fs"; @@ -14,10 +14,13 @@ async function declare_program(programJson: any, compiledProgramJson: any) { process.env.PRIVATE_KEY, ); + const resourceBounds = getDefaultResourceBounds(); + resourceBounds.l2_gas.max_amount = 100000000; // setting a high value to avoud gas issues const declareProgramResponse = await unitsAccount.declareProgram( programJson, hash.computeCompiledClassHash(compiledProgramJson), "ACL", + resourceBounds, ); console.log("ℹ️ Class hash: ", hash.computeContractClassHash(programJson)); diff --git a/js-scripts/src/scripts/deploy_account.ts b/js-scripts/src/scripts/deploy_account.ts index f2062fc..3eedb46 100644 --- a/js-scripts/src/scripts/deploy_account.ts +++ b/js-scripts/src/scripts/deploy_account.ts @@ -14,15 +14,41 @@ async function deploy_account() { const signer = new Signer(privateKey); const unitsAccount = UnitsAccount.newUndeployedAccount( unitsProvider, - "0x01484c93b9d6cf61614d698ed069b3c6992c32549194fc3465258c2194734189", // pre declared account class hash on Dev + "0xe2eb8f5672af4e6a4e8a8f1b44989685e668489b0a25437733756c5a34a1d6", // pre declared account class hash on Dev "0x0", [await signer.getPubKey()], privateKey, ); + await fund_account(unitsProvider, unitsAccount.getAddress()); const deployAccountResponse = await unitsAccount.deploySelf(); console.log("✅ Deploy account response: ", deployAccountResponse); } +async function fund_account( + unitsProvider: UnitsProvider, + accountAddress: string, +) { + const ownerAccount = new UnitsAccount( + unitsProvider, + process.env.ACCOUNT_ADDRESS, + process.env.PRIVATE_KEY, + ); + + const fundAccountResponse = await ownerAccount.sendTransaction([ + { + contractAddress: + "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", // STRK token address + entrypoint: "transfer", + calldata: [accountAddress, "1000000000000000000", 0], + }, + ]); + + const receipt = await ownerAccount.waitForTransaction( + fundAccountResponse.transaction_hash, + ); + console.log("✅ Fund account response: ", receipt); +} + deploy_account(); diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5a08ffa..38217ce 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.85" +channel = "1.88" components = ["rust-src", "rustfmt", "clippy", "rust-analyzer"] profile = "minimal" diff --git a/test-utils/src/units.rs b/test-utils/src/units.rs index 17171f2..7f1f128 100644 --- a/test-utils/src/units.rs +++ b/test-utils/src/units.rs @@ -77,14 +77,14 @@ impl UnitsRunner { thread::spawn(move || { let reader = BufReader::new(stdout); for line in reader.lines().map_while(Result::ok) { - println!("[UNITS] {}", line); + println!("[UNITS] {line}"); } }); thread::spawn(move || { let reader = BufReader::new(stderr); for line in reader.lines().map_while(Result::ok) { - eprintln!("[UNITS] {}", line); + eprintln!("[UNITS] {line}"); } }); @@ -92,7 +92,7 @@ impl UnitsRunner { // Wait for the Units service to be ready let client = Client::new(); - let url = format!("http://localhost:{}/health", units_port); + let url = format!("http://localhost:{units_port}/health"); let mut attempts = 0; const MAX_ATTEMPTS: u32 = 10; diff --git a/units_specs/units_api_openrpc.json b/units_specs/units_api_openrpc.json index 02b4330..eb66810 100644 --- a/units_specs/units_api_openrpc.json +++ b/units_specs/units_api_openrpc.json @@ -141,6 +141,14 @@ "$ref": "#/components/schemas/BYTES32" } } + }, + { + "name": "resource_bounds", + "description": "Resource bounds for the transaction", + "required": true, + "schema": { + "$ref": "#/components/schemas/RESOURCE_BOUNDS_MAPPING" + } } ], "result": { @@ -305,6 +313,14 @@ "schema": { "$ref": "#/components/schemas/BYTES32" } + }, + { + "name": "resource_bounds", + "description": "Resource bounds for the deployment", + "required": true, + "schema": { + "$ref": "#/components/schemas/RESOURCE_BOUNDS_MAPPING" + } } ], "result": { @@ -624,6 +640,37 @@ "required": ["type", "error"] } ] + }, + "RESOURCE_BOUNDS": { + "type": "object", + "properties": { + "max_amount": { + "type": "integer", + "format": "uint64", + "description": "Maximum amount of the resource" + }, + "max_price_per_unit": { + "type": "integer", + "format": "uint128", + "description": "Maximum price per unit of the resource" + } + }, + "required": ["max_amount", "max_price_per_unit"] + }, + "RESOURCE_BOUNDS_MAPPING": { + "type": "object", + "properties": { + "l1_gas": { + "$ref": "#/components/schemas/RESOURCE_BOUNDS" + }, + "l1_data_gas": { + "$ref": "#/components/schemas/RESOURCE_BOUNDS" + }, + "l2_gas": { + "$ref": "#/components/schemas/RESOURCE_BOUNDS" + } + }, + "required": ["l1_gas", "l1_data_gas", "l2_gas"] } } }