From 548d2dd02474a01fbac37a0bb075368226e2c801 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Sun, 16 Jun 2024 03:10:03 -0600 Subject: [PATCH 01/28] test: sierra class hash benchmark (#601) Also updates all benchmark results to use Apple M3 Max. --- scripts/build_bench_wasm.sh | 3 +- scripts/run_bench_wasm.sh | 3 +- starknet-core/Cargo.toml | 6 ++- starknet-core/README.md | 16 ++++--- .../{class_hash.rs => cairo0_class_hash.rs} | 2 +- starknet-core/benches/sierra_class_hash.rs | 18 ++++++++ starknet-crypto/README.md | 46 +++++++++---------- 7 files changed, 60 insertions(+), 34 deletions(-) rename starknet-core/benches/{class_hash.rs => cairo0_class_hash.rs} (92%) create mode 100644 starknet-core/benches/sierra_class_hash.rs diff --git a/scripts/build_bench_wasm.sh b/scripts/build_bench_wasm.sh index 9d7a4da8..d8f72238 100755 --- a/scripts/build_bench_wasm.sh +++ b/scripts/build_bench_wasm.sh @@ -17,7 +17,8 @@ mkdir -p $REPO_ROOT/target/bench-wasm cd $REPO_ROOT/starknet-core benches=( - class_hash + cairo0_class_hash + sierra_class_hash ) for bench in ${benches[@]}; do diff --git a/scripts/run_bench_wasm.sh b/scripts/run_bench_wasm.sh index 47c7a417..a36ae83f 100755 --- a/scripts/run_bench_wasm.sh +++ b/scripts/run_bench_wasm.sh @@ -15,7 +15,8 @@ if [ -z "$RUNTIME" ]; then fi benches=( - class_hash + cairo0_class_hash + sierra_class_hash ecdsa_get_public_key ecdsa_recover ecdsa_sign diff --git a/starknet-core/Cargo.toml b/starknet-core/Cargo.toml index 6179c133..00526ca2 100644 --- a/starknet-core/Cargo.toml +++ b/starknet-core/Cargo.toml @@ -43,5 +43,9 @@ std = ["dep:flate2", "starknet-ff/std", "starknet-crypto/std"] no_unknown_fields = [] [[bench]] -name = "class_hash" +name = "cairo0_class_hash" +harness = false + +[[bench]] +name = "sierra_class_hash" harness = false diff --git a/starknet-core/README.md b/starknet-core/README.md index 3ea1ed96..52421fe7 100644 --- a/starknet-core/README.md +++ b/starknet-core/README.md @@ -4,29 +4,31 @@ ## Benchmark -These results were generated on the author's machine with _AMD Ryzen 9 5950X 16-Core Processor_ running _Ubuntu 22.04.1 LTS_. +These results were generated on the author's machine with _Apple M3 Max_ running _macOS 14.5_. For instructions on running the benchmarks yourself, check out [this page](../BENCHMARK.md). ### Native ```log -class_hash time: [21.680 ms 21.684 ms 21.688 ms] +cairo0_class_hash time: [10.808 ms 10.813 ms 10.819 ms] +sierra_class_hash time: [6.2774 ms 6.2802 ms 6.2832 ms] ``` ### WebAssembly -_(With its excellent wasm performance, results are only provided for Node.js here. Check out the [benchmark page](../BENCHMARK.md) for running the benchmark on other runtimes)._ +_(Results are only provided for `wasmtime` here. Check out the [benchmark page](../BENCHMARK.md) for running the benchmark on other runtimes)._ Runtime version: ```console -$ node --version -v18.16.0 +$ wasmtime --version +wasmtime-cli 21.0.1 (cedf9aa0f 2024-05-22) ``` -Node.js results: +`wasmtime` results: ```log -class_hash time: [124.48 ms 124.58 ms 124.69 ms] +cairo0_class_hash time: [39.192 ms 39.207 ms 39.224 ms] +sierra_class_hash time: [20.514 ms 20.521 ms 20.529 ms] ``` diff --git a/starknet-core/benches/class_hash.rs b/starknet-core/benches/cairo0_class_hash.rs similarity index 92% rename from starknet-core/benches/class_hash.rs rename to starknet-core/benches/cairo0_class_hash.rs index 27a2bedd..1fb2b607 100644 --- a/starknet-core/benches/class_hash.rs +++ b/starknet-core/benches/cairo0_class_hash.rs @@ -8,7 +8,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { )) .unwrap(); - c.bench_function("class_hash", |b| { + c.bench_function("cairo0_class_hash", |b| { b.iter(|| { black_box(&contract_artifact).class_hash().unwrap(); }); diff --git a/starknet-core/benches/sierra_class_hash.rs b/starknet-core/benches/sierra_class_hash.rs new file mode 100644 index 00000000..e36fca88 --- /dev/null +++ b/starknet-core/benches/sierra_class_hash.rs @@ -0,0 +1,18 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use starknet_core::types::contract::SierraClass; + +pub fn criterion_benchmark(c: &mut Criterion) { + let contract_artifact: SierraClass = serde_json::from_str(include_str!( + "../test-data/contracts/cairo1/artifacts/erc20_sierra.txt" + )) + .unwrap(); + + c.bench_function("sierra_class_hash", |b| { + b.iter(|| { + black_box(&contract_artifact).class_hash().unwrap(); + }); + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/starknet-crypto/README.md b/starknet-crypto/README.md index 2715776a..54fb2ff6 100644 --- a/starknet-crypto/README.md +++ b/starknet-crypto/README.md @@ -14,47 +14,47 @@ If you're a cryptographer, you're welcome to contribute by reviewing the impleme ## Benchmark -These results were generated on the author's machine with _AMD Ryzen 9 5950X 16-Core Processor_ running _Ubuntu 22.04.1 LTS_. +These results were generated on the author's machine with _Apple M3 Max_ running _macOS 14.5_. For instructions on running the benchmarks yourself, check out [this page](../BENCHMARK.md). ### Native ```log -ecdsa_get_public_key time: [125.53 µs 125.63 µs 125.75 µs] -ecdsa_recover time: [421.74 µs 421.93 µs 422.16 µs] -ecdsa_sign time: [170.30 µs 170.50 µs 170.71 µs] -ecdsa_verify time: [428.34 µs 428.73 µs 429.17 µs] -pedersen_hash time: [33.379 µs 33.435 µs 33.521 µs] -poseidon_hash time: [12.552 µs 12.571 µs 12.595 µs] -poseidon_hash_single time: [12.572 µs 12.587 µs 12.601 µs] -poseidon_hash_many time: [25.048 µs 25.089 µs 25.137 µs] -rfc6979_generate_k time: [1.4810 µs 1.4817 µs 1.4827 µs] +ecdsa_get_public_key time: [52.416 µs 52.456 µs 52.506 µs] +ecdsa_recover time: [233.25 µs 234.29 µs 235.43 µs] +ecdsa_sign time: [87.730 µs 87.967 µs 88.211 µs] +ecdsa_verify time: [239.97 µs 240.65 µs 241.46 µs] +pedersen_hash time: [15.635 µs 15.668 µs 15.695 µs] +poseidon_hash time: [4.6606 µs 4.6828 µs 4.7052 µs] +poseidon_hash_single time: [4.7146 µs 4.7243 µs 4.7341 µs] +poseidon_hash_many time: [10.101 µs 10.419 µs 10.713 µs] +rfc6979_generate_k time: [4.7230 µs 4.7346 µs 4.7469 µs] ``` ### WebAssembly -_(With its excellent wasm performance, results are only provided for Node.js here. Check out the [benchmark page](../BENCHMARK.md) for running the benchmark on other runtimes)._ +_(Results are only provided for `wasmtime` here. Check out the [benchmark page](../BENCHMARK.md) for running the benchmark on other runtimes)._ Runtime version: ```console -$ node --version -v18.16.0 +$ wasmtime --version +wasmtime-cli 21.0.1 (cedf9aa0f 2024-05-22) ``` -Node.js results: +`wasmtime` results: ```log -ecdsa_get_public_key time: [1.0093 ms 1.0118 ms 1.0147 ms] -ecdsa_recover time: [3.0610 ms 3.0627 ms 3.0646 ms] -ecdsa_sign time: [1.0584 ms 1.0600 ms 1.0615 ms] -ecdsa_verify time: [3.0273 ms 3.0309 ms 3.0345 ms] -pedersen_hash time: [234.12 µs 234.30 µs 234.49 µs] -poseidon_hash time: [90.892 µs 91.032 µs 91.166 µs] -poseidon_hash_single time: [90.358 µs 90.404 µs 90.451 µs] -poseidon_hash_many time: [180.93 µs 181.13 µs 181.35 µs] -rfc6979_generate_k time: [9.2623 µs 9.2793 µs 9.2979 µs] +ecdsa_get_public_key time: [264.92 µs 265.06 µs 265.21 µs] +ecdsa_recover time: [921.34 µs 922.06 µs 922.88 µs] +ecdsa_sign time: [311.44 µs 311.58 µs 311.72 µs] +ecdsa_verify time: [916.04 µs 917.13 µs 918.73 µs] +pedersen_hash time: [71.713 µs 71.751 µs 71.795 µs] +poseidon_hash time: [19.333 µs 19.359 µs 19.381 µs] +poseidon_hash_single time: [19.223 µs 19.234 µs 19.245 µs] +poseidon_hash_many time: [39.004 µs 39.048 µs 39.089 µs] +rfc6979_generate_k time: [11.798 µs 11.807 µs 11.817 µs] ``` ## Credits From 8d0c92c3633165caac4472a7ae6d63fff1e79bb6 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:58:28 +0200 Subject: [PATCH 02/28] feat: migrate to `starknet-types-core` Felt type (#562) --- .github/workflows/build.yml | 1 - .github/workflows/test.yaml | 20 - Cargo.lock | 211 +--- Cargo.toml | 4 - README.md | 1 - examples/declare_cairo0_contract.rs | 6 +- examples/declare_cairo1_contract.rs | 9 +- examples/deploy_argent_account.rs | 17 +- examples/deploy_contract.rs | 6 +- examples/erc20_balance.rs | 30 +- examples/mint_tokens.rs | 16 +- examples/starknet-cxx/README.md | 2 +- examples/starknet-cxx/starknet-cxx/src/lib.rs | 12 +- examples/starknet-wasm/Cargo.toml | 1 - examples/starknet-wasm/src/lib.rs | 4 +- starknet-accounts/src/account/declaration.rs | 210 ++-- starknet-accounts/src/account/execution.rs | 143 ++- starknet-accounts/src/account/mod.rs | 114 +- starknet-accounts/src/call.rs | 8 +- starknet-accounts/src/factory/argent.rs | 26 +- starknet-accounts/src/factory/mod.rs | 210 ++-- .../src/factory/open_zeppelin.rs | 22 +- starknet-accounts/src/single_owner.rs | 30 +- .../tests/single_owner_account.rs | 189 +-- starknet-contract/src/factory.rs | 126 +- .../tests/contract_deployment.rs | 52 +- starknet-core/Cargo.toml | 4 +- starknet-core/README.md | 8 +- starknet-core/src/chain_id.rs | 32 +- starknet-core/src/crypto.rs | 132 +- .../src/serde/unsigned_field_element.rs | 41 +- starknet-core/src/types/codegen.rs | 1060 ++++++++-------- starknet-core/src/types/contract/legacy.rs | 34 +- starknet-core/src/types/contract/mod.rs | 50 +- starknet-core/src/types/eth_address.rs | 33 +- starknet-core/src/types/hash_256.rs | 39 +- starknet-core/src/types/mod.rs | 82 +- starknet-core/src/types/msg.rs | 38 +- starknet-core/src/types/receipt_block.rs | 13 +- starknet-core/src/types/serde_impls.rs | 10 +- starknet-core/src/types/u256.rs | 12 +- starknet-core/src/utils.rs | 174 ++- starknet-crypto-codegen/Cargo.toml | 4 +- starknet-crypto-codegen/src/pedersen.rs | 32 +- starknet-crypto-codegen/src/poseidon/mod.rs | 22 +- starknet-crypto/Cargo.toml | 7 +- starknet-crypto/README.md | 36 +- .../benches/ecdsa_get_public_key.rs | 5 +- starknet-crypto/benches/ecdsa_recover.rs | 21 +- starknet-crypto/benches/ecdsa_sign.rs | 9 +- starknet-crypto/benches/ecdsa_verify.rs | 11 +- starknet-crypto/benches/pedersen_hash.rs | 7 +- starknet-crypto/benches/poseidon_hash.rs | 9 +- starknet-crypto/benches/rfc6979_generate_k.rs | 9 +- starknet-crypto/src/ecdsa.rs | 139 ++- starknet-crypto/src/fe_utils.rs | 22 +- starknet-crypto/src/lib.rs | 2 +- starknet-crypto/src/pedersen_hash.rs | 20 +- starknet-crypto/src/poseidon_hash.rs | 126 +- starknet-crypto/src/rfc6979.rs | 11 +- starknet-crypto/src/test_utils.rs | 6 +- starknet-curve/Cargo.toml | 2 +- starknet-curve/src/curve_params.rs | 157 ++- starknet-curve/src/ec_point.rs | 296 ----- starknet-curve/src/lib.rs | 3 - starknet-ff/Cargo.toml | 38 - starknet-ff/README.md | 1 - starknet-ff/src/fr.rs | 8 - starknet-ff/src/lib.rs | 1110 ----------------- starknet-macros/src/lib.rs | 34 +- starknet-providers/Cargo.toml | 3 + starknet-providers/src/any.rs | 36 +- starknet-providers/src/jsonrpc/mod.rs | 48 +- starknet-providers/src/provider.rs | 32 +- starknet-providers/src/sequencer/mod.rs | 34 +- .../src/sequencer/models/block.rs | 46 +- .../src/sequencer/models/contract.rs | 4 +- .../src/sequencer/models/conversions.rs | 42 +- .../src/sequencer/models/state_update.rs | 40 +- .../src/sequencer/models/trace.rs | 24 +- .../src/sequencer/models/transaction.rs | 106 +- .../sequencer/models/transaction_receipt.rs | 25 +- .../sequencer/models/transaction_request.rs | 214 ++-- starknet-providers/src/sequencer/provider.rs | 36 +- starknet-providers/tests/jsonrpc.rs | 243 ++-- starknet-signers/Cargo.toml | 3 + starknet-signers/src/key_pair.rs | 142 +-- starknet-signers/src/local_wallet.rs | 4 +- starknet-signers/src/signer.rs | 4 +- tests/macros.rs | 10 +- 90 files changed, 2333 insertions(+), 4142 deletions(-) delete mode 100644 starknet-curve/src/ec_point.rs delete mode 100644 starknet-ff/Cargo.toml delete mode 100644 starknet-ff/README.md delete mode 100644 starknet-ff/src/fr.rs delete mode 100644 starknet-ff/src/lib.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 638c4ac6..e76c83db 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,7 +14,6 @@ jobs: strategy: matrix: package: - - "starknet-ff" - "starknet-curve" - "starknet-crypto-codegen" - "starknet-crypto" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 2000d7a7..4f93f2c2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -90,10 +90,6 @@ jobs: command: install args: wasm-pack - - name: Run starknet-ff tests - run: | - (cd ./starknet-ff && wasm-pack test --release --node) - - name: Run starknet-crypto tests run: | (cd ./starknet-crypto && wasm-pack test --release --node) @@ -129,22 +125,6 @@ jobs: run: | rustup target add thumbv6m-none-eabi - - name: Build starknet-ff - run: | - cargo build --package starknet-ff \ - --target thumbv6m-none-eabi \ - --no-default-features - - cargo build --package starknet-ff \ - --target thumbv6m-none-eabi \ - --no-default-features \ - --features alloc - - cargo build --package starknet-ff \ - --target thumbv6m-none-eabi \ - --no-default-features \ - --features serde - - name: Build starknet-crypto run: | cargo build --package starknet-crypto \ diff --git a/Cargo.lock b/Cargo.lock index 6ce30066..0fc89dd6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,70 +34,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" -[[package]] -name = "ark-ff" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" -dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", - "derivative", - "digest", - "itertools", - "num-bigint", - "num-traits", - "paste", - "rustc_version", - "zeroize", -] - -[[package]] -name = "ark-ff-asm" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-macros" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" -dependencies = [ - "num-bigint", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-serialize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" -dependencies = [ - "ark-std", - "digest", - "num-bigint", -] - -[[package]] -name = "ark-std" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" -dependencies = [ - "num-traits", - "rand", -] - [[package]] name = "arrayvec" version = "0.7.2" @@ -112,7 +48,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.63", ] [[package]] @@ -156,18 +92,6 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" -[[package]] -name = "bigdecimal" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aaf33151a6429fe9211d1b276eafdf70cdff28b071e76c0b0e1503221ea3744" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "serde", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -446,7 +370,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.15", + "syn 2.0.63", ] [[package]] @@ -463,7 +387,7 @@ checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.63", ] [[package]] @@ -501,17 +425,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "digest" version = "0.10.6" @@ -970,6 +883,12 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "lambdaworks-math" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "358e172628e713b80a530a59654154bfc45783a6ed70ea284839800cebdf8f97" + [[package]] name = "lazy_static" version = "1.4.0" @@ -1042,9 +961,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -1063,9 +982,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -1147,12 +1066,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "paste" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" - [[package]] name = "pbkdf2" version = "0.11.0" @@ -1235,18 +1148,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.26" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1391,15 +1304,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - [[package]] name = "rustls" version = "0.20.8" @@ -1485,30 +1389,24 @@ dependencies = [ "untrusted", ] -[[package]] -name = "semver" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" - [[package]] name = "serde" -version = "1.0.160" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.63", ] [[package]] @@ -1643,7 +1541,6 @@ dependencies = [ "starknet-contract", "starknet-core", "starknet-crypto", - "starknet-ff", "starknet-macros", "starknet-providers", "starknet-signers", @@ -1702,7 +1599,7 @@ dependencies = [ "sha3", "starknet-core", "starknet-crypto", - "starknet-ff", + "starknet-types-core", "wasm-bindgen-test", ] @@ -1724,7 +1621,7 @@ dependencies = [ "sha2", "starknet-crypto-codegen", "starknet-curve", - "starknet-ff", + "starknet-types-core", "wasm-bindgen-test", "zeroize", ] @@ -1734,15 +1631,15 @@ name = "starknet-crypto-codegen" version = "0.3.3" dependencies = [ "starknet-curve", - "starknet-ff", - "syn 2.0.15", + "starknet-types-core", + "syn 2.0.63", ] [[package]] name = "starknet-curve" version = "0.4.2" dependencies = [ - "starknet-ff", + "starknet-types-core", ] [[package]] @@ -1755,26 +1652,12 @@ dependencies = [ "starknet-crypto", ] -[[package]] -name = "starknet-ff" -version = "0.3.7" -dependencies = [ - "ark-ff", - "bigdecimal", - "crypto-bigint", - "getrandom", - "hex", - "num-bigint", - "serde", - "wasm-bindgen-test", -] - [[package]] name = "starknet-macros" version = "0.1.7" dependencies = [ "starknet-core", - "syn 2.0.15", + "syn 2.0.63", ] [[package]] @@ -1785,6 +1668,7 @@ dependencies = [ "auto_impl", "ethereum-types", "flate2", + "getrandom", "log", "reqwest", "serde", @@ -1805,6 +1689,7 @@ dependencies = [ "auto_impl", "crypto-bigint", "eth-keystore", + "getrandom", "rand", "starknet-core", "starknet-crypto", @@ -1812,13 +1697,25 @@ dependencies = [ "wasm-bindgen-test", ] +[[package]] +name = "starknet-types-core" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe29a53d28ff630e4c7827788f14b28f9386d27cb9d05186a5f2e73218c34677" +dependencies = [ + "lambdaworks-math", + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + [[package]] name = "starknet-wasm" version = "0.1.0" dependencies = [ "console_error_panic_hook", "starknet-crypto", - "starknet-ff", "wasm-bindgen", ] @@ -1853,9 +1750,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.15" +version = "2.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" dependencies = [ "proc-macro2", "quote", @@ -1900,7 +1797,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.63", ] [[package]] @@ -1991,7 +1888,7 @@ checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.63", ] [[package]] @@ -2486,17 +2383,3 @@ name = "zeroize" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.15", -] diff --git a/Cargo.toml b/Cargo.toml index 7d01e5f2..00ada836 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,6 @@ members = [ "starknet-crypto", "starknet-signers", "starknet-accounts", - "starknet-ff", "starknet-macros", "starknet-curve", "starknet-crypto-codegen", @@ -34,7 +33,6 @@ members = [ all-features = true [dependencies] -starknet-ff = { version = "0.3.7", path = "./starknet-ff", default-features = false } starknet-crypto = { version = "0.6.2", path = "./starknet-crypto" } starknet-core = { version = "0.10.0", path = "./starknet-core", default-features = false } starknet-providers = { version = "0.10.0", path = "./starknet-providers" } @@ -49,8 +47,6 @@ tokio = { version = "1.15.0", features = ["full"] } url = "2.2.2" [features] -default = ["bigdecimal"] -bigdecimal = ["starknet-ff/bigdecimal"] no_unknown_fields = [ "starknet-core/no_unknown_fields", "starknet-providers/no_unknown_fields", diff --git a/README.md b/README.md index 2a837c5b..ff782c89 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,6 @@ This workspace contains the following crates: - `starknet-crypto`: **Low-level** cryptography utilities for Starknet - `starknet-signers`: Starknet signer implementations - `starknet-accounts`: Types for handling Starknet account abstraction -- `starknet-ff`: Starknet field element type - `starknet-curve`: Starknet curve operations - `starknet-macros`: Useful macros for using the `starknet` crates diff --git a/examples/declare_cairo0_contract.rs b/examples/declare_cairo0_contract.rs index 1d5248f6..bb7dadfc 100644 --- a/examples/declare_cairo0_contract.rs +++ b/examples/declare_cairo0_contract.rs @@ -4,7 +4,7 @@ use starknet::{ accounts::{Account, ExecutionEncoding, SingleOwnerAccount}, core::{ chain_id, - types::{contract::legacy::LegacyContractClass, BlockId, BlockTag, FieldElement}, + types::{contract::legacy::LegacyContractClass, BlockId, BlockTag, Felt}, }, providers::{ jsonrpc::{HttpTransport, JsonRpcClient}, @@ -23,9 +23,9 @@ async fn main() { )); let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be("YOUR_PRIVATE_KEY_IN_HEX_HERE").unwrap(), + Felt::from_hex("YOUR_PRIVATE_KEY_IN_HEX_HERE").unwrap(), )); - let address = FieldElement::from_hex_be("YOUR_ACCOUNT_CONTRACT_ADDRESS_IN_HEX_HERE").unwrap(); + let address = Felt::from_hex("YOUR_ACCOUNT_CONTRACT_ADDRESS_IN_HEX_HERE").unwrap(); let mut account = SingleOwnerAccount::new( provider, diff --git a/examples/declare_cairo1_contract.rs b/examples/declare_cairo1_contract.rs index 92811586..f6f2fb3d 100644 --- a/examples/declare_cairo1_contract.rs +++ b/examples/declare_cairo1_contract.rs @@ -4,7 +4,7 @@ use starknet::{ accounts::{Account, ExecutionEncoding, SingleOwnerAccount}, core::{ chain_id, - types::{contract::SierraClass, BlockId, BlockTag, FieldElement}, + types::{contract::SierraClass, BlockId, BlockTag, Felt}, }, providers::{ jsonrpc::{HttpTransport, JsonRpcClient}, @@ -21,17 +21,16 @@ async fn main() { .unwrap(); // Class hash of the compiled CASM class from the `starknet-sierra-compile` command - let compiled_class_hash = - FieldElement::from_hex_be("COMPILED_CASM_CLASS_HASH_IN_HEX_HERE").unwrap(); + let compiled_class_hash = Felt::from_hex("COMPILED_CASM_CLASS_HASH_IN_HEX_HERE").unwrap(); let provider = JsonRpcClient::new(HttpTransport::new( Url::parse("https://starknet-sepolia.public.blastapi.io/rpc/v0_7").unwrap(), )); let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be("YOUR_PRIVATE_KEY_IN_HEX_HERE").unwrap(), + Felt::from_hex("YOUR_PRIVATE_KEY_IN_HEX_HERE").unwrap(), )); - let address = FieldElement::from_hex_be("YOUR_ACCOUNT_CONTRACT_ADDRESS_IN_HEX_HERE").unwrap(); + let address = Felt::from_hex("YOUR_ACCOUNT_CONTRACT_ADDRESS_IN_HEX_HERE").unwrap(); let mut account = SingleOwnerAccount::new( provider, diff --git a/examples/deploy_argent_account.rs b/examples/deploy_argent_account.rs index c3545103..bf4ffae4 100644 --- a/examples/deploy_argent_account.rs +++ b/examples/deploy_argent_account.rs @@ -1,6 +1,6 @@ use starknet::{ accounts::{AccountFactory, ArgentAccountFactory}, - core::{chain_id, types::FieldElement}, + core::{chain_id, types::Felt}, macros::felt, providers::{ jsonrpc::{HttpTransport, JsonRpcClient}, @@ -22,18 +22,13 @@ async fn main() { )); let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be("YOUR_PRIVATE_KEY_IN_HEX_HERE").unwrap(), + Felt::from_hex("YOUR_PRIVATE_KEY_IN_HEX_HERE").unwrap(), )); - let factory = ArgentAccountFactory::new( - class_hash, - chain_id::SEPOLIA, - FieldElement::ZERO, - signer, - provider, - ) - .await - .unwrap(); + let factory = + ArgentAccountFactory::new(class_hash, chain_id::SEPOLIA, Felt::ZERO, signer, provider) + .await + .unwrap(); let deployment = factory.deploy_v1(salt); diff --git a/examples/deploy_contract.rs b/examples/deploy_contract.rs index 2219fb6f..049bad5e 100644 --- a/examples/deploy_contract.rs +++ b/examples/deploy_contract.rs @@ -5,7 +5,7 @@ use starknet::{ contract::ContractFactory, core::{ chain_id, - types::{contract::legacy::LegacyContractClass, BlockId, BlockTag, FieldElement}, + types::{contract::legacy::LegacyContractClass, BlockId, BlockTag, Felt}, }, macros::felt, providers::{ @@ -28,9 +28,9 @@ async fn main() { )); let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be("YOUR_PRIVATE_KEY_IN_HEX_HERE").unwrap(), + Felt::from_hex("YOUR_PRIVATE_KEY_IN_HEX_HERE").unwrap(), )); - let address = FieldElement::from_hex_be("YOUR_ACCOUNT_CONTRACT_ADDRESS_IN_HEX_HERE").unwrap(); + let address = Felt::from_hex("YOUR_ACCOUNT_CONTRACT_ADDRESS_IN_HEX_HERE").unwrap(); let mut account = SingleOwnerAccount::new( provider, signer, diff --git a/examples/erc20_balance.rs b/examples/erc20_balance.rs index 96f60288..2e21c42a 100644 --- a/examples/erc20_balance.rs +++ b/examples/erc20_balance.rs @@ -1,5 +1,5 @@ use starknet::{ - core::types::{BlockId, BlockTag, FieldElement, FunctionCall}, + core::types::{BlockId, BlockTag, Felt, FunctionCall}, macros::{felt, selector}, providers::{ jsonrpc::{HttpTransport, JsonRpcClient}, @@ -16,20 +16,20 @@ async fn main() { let tst_token_address = felt!("0x07394cbe418daa16e42b87ba67372d4ab4a5df0b05c6e554d158458ce245bc10"); - let call_result = provider - .call( - FunctionCall { - contract_address: tst_token_address, - entry_point_selector: selector!("balanceOf"), - calldata: vec![FieldElement::from_hex_be( - "YOUR_ACCOUNT_CONTRACT_ADDRESS_IN_HEX_HERE", - ) - .unwrap()], - }, - BlockId::Tag(BlockTag::Latest), - ) - .await - .expect("failed to call contract"); + let call_result = + provider + .call( + FunctionCall { + contract_address: tst_token_address, + entry_point_selector: selector!("balanceOf"), + calldata: vec![ + Felt::from_hex("YOUR_ACCOUNT_CONTRACT_ADDRESS_IN_HEX_HERE").unwrap() + ], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await + .expect("failed to call contract"); dbg!(call_result); } diff --git a/examples/mint_tokens.rs b/examples/mint_tokens.rs index 71718382..33e86ea2 100644 --- a/examples/mint_tokens.rs +++ b/examples/mint_tokens.rs @@ -2,7 +2,7 @@ use starknet::{ accounts::{Account, Call, ExecutionEncoding, SingleOwnerAccount}, core::{ chain_id, - types::{BlockId, BlockTag, FieldElement}, + types::{BlockId, BlockTag, Felt}, utils::get_selector_from_name, }, providers::{ @@ -19,13 +19,11 @@ async fn main() { )); let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be("YOUR_PRIVATE_KEY_IN_HEX_HERE").unwrap(), + Felt::from_hex("YOUR_PRIVATE_KEY_IN_HEX_HERE").unwrap(), )); - let address = FieldElement::from_hex_be("YOUR_ACCOUNT_CONTRACT_ADDRESS_IN_HEX_HERE").unwrap(); - let tst_token_address = FieldElement::from_hex_be( - "07394cbe418daa16e42b87ba67372d4ab4a5df0b05c6e554d158458ce245bc10", - ) - .unwrap(); + let address = Felt::from_hex("YOUR_ACCOUNT_CONTRACT_ADDRESS_IN_HEX_HERE").unwrap(); + let tst_token_address = + Felt::from_hex("07394cbe418daa16e42b87ba67372d4ab4a5df0b05c6e554d158458ce245bc10").unwrap(); let mut account = SingleOwnerAccount::new( provider, @@ -45,8 +43,8 @@ async fn main() { selector: get_selector_from_name("mint").unwrap(), calldata: vec![ address, - FieldElement::from_dec_str("1000000000000000000000").unwrap(), - FieldElement::ZERO, + Felt::from_dec_str("1000000000000000000000").unwrap(), + Felt::ZERO, ], }]) .send() diff --git a/examples/starknet-cxx/README.md b/examples/starknet-cxx/README.md index fc231bcd..1aa0a763 100644 --- a/examples/starknet-cxx/README.md +++ b/examples/starknet-cxx/README.md @@ -8,7 +8,7 @@ As noted in the [`starknet-crypto` page](../../starknet-crypto/), you're advised ## Note -This wrapper crate expose functions that operate on strings, which is bad and probably hurts performance. It's possible to make the C++ side create `FieldElement` instances and operate on those instead, which is much more idiomatic. That said, this demo wrapper crate seems to already offer decent performance. +This wrapper crate expose functions that operate on strings, which is bad and probably hurts performance. It's possible to make the C++ side create `Felt` instances and operate on those instead, which is much more idiomatic. That said, this demo wrapper crate seems to already offer decent performance. Moreover, this crate does not implement error handling and always just panics on error, which is likely not what you want in production. diff --git a/examples/starknet-cxx/starknet-cxx/src/lib.rs b/examples/starknet-cxx/starknet-cxx/src/lib.rs index a45803e0..f34221b5 100644 --- a/examples/starknet-cxx/starknet-cxx/src/lib.rs +++ b/examples/starknet-cxx/starknet-cxx/src/lib.rs @@ -2,7 +2,7 @@ //! https://github.com/xJonathanLEI/starknet-rs/issues/325 //! //! This wrapper crate expose functions that operate on strings, which is bad and probably hurts -//! performance. It's possible to make the C++ side create `FieldElement` instances and operate on +//! performance. It's possible to make the C++ side create `Felt` instances and operate on //! those instead, which is much more idiomatic. That said, this demo wrapper crate seems to already //! offer decent performance. //! @@ -13,7 +13,7 @@ //! create idiomatic bindings, which is way too much work to maintain as an example, and should be //! a project of its own. -use starknet_core::{crypto::Signature, types::FieldElement}; +use starknet_core::{crypto::Signature, types::Felt}; #[cxx::bridge] mod ffi { @@ -26,16 +26,16 @@ mod ffi { pub fn pedersen_hash(x: &str, y: &str) -> String { // WARNING: no error handling here - let x = FieldElement::from_hex_be(x).unwrap(); - let y = FieldElement::from_hex_be(y).unwrap(); + let x = Felt::from_hex(x).unwrap(); + let y = Felt::from_hex(y).unwrap(); format!("{:#064x}", starknet_core::crypto::pedersen_hash(&x, &y)) } fn ecdsa_sign(private_key: &str, message: &str) -> String { // WARNING: no error handling here - let private_key = FieldElement::from_hex_be(private_key).unwrap(); - let message = FieldElement::from_hex_be(message).unwrap(); + let private_key = Felt::from_hex(private_key).unwrap(); + let message = Felt::from_hex(message).unwrap(); let signature: Signature = starknet_core::crypto::ecdsa_sign(&private_key, &message) // WARNING: no error handling here diff --git a/examples/starknet-wasm/Cargo.toml b/examples/starknet-wasm/Cargo.toml index 4d93155d..d214878f 100644 --- a/examples/starknet-wasm/Cargo.toml +++ b/examples/starknet-wasm/Cargo.toml @@ -19,7 +19,6 @@ crate-type = ["cdylib", "rlib"] default = ["console_error_panic_hook"] [dependencies] -starknet-ff = { version = "0.3.7", path = "../../starknet-ff" } starknet-crypto = { version = "0.6.2", path = "../../starknet-crypto" } console_error_panic_hook = { version = "0.1.7", optional = true } wasm-bindgen = "0.2.84" diff --git a/examples/starknet-wasm/src/lib.rs b/examples/starknet-wasm/src/lib.rs index 2d6f0625..a32699fa 100644 --- a/examples/starknet-wasm/src/lib.rs +++ b/examples/starknet-wasm/src/lib.rs @@ -1,6 +1,6 @@ #![allow(clippy::unused_unit)] -use starknet_crypto::FieldElement; +use starknet_crypto::Felt; use wasm_bindgen::prelude::*; #[wasm_bindgen] @@ -8,7 +8,7 @@ pub fn get_public_key(private_key_hex: &str) -> String { #[cfg(feature = "console_error_panic_hook")] console_error_panic_hook::set_once(); - let private_key = FieldElement::from_hex_be(private_key_hex).unwrap(); + let private_key = Felt::from_hex(private_key_hex).unwrap(); let public_key = starknet_crypto::get_public_key(&private_key); format!("{public_key:#064x}") diff --git a/starknet-accounts/src/account/declaration.rs b/starknet-accounts/src/account/declaration.rs index f3535ae2..5162320f 100644 --- a/starknet-accounts/src/account/declaration.rs +++ b/starknet-accounts/src/account/declaration.rs @@ -10,9 +10,8 @@ use starknet_core::{ contract::{legacy::LegacyContractClass, ComputeClassHashError}, BroadcastedDeclareTransaction, BroadcastedDeclareTransactionV1, BroadcastedDeclareTransactionV2, BroadcastedDeclareTransactionV3, BroadcastedTransaction, - DataAvailabilityMode, DeclareTransactionResult, FeeEstimate, FieldElement, - FlattenedSierraClass, ResourceBounds, ResourceBoundsMapping, SimulatedTransaction, - SimulationFlag, + DataAvailabilityMode, DeclareTransactionResult, FeeEstimate, Felt, FlattenedSierraClass, + ResourceBounds, ResourceBoundsMapping, SimulatedTransaction, SimulationFlag, }, }; use starknet_crypto::PoseidonHasher; @@ -20,41 +19,41 @@ use starknet_providers::Provider; use std::sync::Arc; /// Cairo string for "declare" -const PREFIX_DECLARE: FieldElement = FieldElement::from_mont([ - 17542456862011667323, +const PREFIX_DECLARE: Felt = Felt::from_raw([ + 191557713328401194, 18446744073709551615, 18446744073709551615, - 191557713328401194, + 17542456862011667323, ]); /// 2 ^ 128 + 1 -const QUERY_VERSION_ONE: FieldElement = FieldElement::from_mont([ - 18446744073700081633, - 17407, - 18446744073709551584, +const QUERY_VERSION_ONE: Felt = Felt::from_raw([ 576460752142433776, + 18446744073709551584, + 17407, + 18446744073700081633, ]); /// 2 ^ 128 + 2 -const QUERY_VERSION_TWO: FieldElement = FieldElement::from_mont([ - 18446744073700081601, - 17407, - 18446744073709551584, +const QUERY_VERSION_TWO: Felt = Felt::from_raw([ 576460752142433232, + 18446744073709551584, + 17407, + 18446744073700081601, ]); /// 2 ^ 128 + 3 -const QUERY_VERSION_THREE: FieldElement = FieldElement::from_mont([ - 18446744073700081569, - 17407, - 18446744073709551584, +const QUERY_VERSION_THREE: Felt = Felt::from_raw([ 576460752142432688, + 18446744073709551584, + 17407, + 18446744073700081569, ]); impl<'a, A> DeclarationV2<'a, A> { pub fn new( contract_class: Arc, - compiled_class_hash: FieldElement, + compiled_class_hash: Felt, account: &'a A, ) -> Self { Self { @@ -67,14 +66,14 @@ impl<'a, A> DeclarationV2<'a, A> { } } - pub fn nonce(self, nonce: FieldElement) -> Self { + pub fn nonce(self, nonce: Felt) -> Self { Self { nonce: Some(nonce), ..self } } - pub fn max_fee(self, max_fee: FieldElement) -> Self { + pub fn max_fee(self, max_fee: Felt) -> Self { Self { max_fee: Some(max_fee), ..self @@ -162,11 +161,22 @@ where let max_fee = match self.max_fee { Some(value) => value, None => { + // Obtain the fee estimate let fee_estimate = self.estimate_fee_with_nonce(nonce).await?; - ((((TryInto::::try_into(fee_estimate.overall_fee) - .map_err(|_| AccountError::FeeOutOfRange)?) as f64) - * self.fee_estimate_multiplier) as u64) - .into() + // Convert the overall fee to little-endian bytes + let overall_fee_bytes = fee_estimate.overall_fee.to_bytes_le(); + + // Check if the remaining bytes after the first 8 are all zeros + if overall_fee_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountError::FeeOutOfRange); + } + + // Convert the first 8 bytes to u64 + let overall_fee_u64 = + u64::from_le_bytes(overall_fee_bytes[..8].try_into().unwrap()); + + // Perform necessary operations on overall_fee_u64 and convert to f64 then to u64 + (((overall_fee_u64 as f64) * self.fee_estimate_multiplier) as u64).into() } }; @@ -183,7 +193,7 @@ where async fn estimate_fee_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, ) -> Result> { let prepared = PreparedDeclarationV2 { account: self.account, @@ -191,7 +201,7 @@ where contract_class: self.contract_class.clone(), compiled_class_hash: self.compiled_class_hash, nonce, - max_fee: FieldElement::ZERO, + max_fee: Felt::ZERO, }, }; let declare = prepared.get_declare_request(true).await?; @@ -209,7 +219,7 @@ where async fn simulate_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, skip_validate: bool, skip_fee_charge: bool, ) -> Result> { @@ -248,7 +258,7 @@ where impl<'a, A> DeclarationV3<'a, A> { pub fn new( contract_class: Arc, - compiled_class_hash: FieldElement, + compiled_class_hash: Felt, account: &'a A, ) -> Self { Self { @@ -263,7 +273,7 @@ impl<'a, A> DeclarationV3<'a, A> { } } - pub fn nonce(self, nonce: FieldElement) -> Self { + pub fn nonce(self, nonce: Felt) -> Self { Self { nonce: Some(nonce), ..self @@ -388,10 +398,15 @@ where .l1_gas_price() .price_in_fri; - let gas_price = (((TryInto::::try_into(block_l1_gas_price) - .map_err(|_| AccountError::FeeOutOfRange)?) - as f64) - * self.gas_price_estimate_multiplier) as u128; + let block_l1_gas_price_bytes = block_l1_gas_price.to_bytes_le(); + if block_l1_gas_price_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountError::FeeOutOfRange); + } + let block_l1_gas_price = + u64::from_le_bytes(block_l1_gas_price_bytes[..8].try_into().unwrap()); + + let gas_price = + ((block_l1_gas_price as f64) * self.gas_price_estimate_multiplier) as u128; (gas, gas_price) } @@ -402,12 +417,21 @@ where let gas = match self.gas { Some(gas) => gas, None => { - (((TryInto::::try_into( - (fee_estimate.overall_fee + fee_estimate.gas_price - FieldElement::ONE) - .floor_div(fee_estimate.gas_price), - ) - .map_err(|_| AccountError::FeeOutOfRange)?) - as f64) + let overall_fee_bytes = fee_estimate.overall_fee.to_bytes_le(); + if overall_fee_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountError::FeeOutOfRange); + } + let overall_fee = + u64::from_le_bytes(overall_fee_bytes[..8].try_into().unwrap()); + + let gas_price_bytes = fee_estimate.gas_price.to_bytes_le(); + if gas_price_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountError::FeeOutOfRange); + } + let gas_price = + u64::from_le_bytes(gas_price_bytes[..8].try_into().unwrap()); + + (((overall_fee + gas_price - 1) / gas_price) as f64 * self.gas_estimate_multiplier) as u64 } }; @@ -415,10 +439,14 @@ where let gas_price = match self.gas_price { Some(gas_price) => gas_price, None => { - (((TryInto::::try_into(fee_estimate.gas_price) - .map_err(|_| AccountError::FeeOutOfRange)?) - as f64) - * self.gas_price_estimate_multiplier) as u128 + let gas_price_bytes = fee_estimate.gas_price.to_bytes_le(); + if gas_price_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountError::FeeOutOfRange); + } + let gas_price = + u64::from_le_bytes(gas_price_bytes[..8].try_into().unwrap()); + + ((gas_price as f64) * self.gas_price_estimate_multiplier) as u128 } }; @@ -440,7 +468,7 @@ where async fn estimate_fee_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, ) -> Result> { let prepared = PreparedDeclarationV3 { account: self.account, @@ -467,7 +495,7 @@ where async fn simulate_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, skip_validate: bool, skip_fee_charge: bool, ) -> Result> { @@ -515,14 +543,14 @@ impl<'a, A> LegacyDeclaration<'a, A> { } } - pub fn nonce(self, nonce: FieldElement) -> Self { + pub fn nonce(self, nonce: Felt) -> Self { Self { nonce: Some(nonce), ..self } } - pub fn max_fee(self, max_fee: FieldElement) -> Self { + pub fn max_fee(self, max_fee: Felt) -> Self { Self { max_fee: Some(max_fee), ..self @@ -612,11 +640,22 @@ where let max_fee = match self.max_fee { Some(value) => value, None => { + // Obtain the fee estimate let fee_estimate = self.estimate_fee_with_nonce(nonce).await?; - ((((TryInto::::try_into(fee_estimate.overall_fee) - .map_err(|_| AccountError::FeeOutOfRange)?) as f64) - * self.fee_estimate_multiplier) as u64) - .into() + // Convert the overall fee to little-endian bytes + let overall_fee_bytes = fee_estimate.overall_fee.to_bytes_le(); + + // Check if the remaining bytes after the first 8 are all zeros + if overall_fee_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountError::FeeOutOfRange); + } + + // Convert the first 8 bytes to u64 + let overall_fee_u64 = + u64::from_le_bytes(overall_fee_bytes[..8].try_into().unwrap()); + + // Perform necessary operations on overall_fee_u64 and convert to f64 then to u64 + (((overall_fee_u64 as f64) * self.fee_estimate_multiplier) as u64).into() } }; @@ -632,14 +671,14 @@ where async fn estimate_fee_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, ) -> Result> { let prepared = PreparedLegacyDeclaration { account: self.account, inner: RawLegacyDeclaration { contract_class: self.contract_class.clone(), nonce, - max_fee: FieldElement::ZERO, + max_fee: Felt::ZERO, }, }; let declare = prepared.get_declare_request(true).await?; @@ -657,7 +696,7 @@ where async fn simulate_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, skip_validate: bool, skip_fee_charge: bool, ) -> Result> { @@ -693,21 +732,16 @@ where } impl RawDeclarationV2 { - pub fn transaction_hash( - &self, - chain_id: FieldElement, - address: FieldElement, - query_only: bool, - ) -> FieldElement { + pub fn transaction_hash(&self, chain_id: Felt, address: Felt, query_only: bool) -> Felt { compute_hash_on_elements(&[ PREFIX_DECLARE, if query_only { QUERY_VERSION_TWO } else { - FieldElement::TWO + Felt::TWO }, // version address, - FieldElement::ZERO, // entry_point_selector + Felt::ZERO, // entry_point_selector compute_hash_on_elements(&[self.contract_class.class_hash()]), self.max_fee, chain_id, @@ -720,33 +754,28 @@ impl RawDeclarationV2 { &self.contract_class } - pub fn compiled_class_hash(&self) -> FieldElement { + pub fn compiled_class_hash(&self) -> Felt { self.compiled_class_hash } - pub fn nonce(&self) -> FieldElement { + pub fn nonce(&self) -> Felt { self.nonce } - pub fn max_fee(&self) -> FieldElement { + pub fn max_fee(&self) -> Felt { self.max_fee } } impl RawDeclarationV3 { - pub fn transaction_hash( - &self, - chain_id: FieldElement, - address: FieldElement, - query_only: bool, - ) -> FieldElement { + pub fn transaction_hash(&self, chain_id: Felt, address: Felt, query_only: bool) -> Felt { let mut hasher = PoseidonHasher::new(); hasher.update(PREFIX_DECLARE); hasher.update(if query_only { QUERY_VERSION_THREE } else { - FieldElement::THREE + Felt::THREE }); hasher.update(address); @@ -754,7 +783,7 @@ impl RawDeclarationV3 { let mut fee_hasher = PoseidonHasher::new(); // Tip: fee market has not been been activated yet so it's hard-coded to be 0 - fee_hasher.update(FieldElement::ZERO); + fee_hasher.update(Felt::ZERO); let mut resource_buffer = [ 0, 0, b'L', b'1', b'_', b'G', b'A', b'S', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -762,14 +791,14 @@ impl RawDeclarationV3 { ]; resource_buffer[8..(8 + 8)].copy_from_slice(&self.gas.to_be_bytes()); resource_buffer[(8 + 8)..].copy_from_slice(&self.gas_price.to_be_bytes()); - fee_hasher.update(FieldElement::from_bytes_be(&resource_buffer).unwrap()); + fee_hasher.update(Felt::from_bytes_be(&resource_buffer)); // L2 resources are hard-coded to 0 let resource_buffer = [ 0, 0, b'L', b'2', b'_', b'G', b'A', b'S', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; - fee_hasher.update(FieldElement::from_bytes_be(&resource_buffer).unwrap()); + fee_hasher.update(Felt::from_bytes_be(&resource_buffer)); fee_hasher.finalize() }); @@ -781,7 +810,7 @@ impl RawDeclarationV3 { hasher.update(self.nonce); // Hard-coded L1 DA mode for nonce and fee - hasher.update(FieldElement::ZERO); + hasher.update(Felt::ZERO); // Hard-coded empty `account_deployment_data` hasher.update(PoseidonHasher::new().finalize()); @@ -796,11 +825,11 @@ impl RawDeclarationV3 { &self.contract_class } - pub fn compiled_class_hash(&self) -> FieldElement { + pub fn compiled_class_hash(&self) -> Felt { self.compiled_class_hash } - pub fn nonce(&self) -> FieldElement { + pub fn nonce(&self) -> Felt { self.nonce } @@ -816,19 +845,19 @@ impl RawDeclarationV3 { impl RawLegacyDeclaration { pub fn transaction_hash( &self, - chain_id: FieldElement, - address: FieldElement, + chain_id: Felt, + address: Felt, query_only: bool, - ) -> Result { + ) -> Result { Ok(compute_hash_on_elements(&[ PREFIX_DECLARE, if query_only { QUERY_VERSION_ONE } else { - FieldElement::ONE + Felt::ONE }, // version address, - FieldElement::ZERO, // entry_point_selector + Felt::ZERO, // entry_point_selector compute_hash_on_elements(&[self.contract_class.class_hash()?]), self.max_fee, chain_id, @@ -840,11 +869,11 @@ impl RawLegacyDeclaration { &self.contract_class } - pub fn nonce(&self) -> FieldElement { + pub fn nonce(&self) -> Felt { self.nonce } - pub fn max_fee(&self) -> FieldElement { + pub fn max_fee(&self) -> Felt { self.max_fee } } @@ -855,7 +884,7 @@ where { /// Locally calculates the hash of the transaction to be sent from this declaration given the /// parameters. - pub fn transaction_hash(&self, query_only: bool) -> FieldElement { + pub fn transaction_hash(&self, query_only: bool) -> Felt { self.inner .transaction_hash(self.account.chain_id(), self.account.address(), query_only) } @@ -902,7 +931,7 @@ where { /// Locally calculates the hash of the transaction to be sent from this declaration given the /// parameters. - pub fn transaction_hash(&self, query_only: bool) -> FieldElement { + pub fn transaction_hash(&self, query_only: bool) -> Felt { self.inner .transaction_hash(self.account.chain_id(), self.account.address(), query_only) } @@ -968,10 +997,7 @@ where { /// Locally calculates the hash of the transaction to be sent from this declaration given the /// parameters. - pub fn transaction_hash( - &self, - query_only: bool, - ) -> Result { + pub fn transaction_hash(&self, query_only: bool) -> Result { self.inner .transaction_hash(self.account.chain_id(), self.account.address(), query_only) } diff --git a/starknet-accounts/src/account/execution.rs b/starknet-accounts/src/account/execution.rs index d16ec031..cef482fc 100644 --- a/starknet-accounts/src/account/execution.rs +++ b/starknet-accounts/src/account/execution.rs @@ -9,35 +9,35 @@ use starknet_core::{ types::{ BroadcastedInvokeTransaction, BroadcastedInvokeTransactionV1, BroadcastedInvokeTransactionV3, BroadcastedTransaction, DataAvailabilityMode, FeeEstimate, - FieldElement, InvokeTransactionResult, ResourceBounds, ResourceBoundsMapping, - SimulatedTransaction, SimulationFlag, + Felt, InvokeTransactionResult, ResourceBounds, ResourceBoundsMapping, SimulatedTransaction, + SimulationFlag, }, }; use starknet_crypto::PoseidonHasher; use starknet_providers::Provider; /// Cairo string for "invoke" -const PREFIX_INVOKE: FieldElement = FieldElement::from_mont([ - 18443034532770911073, +const PREFIX_INVOKE: Felt = Felt::from_raw([ + 513398556346534256, 18446744073709551615, 18446744073709551615, - 513398556346534256, + 18443034532770911073, ]); /// 2 ^ 128 + 1 -const QUERY_VERSION_ONE: FieldElement = FieldElement::from_mont([ - 18446744073700081633, - 17407, - 18446744073709551584, +const QUERY_VERSION_ONE: Felt = Felt::from_raw([ 576460752142433776, + 18446744073709551584, + 17407, + 18446744073700081633, ]); /// 2 ^ 128 + 3 -const QUERY_VERSION_THREE: FieldElement = FieldElement::from_mont([ - 18446744073700081569, - 17407, - 18446744073709551584, +const QUERY_VERSION_THREE: Felt = Felt::from_raw([ 576460752142432688, + 18446744073709551584, + 17407, + 18446744073700081569, ]); impl<'a, A> ExecutionV1<'a, A> { @@ -51,14 +51,14 @@ impl<'a, A> ExecutionV1<'a, A> { } } - pub fn nonce(self, nonce: FieldElement) -> Self { + pub fn nonce(self, nonce: Felt) -> Self { Self { nonce: Some(nonce), ..self } } - pub fn max_fee(self, max_fee: FieldElement) -> Self { + pub fn max_fee(self, max_fee: Felt) -> Self { Self { max_fee: Some(max_fee), ..self @@ -102,7 +102,7 @@ impl<'a, A> ExecutionV3<'a, A> { } } - pub fn nonce(self, nonce: FieldElement) -> Self { + pub fn nonce(self, nonce: Felt) -> Self { Self { nonce: Some(nonce), ..self @@ -212,11 +212,22 @@ where let max_fee = match self.max_fee { Some(value) => value, None => { + // Obtain the fee estimate let fee_estimate = self.estimate_fee_with_nonce(nonce).await?; - ((((TryInto::::try_into(fee_estimate.overall_fee) - .map_err(|_| AccountError::FeeOutOfRange)?) as f64) - * self.fee_estimate_multiplier) as u64) - .into() + // Convert the overall fee to little-endian bytes + let overall_fee_bytes = fee_estimate.overall_fee.to_bytes_le(); + + // Check if the remaining bytes after the first 8 are all zeros + if overall_fee_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountError::FeeOutOfRange); + } + + // Convert the first 8 bytes to u64 + let overall_fee_u64 = + u64::from_le_bytes(overall_fee_bytes[..8].try_into().unwrap()); + + // Perform necessary operations on overall_fee_u64 and convert to f64 then to u64 + (((overall_fee_u64 as f64) * self.fee_estimate_multiplier) as u64).into() } }; @@ -232,14 +243,14 @@ where async fn estimate_fee_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, ) -> Result> { let prepared = PreparedExecutionV1 { account: self.account, inner: RawExecutionV1 { calls: self.calls.clone(), nonce, - max_fee: FieldElement::ZERO, + max_fee: Felt::ZERO, }, }; let invoke = prepared @@ -260,7 +271,7 @@ where async fn simulate_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, skip_validate: bool, skip_fee_charge: bool, ) -> Result> { @@ -368,10 +379,15 @@ where .l1_gas_price() .price_in_fri; - let gas_price = (((TryInto::::try_into(block_l1_gas_price) - .map_err(|_| AccountError::FeeOutOfRange)?) - as f64) - * self.gas_price_estimate_multiplier) as u128; + let block_l1_gas_price_bytes = block_l1_gas_price.to_bytes_le(); + if block_l1_gas_price_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountError::FeeOutOfRange); + } + let block_l1_gas_price = + u64::from_le_bytes(block_l1_gas_price_bytes[..8].try_into().unwrap()); + + let gas_price = + ((block_l1_gas_price as f64) * self.gas_price_estimate_multiplier) as u128; (gas, gas_price) } @@ -382,12 +398,21 @@ where let gas = match self.gas { Some(gas) => gas, None => { - (((TryInto::::try_into( - (fee_estimate.overall_fee + fee_estimate.gas_price - FieldElement::ONE) - .floor_div(fee_estimate.gas_price), - ) - .map_err(|_| AccountError::FeeOutOfRange)?) - as f64) + let overall_fee_bytes = fee_estimate.overall_fee.to_bytes_le(); + if overall_fee_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountError::FeeOutOfRange); + } + let overall_fee = + u64::from_le_bytes(overall_fee_bytes[..8].try_into().unwrap()); + + let gas_price_bytes = fee_estimate.gas_price.to_bytes_le(); + if gas_price_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountError::FeeOutOfRange); + } + let gas_price = + u64::from_le_bytes(gas_price_bytes[..8].try_into().unwrap()); + + ((((overall_fee + gas_price - 1) / gas_price) as f64) * self.gas_estimate_multiplier) as u64 } }; @@ -395,10 +420,14 @@ where let gas_price = match self.gas_price { Some(gas_price) => gas_price, None => { - (((TryInto::::try_into(fee_estimate.gas_price) - .map_err(|_| AccountError::FeeOutOfRange)?) - as f64) - * self.gas_price_estimate_multiplier) as u128 + let gas_price_bytes = fee_estimate.gas_price.to_bytes_le(); + if gas_price_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountError::FeeOutOfRange); + } + let gas_price = + u64::from_le_bytes(gas_price_bytes[..8].try_into().unwrap()); + + ((gas_price as f64) * self.gas_price_estimate_multiplier) as u128 } }; @@ -419,7 +448,7 @@ where async fn estimate_fee_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, ) -> Result> { let prepared = PreparedExecutionV3 { account: self.account, @@ -448,7 +477,7 @@ where async fn simulate_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, skip_validate: bool, skip_fee_charge: bool, ) -> Result> { @@ -490,11 +519,11 @@ where impl RawExecutionV1 { pub fn transaction_hash( &self, - chain_id: FieldElement, - address: FieldElement, + chain_id: Felt, + address: Felt, query_only: bool, encoder: E, - ) -> FieldElement + ) -> Felt where E: ExecutionEncoder, { @@ -503,10 +532,10 @@ impl RawExecutionV1 { if query_only { QUERY_VERSION_ONE } else { - FieldElement::ONE + Felt::ONE }, // version address, - FieldElement::ZERO, // entry_point_selector + Felt::ZERO, // entry_point_selector compute_hash_on_elements(&encoder.encode_calls(&self.calls)), self.max_fee, chain_id, @@ -518,11 +547,11 @@ impl RawExecutionV1 { &self.calls } - pub fn nonce(&self) -> FieldElement { + pub fn nonce(&self) -> Felt { self.nonce } - pub fn max_fee(&self) -> FieldElement { + pub fn max_fee(&self) -> Felt { self.max_fee } } @@ -530,11 +559,11 @@ impl RawExecutionV1 { impl RawExecutionV3 { pub fn transaction_hash( &self, - chain_id: FieldElement, - address: FieldElement, + chain_id: Felt, + address: Felt, query_only: bool, encoder: E, - ) -> FieldElement + ) -> Felt where E: ExecutionEncoder, { @@ -544,7 +573,7 @@ impl RawExecutionV3 { hasher.update(if query_only { QUERY_VERSION_THREE } else { - FieldElement::THREE + Felt::THREE }); hasher.update(address); @@ -552,7 +581,7 @@ impl RawExecutionV3 { let mut fee_hasher = PoseidonHasher::new(); // Tip: fee market has not been been activated yet so it's hard-coded to be 0 - fee_hasher.update(FieldElement::ZERO); + fee_hasher.update(Felt::ZERO); let mut resource_buffer = [ 0, 0, b'L', b'1', b'_', b'G', b'A', b'S', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -560,14 +589,14 @@ impl RawExecutionV3 { ]; resource_buffer[8..(8 + 8)].copy_from_slice(&self.gas.to_be_bytes()); resource_buffer[(8 + 8)..].copy_from_slice(&self.gas_price.to_be_bytes()); - fee_hasher.update(FieldElement::from_bytes_be(&resource_buffer).unwrap()); + fee_hasher.update(Felt::from_bytes_be(&resource_buffer)); // L2 resources are hard-coded to 0 let resource_buffer = [ 0, 0, b'L', b'2', b'_', b'G', b'A', b'S', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; - fee_hasher.update(FieldElement::from_bytes_be(&resource_buffer).unwrap()); + fee_hasher.update(Felt::from_bytes_be(&resource_buffer)); fee_hasher.finalize() }); @@ -579,7 +608,7 @@ impl RawExecutionV3 { hasher.update(self.nonce); // Hard-coded L1 DA mode for nonce and fee - hasher.update(FieldElement::ZERO); + hasher.update(Felt::ZERO); // Hard-coded empty `account_deployment_data` hasher.update(PoseidonHasher::new().finalize()); @@ -602,7 +631,7 @@ impl RawExecutionV3 { &self.calls } - pub fn nonce(&self) -> FieldElement { + pub fn nonce(&self) -> Felt { self.nonce } @@ -621,7 +650,7 @@ where { /// Locally calculates the hash of the transaction to be sent from this execution given the /// parameters. - pub fn transaction_hash(&self, query_only: bool) -> FieldElement { + pub fn transaction_hash(&self, query_only: bool) -> Felt { self.inner.transaction_hash( self.account.chain_id(), self.account.address(), @@ -637,7 +666,7 @@ where { /// Locally calculates the hash of the transaction to be sent from this execution given the /// parameters. - pub fn transaction_hash(&self, query_only: bool) -> FieldElement { + pub fn transaction_hash(&self, query_only: bool) -> Felt { self.inner.transaction_hash( self.account.chain_id(), self.account.address(), diff --git a/starknet-accounts/src/account/mod.rs b/starknet-accounts/src/account/mod.rs index 615f09ee..30e39730 100644 --- a/starknet-accounts/src/account/mod.rs +++ b/starknet-accounts/src/account/mod.rs @@ -4,7 +4,7 @@ use async_trait::async_trait; use auto_impl::auto_impl; use starknet_core::types::{ contract::{legacy::LegacyContractClass, CompressProgramError, ComputeClassHashError}, - BlockId, BlockTag, FieldElement, FlattenedSierraClass, + BlockId, BlockTag, Felt, FlattenedSierraClass, }; use starknet_providers::{Provider, ProviderError}; use std::{error::Error, sync::Arc}; @@ -21,39 +21,39 @@ mod execution; pub trait Account: ExecutionEncoder + Sized { type SignError: Error + Send + Sync; - fn address(&self) -> FieldElement; + fn address(&self) -> Felt; - fn chain_id(&self) -> FieldElement; + fn chain_id(&self) -> Felt; async fn sign_execution_v1( &self, execution: &RawExecutionV1, query_only: bool, - ) -> Result, Self::SignError>; + ) -> Result, Self::SignError>; async fn sign_execution_v3( &self, execution: &RawExecutionV3, query_only: bool, - ) -> Result, Self::SignError>; + ) -> Result, Self::SignError>; async fn sign_declaration_v2( &self, declaration: &RawDeclarationV2, query_only: bool, - ) -> Result, Self::SignError>; + ) -> Result, Self::SignError>; async fn sign_declaration_v3( &self, declaration: &RawDeclarationV3, query_only: bool, - ) -> Result, Self::SignError>; + ) -> Result, Self::SignError>; async fn sign_legacy_declaration( &self, legacy_declaration: &RawLegacyDeclaration, query_only: bool, - ) -> Result, Self::SignError>; + ) -> Result, Self::SignError>; fn execute_v1(&self, calls: Vec) -> ExecutionV1 { ExecutionV1::new(calls, self) @@ -71,7 +71,7 @@ pub trait Account: ExecutionEncoder + Sized { fn declare_v2( &self, contract_class: Arc, - compiled_class_hash: FieldElement, + compiled_class_hash: Felt, ) -> DeclarationV2 { DeclarationV2::new(contract_class, compiled_class_hash, self) } @@ -79,7 +79,7 @@ pub trait Account: ExecutionEncoder + Sized { fn declare_v3( &self, contract_class: Arc, - compiled_class_hash: FieldElement, + compiled_class_hash: Felt, ) -> DeclarationV3 { DeclarationV3::new(contract_class, compiled_class_hash, self) } @@ -88,7 +88,7 @@ pub trait Account: ExecutionEncoder + Sized { fn declare( &self, contract_class: Arc, - compiled_class_hash: FieldElement, + compiled_class_hash: Felt, ) -> DeclarationV2 { self.declare_v2(contract_class, compiled_class_hash) } @@ -100,7 +100,7 @@ pub trait Account: ExecutionEncoder + Sized { #[auto_impl(&, Box, Arc)] pub trait ExecutionEncoder { - fn encode_calls(&self, calls: &[Call]) -> Vec; + fn encode_calls(&self, calls: &[Call]) -> Vec; } /// An [Account] implementation that also comes with a [Provider]. Functionalities that require a @@ -118,7 +118,7 @@ pub trait ConnectedAccount: Account { BlockId::Tag(BlockTag::Latest) } - async fn get_nonce(&self) -> Result { + async fn get_nonce(&self) -> Result { self.provider() .get_nonce(self.block_id(), self.address()) .await @@ -135,8 +135,8 @@ pub trait ConnectedAccount: Account { pub struct ExecutionV1<'a, A> { account: &'a A, calls: Vec, - nonce: Option, - max_fee: Option, + nonce: Option, + max_fee: Option, fee_estimate_multiplier: f64, } @@ -151,7 +151,7 @@ pub struct ExecutionV1<'a, A> { pub struct ExecutionV3<'a, A> { account: &'a A, calls: Vec, - nonce: Option, + nonce: Option, gas: Option, gas_price: Option, gas_estimate_multiplier: f64, @@ -168,9 +168,9 @@ pub struct ExecutionV3<'a, A> { pub struct DeclarationV2<'a, A> { account: &'a A, contract_class: Arc, - compiled_class_hash: FieldElement, - nonce: Option, - max_fee: Option, + compiled_class_hash: Felt, + nonce: Option, + max_fee: Option, fee_estimate_multiplier: f64, } @@ -185,8 +185,8 @@ pub struct DeclarationV2<'a, A> { pub struct DeclarationV3<'a, A> { account: &'a A, contract_class: Arc, - compiled_class_hash: FieldElement, - nonce: Option, + compiled_class_hash: Felt, + nonce: Option, gas: Option, gas_price: Option, gas_estimate_multiplier: f64, @@ -199,8 +199,8 @@ pub struct DeclarationV3<'a, A> { pub struct LegacyDeclaration<'a, A> { account: &'a A, contract_class: Arc, - nonce: Option, - max_fee: Option, + nonce: Option, + max_fee: Option, fee_estimate_multiplier: f64, } @@ -208,15 +208,15 @@ pub struct LegacyDeclaration<'a, A> { #[derive(Debug)] pub struct RawExecutionV1 { calls: Vec, - nonce: FieldElement, - max_fee: FieldElement, + nonce: Felt, + max_fee: Felt, } /// [ExecutionV3] but with `nonce`, `gas` and `gas_price` already determined. #[derive(Debug)] pub struct RawExecutionV3 { calls: Vec, - nonce: FieldElement, + nonce: Felt, gas: u64, gas_price: u128, } @@ -225,17 +225,17 @@ pub struct RawExecutionV3 { #[derive(Debug)] pub struct RawDeclarationV2 { contract_class: Arc, - compiled_class_hash: FieldElement, - nonce: FieldElement, - max_fee: FieldElement, + compiled_class_hash: Felt, + nonce: Felt, + max_fee: Felt, } /// [DeclarationV3] but with `nonce`, `gas` and `gas_price` already determined. #[derive(Debug)] pub struct RawDeclarationV3 { contract_class: Arc, - compiled_class_hash: FieldElement, - nonce: FieldElement, + compiled_class_hash: Felt, + nonce: Felt, gas: u64, gas_price: u128, } @@ -244,8 +244,8 @@ pub struct RawDeclarationV3 { #[derive(Debug)] pub struct RawLegacyDeclaration { contract_class: Arc, - nonce: FieldElement, - max_fee: FieldElement, + nonce: Felt, + max_fee: Felt, } /// [RawExecutionV1] but with an account associated. @@ -305,11 +305,11 @@ where { type SignError = A::SignError; - fn address(&self) -> FieldElement { + fn address(&self) -> Felt { (*self).address() } - fn chain_id(&self) -> FieldElement { + fn chain_id(&self) -> Felt { (*self).chain_id() } @@ -317,7 +317,7 @@ where &self, execution: &RawExecutionV1, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { (*self).sign_execution_v1(execution, query_only).await } @@ -325,7 +325,7 @@ where &self, execution: &RawExecutionV3, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { (*self).sign_execution_v3(execution, query_only).await } @@ -333,7 +333,7 @@ where &self, declaration: &RawDeclarationV2, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { (*self).sign_declaration_v2(declaration, query_only).await } @@ -341,7 +341,7 @@ where &self, declaration: &RawDeclarationV3, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { (*self).sign_declaration_v3(declaration, query_only).await } @@ -349,7 +349,7 @@ where &self, legacy_declaration: &RawLegacyDeclaration, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { (*self) .sign_legacy_declaration(legacy_declaration, query_only) .await @@ -364,11 +364,11 @@ where { type SignError = A::SignError; - fn address(&self) -> FieldElement { + fn address(&self) -> Felt { self.as_ref().address() } - fn chain_id(&self) -> FieldElement { + fn chain_id(&self) -> Felt { self.as_ref().chain_id() } @@ -376,7 +376,7 @@ where &self, execution: &RawExecutionV1, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { self.as_ref().sign_execution_v1(execution, query_only).await } @@ -384,7 +384,7 @@ where &self, execution: &RawExecutionV3, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { self.as_ref().sign_execution_v3(execution, query_only).await } @@ -392,7 +392,7 @@ where &self, declaration: &RawDeclarationV2, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { self.as_ref() .sign_declaration_v2(declaration, query_only) .await @@ -402,7 +402,7 @@ where &self, declaration: &RawDeclarationV3, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { self.as_ref() .sign_declaration_v3(declaration, query_only) .await @@ -412,7 +412,7 @@ where &self, legacy_declaration: &RawLegacyDeclaration, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { self.as_ref() .sign_legacy_declaration(legacy_declaration, query_only) .await @@ -427,11 +427,11 @@ where { type SignError = A::SignError; - fn address(&self) -> FieldElement { + fn address(&self) -> Felt { self.as_ref().address() } - fn chain_id(&self) -> FieldElement { + fn chain_id(&self) -> Felt { self.as_ref().chain_id() } @@ -439,7 +439,7 @@ where &self, execution: &RawExecutionV1, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { self.as_ref().sign_execution_v1(execution, query_only).await } @@ -447,7 +447,7 @@ where &self, execution: &RawExecutionV3, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { self.as_ref().sign_execution_v3(execution, query_only).await } @@ -455,7 +455,7 @@ where &self, declaration: &RawDeclarationV2, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { self.as_ref() .sign_declaration_v2(declaration, query_only) .await @@ -465,7 +465,7 @@ where &self, declaration: &RawDeclarationV3, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { self.as_ref() .sign_declaration_v3(declaration, query_only) .await @@ -475,7 +475,7 @@ where &self, legacy_declaration: &RawLegacyDeclaration, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { self.as_ref() .sign_legacy_declaration(legacy_declaration, query_only) .await @@ -498,7 +498,7 @@ where (*self).block_id() } - async fn get_nonce(&self) -> Result { + async fn get_nonce(&self) -> Result { (*self).get_nonce().await } } @@ -519,7 +519,7 @@ where self.as_ref().block_id() } - async fn get_nonce(&self) -> Result { + async fn get_nonce(&self) -> Result { self.as_ref().get_nonce().await } } @@ -540,7 +540,7 @@ where self.as_ref().block_id() } - async fn get_nonce(&self) -> Result { + async fn get_nonce(&self) -> Result { self.as_ref().get_nonce().await } } diff --git a/starknet-accounts/src/call.rs b/starknet-accounts/src/call.rs index 9afd5112..6d86ed53 100644 --- a/starknet-accounts/src/call.rs +++ b/starknet-accounts/src/call.rs @@ -1,8 +1,8 @@ -use starknet_core::types::FieldElement; +use starknet_core::types::Felt; #[derive(Debug, Clone)] pub struct Call { - pub to: FieldElement, - pub selector: FieldElement, - pub calldata: Vec, + pub to: Felt, + pub selector: Felt, + pub calldata: Vec, } diff --git a/starknet-accounts/src/factory/argent.rs b/starknet-accounts/src/factory/argent.rs index 86e1870a..4677ef74 100644 --- a/starknet-accounts/src/factory/argent.rs +++ b/starknet-accounts/src/factory/argent.rs @@ -4,15 +4,15 @@ use crate::{ }; use async_trait::async_trait; -use starknet_core::types::{BlockId, BlockTag, FieldElement}; +use starknet_core::types::{BlockId, BlockTag, Felt}; use starknet_providers::Provider; use starknet_signers::Signer; pub struct ArgentAccountFactory { - class_hash: FieldElement, - chain_id: FieldElement, - owner_public_key: FieldElement, - guardian_public_key: FieldElement, + class_hash: Felt, + chain_id: Felt, + owner_public_key: Felt, + guardian_public_key: Felt, signer: S, provider: P, block_id: BlockId, @@ -23,9 +23,9 @@ where S: Signer, { pub async fn new( - class_hash: FieldElement, - chain_id: FieldElement, - guardian_public_key: FieldElement, + class_hash: Felt, + chain_id: Felt, + guardian_public_key: Felt, signer: S, provider: P, ) -> Result { @@ -57,15 +57,15 @@ where type Provider = P; type SignError = S::SignError; - fn class_hash(&self) -> FieldElement { + fn class_hash(&self) -> Felt { self.class_hash } - fn calldata(&self) -> Vec { + fn calldata(&self) -> Vec { vec![self.owner_public_key, self.guardian_public_key] } - fn chain_id(&self) -> FieldElement { + fn chain_id(&self) -> Felt { self.chain_id } @@ -80,7 +80,7 @@ where async fn sign_deployment_v1( &self, deployment: &RawAccountDeploymentV1, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { let tx_hash = PreparedAccountDeploymentV1::from_raw(deployment.clone(), self).transaction_hash(); let signature = self.signer.sign_hash(&tx_hash).await?; @@ -91,7 +91,7 @@ where async fn sign_deployment_v3( &self, deployment: &RawAccountDeploymentV3, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { let tx_hash = PreparedAccountDeploymentV3::from_raw(deployment.clone(), self).transaction_hash(); let signature = self.signer.sign_hash(&tx_hash).await?; diff --git a/starknet-accounts/src/factory/mod.rs b/starknet-accounts/src/factory/mod.rs index 33488367..8f292db4 100644 --- a/starknet-accounts/src/factory/mod.rs +++ b/starknet-accounts/src/factory/mod.rs @@ -7,8 +7,8 @@ use starknet_core::{ BlockId, BlockTag, BroadcastedDeployAccountTransaction, BroadcastedDeployAccountTransactionV1, BroadcastedDeployAccountTransactionV3, BroadcastedTransaction, DataAvailabilityMode, DeployAccountTransactionResult, FeeEstimate, - FieldElement, ResourceBounds, ResourceBoundsMapping, SimulatedTransaction, SimulationFlag, - StarknetError, + Felt, NonZeroFelt, ResourceBounds, ResourceBoundsMapping, SimulatedTransaction, + SimulationFlag, StarknetError, }, }; use starknet_crypto::PoseidonHasher; @@ -19,27 +19,27 @@ pub mod argent; pub mod open_zeppelin; /// Cairo string for "deploy_account" -const PREFIX_DEPLOY_ACCOUNT: FieldElement = FieldElement::from_mont([ - 3350261884043292318, - 18443211694809419988, - 18446744073709551615, +const PREFIX_DEPLOY_ACCOUNT: Felt = Felt::from_raw([ 461298303000467581, + 18446744073709551615, + 18443211694809419988, + 3350261884043292318, ]); /// Cairo string for "STARKNET_CONTRACT_ADDRESS" -const PREFIX_CONTRACT_ADDRESS: FieldElement = FieldElement::from_mont([ - 3829237882463328880, - 17289941567720117366, - 8635008616843941496, +const PREFIX_CONTRACT_ADDRESS: Felt = Felt::from_raw([ 533439743893157637, + 8635008616843941496, + 17289941567720117366, + 3829237882463328880, ]); // 2 ** 251 - 256 -const ADDR_BOUND: FieldElement = FieldElement::from_mont([ - 18446743986131443745, - 160989183, - 18446744073709255680, +const ADDR_BOUND: NonZeroFelt = NonZeroFelt::from_raw([ 576459263475590224, + 18446744073709255680, + 160989183, + 18446743986131443745, ]); /// This trait enables deploying account contracts using the `DeployAccount` transaction type. @@ -49,11 +49,11 @@ pub trait AccountFactory: Sized { type Provider: Provider + Sync; type SignError: Error + Send + Sync; - fn class_hash(&self) -> FieldElement; + fn class_hash(&self) -> Felt; - fn calldata(&self) -> Vec; + fn calldata(&self) -> Vec; - fn chain_id(&self) -> FieldElement; + fn chain_id(&self) -> Felt; fn provider(&self) -> &Self::Provider; @@ -65,23 +65,23 @@ pub trait AccountFactory: Sized { async fn sign_deployment_v1( &self, deployment: &RawAccountDeploymentV1, - ) -> Result, Self::SignError>; + ) -> Result, Self::SignError>; async fn sign_deployment_v3( &self, deployment: &RawAccountDeploymentV3, - ) -> Result, Self::SignError>; + ) -> Result, Self::SignError>; - fn deploy_v1(&self, salt: FieldElement) -> AccountDeploymentV1 { + fn deploy_v1(&self, salt: Felt) -> AccountDeploymentV1 { AccountDeploymentV1::new(salt, self) } - fn deploy_v3(&self, salt: FieldElement) -> AccountDeploymentV3 { + fn deploy_v3(&self, salt: Felt) -> AccountDeploymentV3 { AccountDeploymentV3::new(salt, self) } #[deprecated = "use version specific variants (`deploy_v1` & `deploy_v3`) instead"] - fn deploy(&self, salt: FieldElement) -> AccountDeploymentV1 { + fn deploy(&self, salt: Felt) -> AccountDeploymentV1 { self.deploy_v1(salt) } } @@ -95,11 +95,11 @@ pub trait AccountFactory: Sized { #[derive(Debug)] pub struct AccountDeploymentV1<'f, F> { factory: &'f F, - salt: FieldElement, + salt: Felt, // We need to allow setting nonce here as `DeployAccount` transactions may have non-zero nonces /// after failed transactions can be included in blocks. - nonce: Option, - max_fee: Option, + nonce: Option, + max_fee: Option, fee_estimate_multiplier: f64, } @@ -113,10 +113,10 @@ pub struct AccountDeploymentV1<'f, F> { #[derive(Debug)] pub struct AccountDeploymentV3<'f, F> { factory: &'f F, - salt: FieldElement, + salt: Felt, // We need to allow setting nonce here as `DeployAccount` transactions may have non-zero nonces /// after failed transactions can be included in blocks. - nonce: Option, + nonce: Option, gas: Option, gas_price: Option, gas_estimate_multiplier: f64, @@ -126,16 +126,16 @@ pub struct AccountDeploymentV3<'f, F> { /// [AccountDeploymentV1] but with `nonce` and `max_fee` already determined. #[derive(Debug, Clone)] pub struct RawAccountDeploymentV1 { - salt: FieldElement, - nonce: FieldElement, - max_fee: FieldElement, + salt: Felt, + nonce: Felt, + max_fee: Felt, } /// [AccountDeploymentV3] but with `nonce`, `gas` and `gas_price` already determined. #[derive(Debug, Clone)] pub struct RawAccountDeploymentV3 { - salt: FieldElement, - nonce: FieldElement, + salt: Felt, + nonce: Felt, gas: u64, gas_price: u128, } @@ -165,7 +165,7 @@ pub enum AccountFactoryError { } impl<'f, F> AccountDeploymentV1<'f, F> { - pub fn new(salt: FieldElement, factory: &'f F) -> Self { + pub fn new(salt: Felt, factory: &'f F) -> Self { Self { factory, salt, @@ -175,14 +175,14 @@ impl<'f, F> AccountDeploymentV1<'f, F> { } } - pub fn nonce(self, nonce: FieldElement) -> Self { + pub fn nonce(self, nonce: Felt) -> Self { Self { nonce: Some(nonce), ..self } } - pub fn max_fee(self, max_fee: FieldElement) -> Self { + pub fn max_fee(self, max_fee: Felt) -> Self { Self { max_fee: Some(max_fee), ..self @@ -215,7 +215,7 @@ impl<'f, F> AccountDeploymentV1<'f, F> { } impl<'f, F> AccountDeploymentV3<'f, F> { - pub fn new(salt: FieldElement, factory: &'f F) -> Self { + pub fn new(salt: Felt, factory: &'f F) -> Self { Self { factory, salt, @@ -227,7 +227,7 @@ impl<'f, F> AccountDeploymentV3<'f, F> { } } - pub fn nonce(self, nonce: FieldElement) -> Self { + pub fn nonce(self, nonce: Felt) -> Self { Self { nonce: Some(nonce), ..self @@ -287,7 +287,7 @@ where F: AccountFactory + Sync, { /// Locally calculates the target deployment address. - pub fn address(&self) -> FieldElement { + pub fn address(&self) -> Felt { calculate_contract_address( self.salt, self.factory.class_hash(), @@ -295,7 +295,7 @@ where ) } - pub async fn fetch_nonce(&self) -> Result { + pub async fn fetch_nonce(&self) -> Result { match self .factory .provider() @@ -303,9 +303,7 @@ where .await { Ok(nonce) => Ok(nonce), - Err(ProviderError::StarknetError(StarknetError::ContractNotFound)) => { - Ok(FieldElement::ZERO) - } + Err(ProviderError::StarknetError(StarknetError::ContractNotFound)) => Ok(Felt::ZERO), Err(err) => Err(err), } } @@ -363,11 +361,23 @@ where let max_fee = match self.max_fee { Some(value) => value, None => { + // TODO: remove this when a proper u64 conversion is implemented for `Felt` + // Obtain the fee estimate let fee_estimate = self.estimate_fee_with_nonce(nonce).await?; - ((((TryInto::::try_into(fee_estimate.overall_fee) - .map_err(|_| AccountFactoryError::FeeOutOfRange)?) as f64) - * self.fee_estimate_multiplier) as u64) - .into() + // Convert the overall fee to little-endian bytes + let overall_fee_bytes = fee_estimate.overall_fee.to_bytes_le(); + + // Check if the remaining bytes after the first 8 are all zeros + if overall_fee_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountFactoryError::FeeOutOfRange); + } + + // Convert the first 8 bytes to u64 + let overall_fee_u64 = + u64::from_le_bytes(overall_fee_bytes[..8].try_into().unwrap()); + + // Perform necessary operations on overall_fee_u64 and convert to f64 then to u64 + (((overall_fee_u64 as f64) * self.fee_estimate_multiplier) as u64).into() } }; @@ -383,14 +393,14 @@ where async fn estimate_fee_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, ) -> Result> { let prepared = PreparedAccountDeploymentV1 { factory: self.factory, inner: RawAccountDeploymentV1 { salt: self.salt, nonce, - max_fee: FieldElement::ZERO, + max_fee: Felt::ZERO, }, }; let deploy = prepared @@ -413,7 +423,7 @@ where async fn simulate_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, skip_validate: bool, skip_fee_charge: bool, ) -> Result> { @@ -458,7 +468,7 @@ where F: AccountFactory + Sync, { /// Locally calculates the target deployment address. - pub fn address(&self) -> FieldElement { + pub fn address(&self) -> Felt { calculate_contract_address( self.salt, self.factory.class_hash(), @@ -466,7 +476,7 @@ where ) } - pub async fn fetch_nonce(&self) -> Result { + pub async fn fetch_nonce(&self) -> Result { match self .factory .provider() @@ -474,9 +484,7 @@ where .await { Ok(nonce) => Ok(nonce), - Err(ProviderError::StarknetError(StarknetError::ContractNotFound)) => { - Ok(FieldElement::ZERO) - } + Err(ProviderError::StarknetError(StarknetError::ContractNotFound)) => Ok(Felt::ZERO), Err(err) => Err(err), } } @@ -548,10 +556,15 @@ where .l1_gas_price() .price_in_fri; - let gas_price = (((TryInto::::try_into(block_l1_gas_price) - .map_err(|_| AccountFactoryError::FeeOutOfRange)?) - as f64) - * self.gas_price_estimate_multiplier) as u128; + let block_l1_gas_price_bytes = block_l1_gas_price.to_bytes_le(); + if block_l1_gas_price_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountFactoryError::FeeOutOfRange); + } + let block_l1_gas_price = + u64::from_le_bytes(block_l1_gas_price_bytes[..8].try_into().unwrap()); + + let gas_price = + ((block_l1_gas_price as f64) * self.gas_price_estimate_multiplier) as u128; (gas, gas_price) } @@ -562,12 +575,21 @@ where let gas = match self.gas { Some(gas) => gas, None => { - (((TryInto::::try_into( - (fee_estimate.overall_fee + fee_estimate.gas_price - FieldElement::ONE) - .floor_div(fee_estimate.gas_price), - ) - .map_err(|_| AccountFactoryError::FeeOutOfRange)?) - as f64) + let overall_fee_bytes = fee_estimate.overall_fee.to_bytes_le(); + if overall_fee_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountFactoryError::FeeOutOfRange); + } + let overall_fee = + u64::from_le_bytes(overall_fee_bytes[..8].try_into().unwrap()); + + let gas_price_bytes = fee_estimate.gas_price.to_bytes_le(); + if gas_price_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountFactoryError::FeeOutOfRange); + } + let gas_price = + u64::from_le_bytes(gas_price_bytes[..8].try_into().unwrap()); + + ((((overall_fee + gas_price - 1) / gas_price) as f64) * self.gas_estimate_multiplier) as u64 } }; @@ -575,10 +597,14 @@ where let gas_price = match self.gas_price { Some(gas_price) => gas_price, None => { - (((TryInto::::try_into(fee_estimate.gas_price) - .map_err(|_| AccountFactoryError::FeeOutOfRange)?) - as f64) - * self.gas_price_estimate_multiplier) as u128 + let gas_price_bytes = fee_estimate.gas_price.to_bytes_le(); + if gas_price_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(AccountFactoryError::FeeOutOfRange); + } + let gas_price = + u64::from_le_bytes(gas_price_bytes[..8].try_into().unwrap()); + + ((gas_price as f64) * self.gas_price_estimate_multiplier) as u128 } }; @@ -599,7 +625,7 @@ where async fn estimate_fee_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, ) -> Result> { let prepared = PreparedAccountDeploymentV3 { factory: self.factory, @@ -630,7 +656,7 @@ where async fn simulate_with_nonce( &self, - nonce: FieldElement, + nonce: Felt, skip_validate: bool, skip_fee_charge: bool, ) -> Result> { @@ -672,25 +698,25 @@ where } impl RawAccountDeploymentV1 { - pub fn salt(&self) -> FieldElement { + pub fn salt(&self) -> Felt { self.salt } - pub fn nonce(&self) -> FieldElement { + pub fn nonce(&self) -> Felt { self.nonce } - pub fn max_fee(&self) -> FieldElement { + pub fn max_fee(&self) -> Felt { self.max_fee } } impl RawAccountDeploymentV3 { - pub fn salt(&self) -> FieldElement { + pub fn salt(&self) -> Felt { self.salt } - pub fn nonce(&self) -> FieldElement { + pub fn nonce(&self) -> Felt { self.nonce } @@ -726,7 +752,7 @@ where F: AccountFactory, { /// Locally calculates the target deployment address. - pub fn address(&self) -> FieldElement { + pub fn address(&self) -> Felt { calculate_contract_address( self.inner.salt, self.factory.class_hash(), @@ -734,15 +760,15 @@ where ) } - pub fn transaction_hash(&self) -> FieldElement { + pub fn transaction_hash(&self) -> Felt { let mut calldata_to_hash = vec![self.factory.class_hash(), self.inner.salt]; calldata_to_hash.append(&mut self.factory.calldata()); compute_hash_on_elements(&[ PREFIX_DEPLOY_ACCOUNT, - FieldElement::ONE, // version + Felt::ONE, // version self.address(), - FieldElement::ZERO, // entry_point_selector + Felt::ZERO, // entry_point_selector compute_hash_on_elements(&calldata_to_hash), self.inner.max_fee, self.factory.chain_id(), @@ -787,7 +813,7 @@ where F: AccountFactory, { /// Locally calculates the target deployment address. - pub fn address(&self) -> FieldElement { + pub fn address(&self) -> Felt { calculate_contract_address( self.inner.salt, self.factory.class_hash(), @@ -795,18 +821,18 @@ where ) } - pub fn transaction_hash(&self) -> FieldElement { + pub fn transaction_hash(&self) -> Felt { let mut hasher = PoseidonHasher::new(); hasher.update(PREFIX_DEPLOY_ACCOUNT); - hasher.update(FieldElement::THREE); + hasher.update(Felt::THREE); hasher.update(self.address()); hasher.update({ let mut fee_hasher = PoseidonHasher::new(); // Tip: fee market has not been been activated yet so it's hard-coded to be 0 - fee_hasher.update(FieldElement::ZERO); + fee_hasher.update(Felt::ZERO); let mut resource_buffer = [ 0, 0, b'L', b'1', b'_', b'G', b'A', b'S', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -814,14 +840,14 @@ where ]; resource_buffer[8..(8 + 8)].copy_from_slice(&self.inner.gas.to_be_bytes()); resource_buffer[(8 + 8)..].copy_from_slice(&self.inner.gas_price.to_be_bytes()); - fee_hasher.update(FieldElement::from_bytes_be(&resource_buffer).unwrap()); + fee_hasher.update(Felt::from_bytes_be(&resource_buffer)); // L2 resources are hard-coded to 0 let resource_buffer = [ 0, 0, b'L', b'2', b'_', b'G', b'A', b'S', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; - fee_hasher.update(FieldElement::from_bytes_be(&resource_buffer).unwrap()); + fee_hasher.update(Felt::from_bytes_be(&resource_buffer)); fee_hasher.finalize() }); @@ -833,7 +859,7 @@ where hasher.update(self.inner.nonce); // Hard-coded L1 DA mode for nonce and fee - hasher.update(FieldElement::ZERO); + hasher.update(Felt::ZERO); hasher.update({ let mut calldata_hasher = PoseidonHasher::new(); @@ -900,16 +926,14 @@ where }) } } -fn calculate_contract_address( - salt: FieldElement, - class_hash: FieldElement, - constructor_calldata: &[FieldElement], -) -> FieldElement { + +fn calculate_contract_address(salt: Felt, class_hash: Felt, constructor_calldata: &[Felt]) -> Felt { compute_hash_on_elements(&[ PREFIX_CONTRACT_ADDRESS, - FieldElement::ZERO, + Felt::ZERO, salt, class_hash, compute_hash_on_elements(constructor_calldata), - ]) % ADDR_BOUND + ]) + .mod_floor(&ADDR_BOUND) } diff --git a/starknet-accounts/src/factory/open_zeppelin.rs b/starknet-accounts/src/factory/open_zeppelin.rs index 343eaf90..0b1c78ad 100644 --- a/starknet-accounts/src/factory/open_zeppelin.rs +++ b/starknet-accounts/src/factory/open_zeppelin.rs @@ -4,14 +4,14 @@ use crate::{ }; use async_trait::async_trait; -use starknet_core::types::{BlockId, BlockTag, FieldElement}; +use starknet_core::types::{BlockId, BlockTag, Felt}; use starknet_providers::Provider; use starknet_signers::Signer; pub struct OpenZeppelinAccountFactory { - class_hash: FieldElement, - chain_id: FieldElement, - public_key: FieldElement, + class_hash: Felt, + chain_id: Felt, + public_key: Felt, signer: S, provider: P, block_id: BlockId, @@ -22,8 +22,8 @@ where S: Signer, { pub async fn new( - class_hash: FieldElement, - chain_id: FieldElement, + class_hash: Felt, + chain_id: Felt, signer: S, provider: P, ) -> Result { @@ -54,15 +54,15 @@ where type Provider = P; type SignError = S::SignError; - fn class_hash(&self) -> FieldElement { + fn class_hash(&self) -> Felt { self.class_hash } - fn calldata(&self) -> Vec { + fn calldata(&self) -> Vec { vec![self.public_key] } - fn chain_id(&self) -> FieldElement { + fn chain_id(&self) -> Felt { self.chain_id } @@ -77,7 +77,7 @@ where async fn sign_deployment_v1( &self, deployment: &RawAccountDeploymentV1, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { let tx_hash = PreparedAccountDeploymentV1::from_raw(deployment.clone(), self).transaction_hash(); let signature = self.signer.sign_hash(&tx_hash).await?; @@ -88,7 +88,7 @@ where async fn sign_deployment_v3( &self, deployment: &RawAccountDeploymentV3, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { let tx_hash = PreparedAccountDeploymentV3::from_raw(deployment.clone(), self).transaction_hash(); let signature = self.signer.sign_hash(&tx_hash).await?; diff --git a/starknet-accounts/src/single_owner.rs b/starknet-accounts/src/single_owner.rs index 91d8acb2..9aa7a5b7 100644 --- a/starknet-accounts/src/single_owner.rs +++ b/starknet-accounts/src/single_owner.rs @@ -4,7 +4,7 @@ use crate::{ }; use async_trait::async_trait; -use starknet_core::types::{contract::ComputeClassHashError, BlockId, BlockTag, FieldElement}; +use starknet_core::types::{contract::ComputeClassHashError, BlockId, BlockTag, Felt}; use starknet_providers::Provider; use starknet_signers::Signer; @@ -16,8 +16,8 @@ where { provider: P, signer: S, - address: FieldElement, - chain_id: FieldElement, + address: Felt, + chain_id: Felt, block_id: BlockId, encoding: ExecutionEncoding, } @@ -57,8 +57,8 @@ where pub fn new( provider: P, signer: S, - address: FieldElement, - chain_id: FieldElement, + address: Felt, + chain_id: Felt, encoding: ExecutionEncoding, ) -> Self { Self { @@ -86,11 +86,11 @@ where { type SignError = SignError; - fn address(&self) -> FieldElement { + fn address(&self) -> Felt { self.address } - fn chain_id(&self) -> FieldElement { + fn chain_id(&self) -> Felt { self.chain_id } @@ -98,7 +98,7 @@ where &self, execution: &RawExecutionV1, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { let tx_hash = execution.transaction_hash(self.chain_id, self.address, query_only, self); let signature = self .signer @@ -113,7 +113,7 @@ where &self, execution: &RawExecutionV3, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { let tx_hash = execution.transaction_hash(self.chain_id, self.address, query_only, self); let signature = self .signer @@ -128,7 +128,7 @@ where &self, declaration: &RawDeclarationV2, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { let tx_hash = declaration.transaction_hash(self.chain_id, self.address, query_only); let signature = self .signer @@ -143,7 +143,7 @@ where &self, declaration: &RawDeclarationV3, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { let tx_hash = declaration.transaction_hash(self.chain_id, self.address, query_only); let signature = self .signer @@ -158,7 +158,7 @@ where &self, legacy_declaration: &RawLegacyDeclaration, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { let tx_hash = legacy_declaration .transaction_hash(self.chain_id, self.address, query_only) .map_err(SignError::ClassHash)?; @@ -177,12 +177,12 @@ where P: Provider + Send, S: Signer + Send, { - fn encode_calls(&self, calls: &[Call]) -> Vec { - let mut execute_calldata: Vec = vec![calls.len().into()]; + fn encode_calls(&self, calls: &[Call]) -> Vec { + let mut execute_calldata: Vec = vec![calls.len().into()]; match self.encoding { ExecutionEncoding::Legacy => { - let mut concated_calldata: Vec = vec![]; + let mut concated_calldata: Vec = vec![]; for call in calls.iter() { execute_calldata.push(call.to); // to execute_calldata.push(call.selector); // selector diff --git a/starknet-accounts/tests/single_owner_account.rs b/starknet-accounts/tests/single_owner_account.rs index fa5cbcee..c779c491 100644 --- a/starknet-accounts/tests/single_owner_account.rs +++ b/starknet-accounts/tests/single_owner_account.rs @@ -7,7 +7,7 @@ use starknet_core::{ legacy::{LegacyContractClass, RawLegacyAbiEntry, RawLegacyFunction}, SierraClass, }, - BlockId, BlockTag, FieldElement, StarknetError, + BlockId, BlockTag, Felt, StarknetError, }, utils::get_selector_from_name, }; @@ -19,11 +19,11 @@ use starknet_signers::{LocalWallet, SigningKey}; use std::sync::Arc; /// Cairo short string encoding for `SN_SEPOLIA`. -const CHAIN_ID: FieldElement = FieldElement::from_mont([ - 1555806712078248243, - 18446744073708869172, - 18446744073709551615, +const CHAIN_ID: Felt = Felt::from_raw([ 507980251676163170, + 18446744073709551615, + 18446744073708869172, + 1555806712078248243, ]); fn create_sequencer_client() -> SequencerGatewayProvider { @@ -191,32 +191,24 @@ async fn can_declare_cairo0_contract_with_jsonrpc() { async fn can_get_nonce_inner(provider: P, address: &str) { let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be(address).unwrap(); + let address = Felt::from_hex(address).unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); account.set_block_id(BlockId::Tag(BlockTag::Pending)); - assert_ne!(account.get_nonce().await.unwrap(), FieldElement::ZERO); + assert_ne!(account.get_nonce().await.unwrap(), Felt::ZERO); } async fn can_estimate_invoke_v1_fee_inner(provider: P, address: &str) { let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be(address).unwrap(); - let eth_token_address = FieldElement::from_hex_be( - "049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - ) - .unwrap(); + let address = Felt::from_hex(address).unwrap(); + let eth_token_address = + Felt::from_hex("049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7").unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); @@ -226,31 +218,22 @@ async fn can_estimate_invoke_v1_fee_inner(provider: P .execute_v1(vec![Call { to: eth_token_address, selector: get_selector_from_name("transfer").unwrap(), - calldata: vec![ - FieldElement::from_hex_be("0x1234").unwrap(), - FieldElement::ONE, - FieldElement::ZERO, - ], + calldata: vec![Felt::from_hex("0x1234").unwrap(), Felt::ONE, Felt::ZERO], }]) .estimate_fee() .await .unwrap(); - assert!(fee_estimate.overall_fee > FieldElement::ZERO); + assert!(fee_estimate.overall_fee > Felt::ZERO); } async fn can_estimate_invoke_v3_fee_inner(provider: P, address: &str) { let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be(address).unwrap(); - let eth_token_address = FieldElement::from_hex_be( - "049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - ) - .unwrap(); + let address = Felt::from_hex(address).unwrap(); + let eth_token_address = + Felt::from_hex("049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7").unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); @@ -260,17 +243,13 @@ async fn can_estimate_invoke_v3_fee_inner(provider: P .execute_v3(vec![Call { to: eth_token_address, selector: get_selector_from_name("transfer").unwrap(), - calldata: vec![ - FieldElement::from_hex_be("0x1234").unwrap(), - FieldElement::ONE, - FieldElement::ZERO, - ], + calldata: vec![Felt::from_hex("0x1234").unwrap(), Felt::ONE, Felt::ZERO], }]) .estimate_fee() .await .unwrap(); - assert!(fee_estimate.overall_fee > FieldElement::ZERO); + assert!(fee_estimate.overall_fee > Felt::ZERO); } async fn can_parse_fee_estimation_error_inner( @@ -278,16 +257,11 @@ async fn can_parse_fee_estimation_error_inner( address: &str, ) { let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be(address).unwrap(); - let eth_token_address = FieldElement::from_hex_be( - "049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - ) - .unwrap(); + let address = Felt::from_hex(address).unwrap(); + let eth_token_address = + Felt::from_hex("049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7").unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); @@ -299,8 +273,8 @@ async fn can_parse_fee_estimation_error_inner( selector: get_selector_from_name("transfer").unwrap(), calldata: vec![ address, - FieldElement::from_dec_str("1000000000000000000000").unwrap(), - FieldElement::ZERO, + Felt::from_dec_str("1000000000000000000000").unwrap(), + Felt::ZERO, ], }]) .estimate_fee() @@ -328,16 +302,11 @@ async fn can_execute_eth_transfer_invoke_v1_inner( // - poll the transaction hash until it's processed. let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be(address).unwrap(); - let eth_token_address = FieldElement::from_hex_be( - "049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - ) - .unwrap(); + let address = Felt::from_hex(address).unwrap(); + let eth_token_address = + Felt::from_hex("049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7").unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); @@ -347,18 +316,14 @@ async fn can_execute_eth_transfer_invoke_v1_inner( .execute_v1(vec![Call { to: eth_token_address, selector: get_selector_from_name("transfer").unwrap(), - calldata: vec![ - FieldElement::from_hex_be("0x1234").unwrap(), - FieldElement::ONE, - FieldElement::ZERO, - ], + calldata: vec![Felt::from_hex("0x1234").unwrap(), Felt::ONE, Felt::ZERO], }]) - .max_fee(FieldElement::from_dec_str("1000000000000000000").unwrap()) + .max_fee(Felt::from_dec_str("1000000000000000000").unwrap()) .send() .await .unwrap(); - assert!(result.transaction_hash > FieldElement::ZERO); + assert!(result.transaction_hash > Felt::ZERO); } async fn can_execute_eth_transfer_invoke_v3_inner( @@ -373,16 +338,11 @@ async fn can_execute_eth_transfer_invoke_v3_inner( // - poll the transaction hash until it's processed. let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be(address).unwrap(); - let eth_token_address = FieldElement::from_hex_be( - "049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - ) - .unwrap(); + let address = Felt::from_hex(address).unwrap(); + let eth_token_address = + Felt::from_hex("049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7").unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); @@ -392,11 +352,7 @@ async fn can_execute_eth_transfer_invoke_v3_inner( .execute_v3(vec![Call { to: eth_token_address, selector: get_selector_from_name("transfer").unwrap(), - calldata: vec![ - FieldElement::from_hex_be("0x1234").unwrap(), - FieldElement::ONE, - FieldElement::ZERO, - ], + calldata: vec![Felt::from_hex("0x1234").unwrap(), Felt::ONE, Felt::ZERO], }]) .gas(200000) .gas_price(500000000000000) @@ -404,7 +360,7 @@ async fn can_execute_eth_transfer_invoke_v3_inner( .await .unwrap(); - assert!(result.transaction_hash > FieldElement::ZERO); + assert!(result.transaction_hash > Felt::ZERO); } async fn can_execute_eth_transfer_invoke_v3_with_manual_gas_inner( @@ -416,16 +372,11 @@ async fn can_execute_eth_transfer_invoke_v3_with_manual_gas_inner FieldElement::ZERO); + assert!(result.transaction_hash > Felt::ZERO); } async fn can_declare_cairo1_contract_v2_inner( @@ -461,12 +412,9 @@ async fn can_declare_cairo1_contract_v2_inner( } let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be(address).unwrap(); + let address = Felt::from_hex(address).unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); account.set_block_id(BlockId::Tag(BlockTag::Pending)); @@ -494,16 +442,16 @@ async fn can_declare_cairo1_contract_v2_inner( let result = account .declare_v2( Arc::new(flattened_class), - FieldElement::from_hex_be(&hashes.compiled_class_hash).unwrap(), + Felt::from_hex(&hashes.compiled_class_hash).unwrap(), ) - .max_fee(FieldElement::from_dec_str("1000000000000000000").unwrap()) + .max_fee(Felt::from_dec_str("1000000000000000000").unwrap()) .send() .await .unwrap(); dbg!(&result); - assert!(result.transaction_hash > FieldElement::ZERO); + assert!(result.transaction_hash > Felt::ZERO); } async fn can_estimate_declare_v3_fee_inner(provider: P, address: &str) { @@ -513,12 +461,9 @@ async fn can_estimate_declare_v3_fee_inner(provider: } let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be(address).unwrap(); + let address = Felt::from_hex(address).unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); account.set_block_id(BlockId::Tag(BlockTag::Pending)); @@ -546,13 +491,13 @@ async fn can_estimate_declare_v3_fee_inner(provider: let result = account .declare_v3( Arc::new(flattened_class), - FieldElement::from_hex_be(&hashes.compiled_class_hash).unwrap(), + Felt::from_hex(&hashes.compiled_class_hash).unwrap(), ) .estimate_fee() .await .unwrap(); - assert!(result.overall_fee > FieldElement::ZERO); + assert!(result.overall_fee > Felt::ZERO); } async fn can_declare_cairo1_contract_v3_inner( @@ -567,12 +512,9 @@ async fn can_declare_cairo1_contract_v3_inner( } let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be(address).unwrap(); + let address = Felt::from_hex(address).unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); account.set_block_id(BlockId::Tag(BlockTag::Pending)); @@ -600,7 +542,7 @@ async fn can_declare_cairo1_contract_v3_inner( let result = account .declare_v3( Arc::new(flattened_class), - FieldElement::from_hex_be(&hashes.compiled_class_hash).unwrap(), + Felt::from_hex(&hashes.compiled_class_hash).unwrap(), ) .gas(200000) .gas_price(500000000000000) @@ -608,19 +550,16 @@ async fn can_declare_cairo1_contract_v3_inner( .await .unwrap(); - assert!(result.transaction_hash > FieldElement::ZERO); + assert!(result.transaction_hash > Felt::ZERO); } async fn can_declare_cairo0_contract_inner(provider: P, address: &str) { // This test case is not very useful, same as `can_execute_eth_transfer` above. let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be(address).unwrap(); + let address = Felt::from_hex(address).unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); account.set_block_id(BlockId::Tag(BlockTag::Pending)); @@ -647,10 +586,10 @@ async fn can_declare_cairo0_contract_inner(provider: let result = account .declare_legacy(Arc::new(contract_artifact)) - .max_fee(FieldElement::from_dec_str("1000000000000000000").unwrap()) + .max_fee(Felt::from_dec_str("1000000000000000000").unwrap()) .send() .await .unwrap(); - assert!(result.transaction_hash > FieldElement::ZERO); + assert!(result.transaction_hash > Felt::ZERO); } diff --git a/starknet-contract/src/factory.rs b/starknet-contract/src/factory.rs index a57b6e70..0cbd6065 100644 --- a/starknet-contract/src/factory.rs +++ b/starknet-contract/src/factory.rs @@ -1,28 +1,28 @@ use starknet_accounts::{Account, AccountError, Call, ConnectedAccount, ExecutionV1, ExecutionV3}; use starknet_core::{ - types::{FeeEstimate, FieldElement, InvokeTransactionResult, SimulatedTransaction}, + types::{FeeEstimate, Felt, InvokeTransactionResult, SimulatedTransaction}, utils::{get_udc_deployed_address, UdcUniqueSettings, UdcUniqueness}, }; /// The default UDC address: 0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf. -const UDC_ADDRESS: FieldElement = FieldElement::from_mont([ - 15144800532519055890, - 15685625669053253235, - 9333317513348225193, +const UDC_ADDRESS: Felt = Felt::from_raw([ 121672436446604875, + 9333317513348225193, + 15685625669053253235, + 15144800532519055890, ]); /// Selector for entrypoint `deployContract`. -const SELECTOR_DEPLOYCONTRACT: FieldElement = FieldElement::from_mont([ - 18249998464715511309, - 1265649739554438882, - 1439621915307882061, +const SELECTOR_DEPLOYCONTRACT: Felt = Felt::from_raw([ 469988280392664069, + 1439621915307882061, + 1265649739554438882, + 18249998464715511309, ]); pub struct ContractFactory { - class_hash: FieldElement, - udc_address: FieldElement, + class_hash: Felt, + udc_address: Felt, account: A, } @@ -32,12 +32,12 @@ pub struct ContractFactory { #[must_use] pub struct DeploymentV1<'f, A> { factory: &'f ContractFactory, - constructor_calldata: Vec, - salt: FieldElement, + constructor_calldata: Vec, + salt: Felt, unique: bool, // The following fields allow us to mimic an `Execution` API. - nonce: Option, - max_fee: Option, + nonce: Option, + max_fee: Option, fee_estimate_multiplier: f64, } @@ -47,11 +47,11 @@ pub struct DeploymentV1<'f, A> { #[must_use] pub struct DeploymentV3<'f, A> { factory: &'f ContractFactory, - constructor_calldata: Vec, - salt: FieldElement, + constructor_calldata: Vec, + salt: Felt, unique: bool, // The following fields allow us to mimic an `Execution` API. - nonce: Option, + nonce: Option, gas: Option, gas_price: Option, gas_estimate_multiplier: f64, @@ -59,11 +59,11 @@ pub struct DeploymentV3<'f, A> { } impl ContractFactory { - pub fn new(class_hash: FieldElement, account: A) -> Self { + pub fn new(class_hash: Felt, account: A) -> Self { Self::new_with_udc(class_hash, account, UDC_ADDRESS) } - pub fn new_with_udc(class_hash: FieldElement, account: A, udc_address: FieldElement) -> Self { + pub fn new_with_udc(class_hash: Felt, account: A, udc_address: Felt) -> Self { Self { class_hash, udc_address, @@ -78,8 +78,8 @@ where { pub fn deploy_v1( &self, - constructor_calldata: Vec, - salt: FieldElement, + constructor_calldata: Vec, + salt: Felt, unique: bool, ) -> DeploymentV1 { DeploymentV1 { @@ -95,8 +95,8 @@ where pub fn deploy_v3( &self, - constructor_calldata: Vec, - salt: FieldElement, + constructor_calldata: Vec, + salt: Felt, unique: bool, ) -> DeploymentV3 { DeploymentV3 { @@ -115,8 +115,8 @@ where #[deprecated = "use version specific variants (`deploy_v1` & `deploy_v3`) instead"] pub fn deploy( &self, - constructor_calldata: Vec, - salt: FieldElement, + constructor_calldata: Vec, + salt: Felt, unique: bool, ) -> DeploymentV1 { self.deploy_v1(constructor_calldata, salt, unique) @@ -124,14 +124,14 @@ where } impl<'f, A> DeploymentV1<'f, A> { - pub fn nonce(self, nonce: FieldElement) -> Self { + pub fn nonce(self, nonce: Felt) -> Self { Self { nonce: Some(nonce), ..self } } - pub fn max_fee(self, max_fee: FieldElement) -> Self { + pub fn max_fee(self, max_fee: Felt) -> Self { Self { max_fee: Some(max_fee), ..self @@ -147,7 +147,7 @@ impl<'f, A> DeploymentV1<'f, A> { } impl<'f, A> DeploymentV3<'f, A> { - pub fn nonce(self, nonce: FieldElement) -> Self { + pub fn nonce(self, nonce: Felt) -> Self { Self { nonce: Some(nonce), ..self @@ -188,7 +188,7 @@ where A: Account, { /// Calculate the resulting contract address without sending a transaction. - pub fn deployed_address(&self) -> FieldElement { + pub fn deployed_address(&self) -> Felt { get_udc_deployed_address( self.salt, self.factory.class_hash, @@ -210,7 +210,7 @@ where A: Account, { /// Calculate the resulting contract address without sending a transaction. - pub fn deployed_address(&self) -> FieldElement { + pub fn deployed_address(&self) -> Felt { get_udc_deployed_address( self.salt, self.factory.class_hash, @@ -280,11 +280,7 @@ impl<'f, A> From<&DeploymentV1<'f, A>> for ExecutionV1<'f, A> { let mut calldata = vec![ value.factory.class_hash, value.salt, - if value.unique { - FieldElement::ONE - } else { - FieldElement::ZERO - }, + if value.unique { Felt::ONE } else { Felt::ZERO }, value.constructor_calldata.len().into(), ]; calldata.extend_from_slice(&value.constructor_calldata); @@ -319,11 +315,7 @@ impl<'f, A> From<&DeploymentV3<'f, A>> for ExecutionV3<'f, A> { let mut calldata = vec![ value.factory.class_hash, value.salt, - if value.unique { - FieldElement::ONE - } else { - FieldElement::ZERO - }, + if value.unique { Felt::ONE } else { Felt::ZERO }, value.constructor_calldata.len().into(), ]; calldata.extend_from_slice(&value.constructor_calldata); @@ -373,17 +365,13 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_deployed_address_unique() { let factory = ContractFactory::new( - FieldElement::from_hex_be( - "0x2bfd9564754d9b4a326da62b2f22b8fea7bbeffd62da4fcaea986c323b7aeb", - ) - .unwrap(), + Felt::from_hex("0x2bfd9564754d9b4a326da62b2f22b8fea7bbeffd62da4fcaea986c323b7aeb") + .unwrap(), SingleOwnerAccount::new( SequencerGatewayProvider::starknet_alpha_sepolia(), LocalWallet::from_signing_key(SigningKey::from_random()), - FieldElement::from_hex_be( - "0xb1461de04c6a1aa3375bdf9b7723a8779c082ffe21311d683a0b15c078b5dc", - ) - .unwrap(), + Felt::from_hex("0xb1461de04c6a1aa3375bdf9b7723a8779c082ffe21311d683a0b15c078b5dc") + .unwrap(), chain_id::SEPOLIA, ExecutionEncoding::Legacy, ), @@ -391,62 +379,54 @@ mod tests { let unique_address_v1 = factory .deploy_v1( - vec![FieldElement::from_hex_be("0x1234").unwrap()], - FieldElement::from_hex_be("0x3456").unwrap(), + vec![Felt::from_hex("0x1234").unwrap()], + Felt::from_hex("0x3456").unwrap(), true, ) .deployed_address(); let unique_address_v3 = factory .deploy_v3( - vec![FieldElement::from_hex_be("0x1234").unwrap()], - FieldElement::from_hex_be("0x3456").unwrap(), + vec![Felt::from_hex("0x1234").unwrap()], + Felt::from_hex("0x3456").unwrap(), true, ) .deployed_address(); let not_unique_address_v1 = factory .deploy_v1( - vec![FieldElement::from_hex_be("0x1234").unwrap()], - FieldElement::from_hex_be("0x3456").unwrap(), + vec![Felt::from_hex("0x1234").unwrap()], + Felt::from_hex("0x3456").unwrap(), false, ) .deployed_address(); let not_unique_address_v3 = factory .deploy_v3( - vec![FieldElement::from_hex_be("0x1234").unwrap()], - FieldElement::from_hex_be("0x3456").unwrap(), + vec![Felt::from_hex("0x1234").unwrap()], + Felt::from_hex("0x3456").unwrap(), false, ) .deployed_address(); assert_eq!( unique_address_v1, - FieldElement::from_hex_be( - "0x36e05bcd41191387bc2f04ed9cad4776a75df3b748b0246a5d217a988474181" - ) - .unwrap() + Felt::from_hex("0x36e05bcd41191387bc2f04ed9cad4776a75df3b748b0246a5d217a988474181") + .unwrap() ); assert_eq!( unique_address_v3, - FieldElement::from_hex_be( - "0x36e05bcd41191387bc2f04ed9cad4776a75df3b748b0246a5d217a988474181" - ) - .unwrap() + Felt::from_hex("0x36e05bcd41191387bc2f04ed9cad4776a75df3b748b0246a5d217a988474181") + .unwrap() ); assert_eq!( not_unique_address_v1, - FieldElement::from_hex_be( - "0x3a320b6aa0b451b22fba90b5d75b943932649137c09a86a5cf4853031be70c1" - ) - .unwrap() + Felt::from_hex("0x3a320b6aa0b451b22fba90b5d75b943932649137c09a86a5cf4853031be70c1") + .unwrap() ); assert_eq!( not_unique_address_v3, - FieldElement::from_hex_be( - "0x3a320b6aa0b451b22fba90b5d75b943932649137c09a86a5cf4853031be70c1" - ) - .unwrap() + Felt::from_hex("0x3a320b6aa0b451b22fba90b5d75b943932649137c09a86a5cf4853031be70c1") + .unwrap() ); } } diff --git a/starknet-contract/tests/contract_deployment.rs b/starknet-contract/tests/contract_deployment.rs index b4bc6b0c..14ab3f26 100644 --- a/starknet-contract/tests/contract_deployment.rs +++ b/starknet-contract/tests/contract_deployment.rs @@ -1,19 +1,17 @@ use rand::{rngs::StdRng, RngCore, SeedableRng}; use starknet_accounts::{ExecutionEncoding, SingleOwnerAccount}; use starknet_contract::ContractFactory; -use starknet_core::types::{ - contract::legacy::LegacyContractClass, BlockId, BlockTag, FieldElement, -}; +use starknet_core::types::{contract::legacy::LegacyContractClass, BlockId, BlockTag, Felt}; use starknet_providers::{jsonrpc::HttpTransport, JsonRpcClient}; use starknet_signers::{LocalWallet, SigningKey}; use url::Url; /// Cairo short string encoding for `SN_SEPOLIA`. -const CHAIN_ID: FieldElement = FieldElement::from_mont([ - 1555806712078248243, - 18446744073708869172, - 18446744073709551615, +const CHAIN_ID: Felt = Felt::from_raw([ 507980251676163170, + 18446744073709551615, + 18446744073708869172, + 1555806712078248243, ]); #[tokio::test] @@ -22,15 +20,11 @@ async fn can_deploy_contract_to_alpha_sepolia_with_invoke_v1() { .unwrap_or("https://pathfinder.rpc.sepolia.starknet.rs/rpc/v0_6".into()); let provider = JsonRpcClient::new(HttpTransport::new(Url::parse(&rpc_url).unwrap())); let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be( - "0x059e738b86f82e11cd5b4afaccfce1d5166700c92fb87be59ad4af908e9bf866", - ) - .unwrap(); + let address = + Felt::from_hex("0x059e738b86f82e11cd5b4afaccfce1d5166700c92fb87be59ad4af908e9bf866") + .unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); account.set_block_id(BlockId::Tag(BlockTag::Pending)); @@ -47,12 +41,8 @@ async fn can_deploy_contract_to_alpha_sepolia_with_invoke_v1() { rng.fill_bytes(&mut salt_buffer[1..]); let result = factory - .deploy_v1( - vec![FieldElement::ONE], - FieldElement::from_bytes_be(&salt_buffer).unwrap(), - true, - ) - .max_fee(FieldElement::from_dec_str("100000000000000000").unwrap()) + .deploy_v1(vec![Felt::ONE], Felt::from_bytes_be(&salt_buffer), true) + .max_fee(Felt::from_dec_str("100000000000000000").unwrap()) .send() .await; @@ -68,15 +58,11 @@ async fn can_deploy_contract_to_alpha_sepolia_with_invoke_v3() { .unwrap_or("https://pathfinder.rpc.sepolia.starknet.rs/rpc/v0_6".into()); let provider = JsonRpcClient::new(HttpTransport::new(Url::parse(&rpc_url).unwrap())); let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be( - "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ) - .unwrap(), + Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), )); - let address = FieldElement::from_hex_be( - "0x034dd51aa591d174b60d1cb45e46dfcae47946fae1c5e62933bbf48effedde4d", - ) - .unwrap(); + let address = + Felt::from_hex("0x034dd51aa591d174b60d1cb45e46dfcae47946fae1c5e62933bbf48effedde4d") + .unwrap(); let mut account = SingleOwnerAccount::new(provider, signer, address, CHAIN_ID, ExecutionEncoding::New); account.set_block_id(BlockId::Tag(BlockTag::Pending)); @@ -93,13 +79,9 @@ async fn can_deploy_contract_to_alpha_sepolia_with_invoke_v3() { rng.fill_bytes(&mut salt_buffer[1..]); let result = factory - .deploy_v3( - vec![FieldElement::ONE], - FieldElement::from_bytes_be(&salt_buffer).unwrap(), - true, - ) + .deploy_v3(vec![Felt::ONE], Felt::from_bytes_be(&salt_buffer), true) .gas(200000) - .gas_price(100000000000000) + .gas_price(500000000000000) .send() .await; diff --git a/starknet-core/Cargo.toml b/starknet-core/Cargo.toml index 00526ca2..74164b66 100644 --- a/starknet-core/Cargo.toml +++ b/starknet-core/Cargo.toml @@ -18,7 +18,6 @@ all-features = true [dependencies] starknet-crypto = { version = "0.6.2", path = "../starknet-crypto", default-features = false, features = ["alloc"] } -starknet-ff = { version = "0.3.7", path = "../starknet-ff", default-features = false, features = ["serde"] } base64 = { version = "0.21.0", default-features = false, features = ["alloc"] } crypto-bigint = { version = "0.5.1", default-features = false } flate2 = { version = "1.0.25", optional = true } @@ -28,6 +27,7 @@ serde_json = { version = "1.0.96", default-features = false, features = ["alloc" serde_json_pythonic = { version = "0.1.2", default-features = false, features = ["alloc", "raw_value"] } serde_with = { version = "2.3.2", default-features = false, features = ["alloc", "macros"] } sha3 = { version = "0.10.7", default-features = false } +starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve", "serde"] } [dev-dependencies] criterion = { version = "0.4.0", default-features = false } @@ -39,7 +39,7 @@ wasm-bindgen-test = "0.3.34" [features] default = ["std"] -std = ["dep:flate2", "starknet-ff/std", "starknet-crypto/std"] +std = ["dep:flate2", "starknet-crypto/std"] no_unknown_fields = [] [[bench]] diff --git a/starknet-core/README.md b/starknet-core/README.md index 52421fe7..51ffb585 100644 --- a/starknet-core/README.md +++ b/starknet-core/README.md @@ -11,8 +11,8 @@ For instructions on running the benchmarks yourself, check out [this page](../BE ### Native ```log -cairo0_class_hash time: [10.808 ms 10.813 ms 10.819 ms] -sierra_class_hash time: [6.2774 ms 6.2802 ms 6.2832 ms] +cairo0_class_hash time: [9.1665 ms 9.1690 ms 9.1718 ms] +sierra_class_hash time: [6.6931 ms 6.6944 ms 6.6958 ms] ``` ### WebAssembly @@ -29,6 +29,6 @@ wasmtime-cli 21.0.1 (cedf9aa0f 2024-05-22) `wasmtime` results: ```log -cairo0_class_hash time: [39.192 ms 39.207 ms 39.224 ms] -sierra_class_hash time: [20.514 ms 20.521 ms 20.529 ms] +cairo0_class_hash time: [36.515 ms 36.526 ms 36.538 ms] +sierra_class_hash time: [22.550 ms 22.557 ms 22.567 ms] ``` diff --git a/starknet-core/src/chain_id.rs b/starknet-core/src/chain_id.rs index eac0ec51..cbb430fa 100644 --- a/starknet-core/src/chain_id.rs +++ b/starknet-core/src/chain_id.rs @@ -1,33 +1,33 @@ -use crate::types::FieldElement; +use starknet_types_core::felt::Felt; -pub const MAINNET: FieldElement = FieldElement::from_mont([ - 17696389056366564951, +pub const MAINNET: Felt = Felt::from_raw([ + 502562008147966918, 18446744073709551615, 18446744073709551615, - 502562008147966918, + 17696389056366564951, ]); #[deprecated = "The Goerli testnet has been shutdown"] -pub const TESTNET: FieldElement = FieldElement::from_mont([ - 3753493103916128178, - 18446744073709548950, - 18446744073709551615, +pub const TESTNET: Felt = Felt::from_raw([ 398700013197595345, + 18446744073709551615, + 18446744073709548950, + 3753493103916128178, ]); #[deprecated = "The Goerli testnet has been shutdown"] -pub const TESTNET2: FieldElement = FieldElement::from_mont([ - 1663542769632127759, - 18446744073708869172, - 18446744073709551615, +pub const TESTNET2: Felt = Felt::from_raw([ 33650220878420990, + 18446744073709551615, + 18446744073708869172, + 1663542769632127759, ]); -pub const SEPOLIA: FieldElement = FieldElement::from_mont([ - 1555806712078248243, - 18446744073708869172, - 18446744073709551615, +pub const SEPOLIA: Felt = Felt::from_raw([ 507980251676163170, + 18446744073709551615, + 18446744073708869172, + 1555806712078248243, ]); #[cfg(test)] diff --git a/starknet-core/src/crypto.rs b/starknet-core/src/crypto.rs index e703fc24..634faab9 100644 --- a/starknet-core/src/crypto.rs +++ b/starknet-core/src/crypto.rs @@ -1,4 +1,4 @@ -use crate::types::FieldElement; +use starknet_types_core::felt::Felt; pub use starknet_crypto::{pedersen_hash, ExtendedSignature, Signature}; use starknet_crypto::{rfc6979_generate_k, sign, verify, SignError, VerifyError}; @@ -46,20 +46,20 @@ mod errors { } pub use errors::{EcdsaSignError, EcdsaVerifyError}; -pub fn compute_hash_on_elements(data: &[FieldElement]) -> FieldElement { - let mut current_hash = FieldElement::ZERO; +pub fn compute_hash_on_elements(data: &[Felt]) -> Felt { + let mut current_hash = Felt::ZERO; for item in data.iter() { current_hash = pedersen_hash(¤t_hash, item); } - let data_len = FieldElement::from(data.len()); + let data_len = Felt::from(data.len()); pedersen_hash(¤t_hash, &data_len) } pub fn ecdsa_sign( - private_key: &FieldElement, - message_hash: &FieldElement, + private_key: &Felt, + message_hash: &Felt, ) -> Result { // Seed-retry logic ported from `cairo-lang` let mut seed = None; @@ -76,8 +76,8 @@ pub fn ecdsa_sign( Err(SignError::InvalidK) => { // Bump seed and retry seed = match seed { - Some(prev_seed) => Some(prev_seed + FieldElement::ONE), - None => Some(FieldElement::ONE), + Some(prev_seed) => Some(prev_seed + Felt::ONE), + None => Some(Felt::ONE), }; } }; @@ -85,8 +85,8 @@ pub fn ecdsa_sign( } pub fn ecdsa_verify( - public_key: &FieldElement, - message_hash: &FieldElement, + public_key: &Felt, + message_hash: &Felt, signature: &Signature, ) -> Result { match verify(public_key, message_hash, &signature.r, &signature.s) { @@ -107,15 +107,14 @@ mod tests { fn test_compute_hash_on_elements() { // Generated with `cairo-lang` let hash = compute_hash_on_elements(&[ - FieldElement::from_hex_be("0xaa").unwrap(), - FieldElement::from_hex_be("0xbb").unwrap(), - FieldElement::from_hex_be("0xcc").unwrap(), - FieldElement::from_hex_be("0xdd").unwrap(), + Felt::from_hex("0xaa").unwrap(), + Felt::from_hex("0xbb").unwrap(), + Felt::from_hex("0xcc").unwrap(), + Felt::from_hex("0xdd").unwrap(), ]); - let expected_hash = FieldElement::from_hex_be( - "025cde77210b1c223b2c6e69db6e9021aa1599177ab177474d5326cd2a62cb69", - ) - .unwrap(); + let expected_hash = + Felt::from_hex("025cde77210b1c223b2c6e69db6e9021aa1599177ab177474d5326cd2a62cb69") + .unwrap(); assert_eq!(expected_hash, hash); } @@ -125,10 +124,9 @@ mod tests { fn test_compute_hash_on_elements_empty_data() { // Generated with `cairo-lang` let hash = compute_hash_on_elements(&[]); - let expected_hash = FieldElement::from_hex_be( - "049ee3eba8c1600700ee1b87eb599f16716b0b1022947733551fde4050ca6804", - ) - .unwrap(); + let expected_hash = + Felt::from_hex("049ee3eba8c1600700ee1b87eb599f16716b0b1022947733551fde4050ca6804") + .unwrap(); assert_eq!(expected_hash, hash); } @@ -138,24 +136,18 @@ mod tests { fn test_ecdsa_sign() { // Generated with `cairo-lang` let signature = ecdsa_sign( - &FieldElement::from_hex_be( - "0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79", - ) - .unwrap(), - &FieldElement::from_hex_be( - "06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76", - ) - .unwrap(), - ) - .unwrap(); - let expected_r = FieldElement::from_hex_be( - "061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f", - ) - .unwrap(); - let expected_s = FieldElement::from_hex_be( - "04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a", + &Felt::from_hex("0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79") + .unwrap(), + &Felt::from_hex("06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76") + .unwrap(), ) .unwrap(); + let expected_r = + Felt::from_hex("061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f") + .unwrap(); + let expected_s = + Felt::from_hex("04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a") + .unwrap(); assert_eq!(signature.r, expected_r); assert_eq!(signature.s, expected_s); @@ -165,14 +157,10 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_ecdsa_sign_message_hash_out_of_range() { match ecdsa_sign( - &FieldElement::from_hex_be( - "0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79", - ) - .unwrap(), - &FieldElement::from_hex_be( - "0800000000000000000000000000000000000000000000000000000000000000", - ) - .unwrap(), + &Felt::from_hex("0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79") + .unwrap(), + &Felt::from_hex("0800000000000000000000000000000000000000000000000000000000000000") + .unwrap(), ) { Err(EcdsaSignError::MessageHashOutOfRange) => {} _ => panic!("Should throw error on out of range message hash"), @@ -183,22 +171,16 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_ecdsa_verify_valid_signature() { // Generated with `cairo-lang` - let public_key = FieldElement::from_hex_be( - "02c5dbad71c92a45cc4b40573ae661f8147869a91d57b8d9b8f48c8af7f83159", - ) - .unwrap(); - let message_hash = FieldElement::from_hex_be( - "06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76", - ) - .unwrap(); - let r = FieldElement::from_hex_be( - "061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f", - ) - .unwrap(); - let s = FieldElement::from_hex_be( - "04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a", - ) - .unwrap(); + let public_key = + Felt::from_hex("02c5dbad71c92a45cc4b40573ae661f8147869a91d57b8d9b8f48c8af7f83159") + .unwrap(); + let message_hash = + Felt::from_hex("06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76") + .unwrap(); + let r = Felt::from_hex("061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f") + .unwrap(); + let s = Felt::from_hex("04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a") + .unwrap(); assert!(ecdsa_verify(&public_key, &message_hash, &Signature { r, s }).unwrap()); } @@ -207,22 +189,16 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_ecdsa_verify_invalid_signature() { // Generated with `cairo-lang` - let public_key = FieldElement::from_hex_be( - "02c5dbad71c92a45cc4b40573ae661f8147869a91d57b8d9b8f48c8af7f83159", - ) - .unwrap(); - let message_hash = FieldElement::from_hex_be( - "06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76", - ) - .unwrap(); - let r = FieldElement::from_hex_be( - "061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f", - ) - .unwrap(); - let s = FieldElement::from_hex_be( - "04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9b", - ) - .unwrap(); + let public_key = + Felt::from_hex("02c5dbad71c92a45cc4b40573ae661f8147869a91d57b8d9b8f48c8af7f83159") + .unwrap(); + let message_hash = + Felt::from_hex("06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76") + .unwrap(); + let r = Felt::from_hex("061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f") + .unwrap(); + let s = Felt::from_hex("04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9b") + .unwrap(); assert!(!ecdsa_verify(&public_key, &message_hash, &Signature { r, s }).unwrap()); } diff --git a/starknet-core/src/serde/unsigned_field_element.rs b/starknet-core/src/serde/unsigned_field_element.rs index 1a4d8a53..38317ff9 100644 --- a/starknet-core/src/serde/unsigned_field_element.rs +++ b/starknet-core/src/serde/unsigned_field_element.rs @@ -6,7 +6,7 @@ use serde::{ }; use serde_with::{DeserializeAs, SerializeAs}; -use crate::types::FieldElement; +use starknet_types_core::felt::Felt; pub struct UfeHex; @@ -18,8 +18,8 @@ struct UfeHexVisitor; struct UfeHexOptionVisitor; struct UfePendingBlockHashVisitor; -impl SerializeAs for UfeHex { - fn serialize_as(value: &FieldElement, serializer: S) -> Result +impl SerializeAs for UfeHex { + fn serialize_as(value: &Felt, serializer: S) -> Result where S: Serializer, { @@ -27,8 +27,8 @@ impl SerializeAs for UfeHex { } } -impl<'de> DeserializeAs<'de, FieldElement> for UfeHex { - fn deserialize_as(deserializer: D) -> Result +impl<'de> DeserializeAs<'de, Felt> for UfeHex { + fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { @@ -37,7 +37,7 @@ impl<'de> DeserializeAs<'de, FieldElement> for UfeHex { } impl<'de> Visitor<'de> for UfeHexVisitor { - type Value = FieldElement; + type Value = Felt; fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { write!(formatter, "string") @@ -47,13 +47,12 @@ impl<'de> Visitor<'de> for UfeHexVisitor { where E: DeError, { - FieldElement::from_hex_be(v) - .map_err(|err| DeError::custom(format!("invalid hex string: {err}"))) + Felt::from_hex(v).map_err(|err| DeError::custom(format!("invalid hex string: {err}"))) } } -impl SerializeAs> for UfeHexOption { - fn serialize_as(value: &Option, serializer: S) -> Result +impl SerializeAs> for UfeHexOption { + fn serialize_as(value: &Option, serializer: S) -> Result where S: Serializer, { @@ -64,8 +63,8 @@ impl SerializeAs> for UfeHexOption { } } -impl<'de> DeserializeAs<'de, Option> for UfeHexOption { - fn deserialize_as(deserializer: D) -> Result, D::Error> +impl<'de> DeserializeAs<'de, Option> for UfeHexOption { + fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { @@ -74,7 +73,7 @@ impl<'de> DeserializeAs<'de, Option> for UfeHexOption { } impl<'de> Visitor<'de> for UfeHexOptionVisitor { - type Value = Option; + type Value = Option; fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { write!(formatter, "string") @@ -86,7 +85,7 @@ impl<'de> Visitor<'de> for UfeHexOptionVisitor { { match v { "" => Ok(None), - _ => match FieldElement::from_hex_be(v) { + _ => match Felt::from_hex(v) { Ok(value) => Ok(Some(value)), Err(err) => Err(DeError::custom(format!("invalid hex string: {err}"))), }, @@ -94,8 +93,8 @@ impl<'de> Visitor<'de> for UfeHexOptionVisitor { } } -impl SerializeAs> for UfePendingBlockHash { - fn serialize_as(value: &Option, serializer: S) -> Result +impl SerializeAs> for UfePendingBlockHash { + fn serialize_as(value: &Option, serializer: S) -> Result where S: Serializer, { @@ -107,8 +106,8 @@ impl SerializeAs> for UfePendingBlockHash { } } -impl<'de> DeserializeAs<'de, Option> for UfePendingBlockHash { - fn deserialize_as(deserializer: D) -> Result, D::Error> +impl<'de> DeserializeAs<'de, Option> for UfePendingBlockHash { + fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { @@ -117,7 +116,7 @@ impl<'de> DeserializeAs<'de, Option> for UfePendingBlockHash { } impl<'de> Visitor<'de> for UfePendingBlockHashVisitor { - type Value = Option; + type Value = Option; fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { write!(formatter, "string") @@ -130,7 +129,7 @@ impl<'de> Visitor<'de> for UfePendingBlockHashVisitor { if v.is_empty() || v == "pending" || v == "None" { Ok(None) } else { - match FieldElement::from_hex_be(v) { + match Felt::from_hex(v) { Ok(value) => Ok(Some(value)), Err(err) => Err(DeError::custom(format!("invalid hex string: {err}"))), } @@ -147,7 +146,7 @@ mod tests { #[serde_as] #[derive(Deserialize)] - struct TestStruct(#[serde_as(as = "UfeHexOption")] pub Option); + struct TestStruct(#[serde_as(as = "UfeHexOption")] pub Option); #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] diff --git a/starknet-core/src/types/codegen.rs b/starknet-core/src/types/codegen.rs index b10d4976..46e11560 100644 --- a/starknet-core/src/types/codegen.rs +++ b/starknet-core/src/types/codegen.rs @@ -3,7 +3,7 @@ // https://github.com/xJonathanLEI/starknet-jsonrpc-codegen // Code generated with version: -// https://github.com/xJonathanLEI/starknet-jsonrpc-codegen#2fc8455d3720039015a9abf014c27ea3ca24bd25 +// https://github.com/xJonathanLEI/starknet-jsonrpc-codegen#4118b48cc450a8ff558c2ac480aa12bf5efdd3bd // These types are ignored from code generation. Implement them manually: // - `RECEIPT_BLOCK` @@ -38,11 +38,11 @@ pub type OwnedPtr = alloc::sync::Arc; #[cfg(not(target_has_atomic = "ptr"))] pub type OwnedPtr = alloc::boxed::Box; -const QUERY_VERSION_OFFSET: FieldElement = FieldElement::from_mont([ - 18446744073700081665, - 17407, - 18446744073709551584, +const QUERY_VERSION_OFFSET: Felt = Felt::from_raw([ 576460752142434320, + 18446744073709551584, + 17407, + 18446744073700081665, ]); /// Block status. @@ -82,20 +82,20 @@ pub struct BlockWithReceipts { pub status: BlockStatus, /// Block hash #[serde_as(as = "UfeHex")] - pub block_hash: FieldElement, + pub block_hash: Felt, /// The hash of this block's parent #[serde_as(as = "UfeHex")] - pub parent_hash: FieldElement, + pub parent_hash: Felt, /// The block number (its height) pub block_number: u64, /// The new global state root #[serde_as(as = "UfeHex")] - pub new_root: FieldElement, + pub new_root: Felt, /// The time in which the block was created, encoded in Unix time pub timestamp: u64, /// The Starknet identity of the sequencer submitting this block #[serde_as(as = "UfeHex")] - pub sequencer_address: FieldElement, + pub sequencer_address: Felt, /// The price of L1 gas in the block pub l1_gas_price: ResourcePrice, /// The price of L1 data gas in the block @@ -119,20 +119,20 @@ pub struct BlockWithTxHashes { pub status: BlockStatus, /// Block hash #[serde_as(as = "UfeHex")] - pub block_hash: FieldElement, + pub block_hash: Felt, /// The hash of this block's parent #[serde_as(as = "UfeHex")] - pub parent_hash: FieldElement, + pub parent_hash: Felt, /// The block number (its height) pub block_number: u64, /// The new global state root #[serde_as(as = "UfeHex")] - pub new_root: FieldElement, + pub new_root: Felt, /// The time in which the block was created, encoded in Unix time pub timestamp: u64, /// The Starknet identity of the sequencer submitting this block #[serde_as(as = "UfeHex")] - pub sequencer_address: FieldElement, + pub sequencer_address: Felt, /// The price of L1 gas in the block pub l1_gas_price: ResourcePrice, /// The price of L1 data gas in the block @@ -143,7 +143,7 @@ pub struct BlockWithTxHashes { pub starknet_version: String, /// The hashes of the transactions included in this block #[serde_as(as = "Vec")] - pub transactions: Vec, + pub transactions: Vec, } /// Block with transactions. @@ -157,20 +157,20 @@ pub struct BlockWithTxs { pub status: BlockStatus, /// Block hash #[serde_as(as = "UfeHex")] - pub block_hash: FieldElement, + pub block_hash: Felt, /// The hash of this block's parent #[serde_as(as = "UfeHex")] - pub parent_hash: FieldElement, + pub parent_hash: Felt, /// The block number (its height) pub block_number: u64, /// The new global state root #[serde_as(as = "UfeHex")] - pub new_root: FieldElement, + pub new_root: Felt, /// The time in which the block was created, encoded in Unix time pub timestamp: u64, /// The Starknet identity of the sequencer submitting this block #[serde_as(as = "UfeHex")] - pub sequencer_address: FieldElement, + pub sequencer_address: Felt, /// The price of L1 gas in the block pub l1_gas_price: ResourcePrice, /// The price of L1 data gas in the block @@ -187,13 +187,13 @@ pub struct BlockWithTxs { #[derive(Debug, Clone, PartialEq, Eq)] pub struct BroadcastedDeclareTransactionV1 { /// The address of the account contract sending the declaration transaction - pub sender_address: FieldElement, + pub sender_address: Felt, /// The maximal fee that can be charged for including the transaction - pub max_fee: FieldElement, + pub max_fee: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// The class to be declared pub contract_class: OwnedPtr, /// If set to `true`, uses a query-only transaction version that's invalid for execution @@ -206,15 +206,15 @@ pub struct BroadcastedDeclareTransactionV1 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct BroadcastedDeclareTransactionV2 { /// The address of the account contract sending the declaration transaction - pub sender_address: FieldElement, + pub sender_address: Felt, /// The hash of the cairo assembly resulting from the sierra compilation - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, /// The maximal fee that can be charged for including the transaction - pub max_fee: FieldElement, + pub max_fee: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// The class to be declared pub contract_class: OwnedPtr, /// If set to `true`, uses a query-only transaction version that's invalid for execution @@ -227,13 +227,13 @@ pub struct BroadcastedDeclareTransactionV2 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct BroadcastedDeclareTransactionV3 { /// The address of the account contract sending the declaration transaction - pub sender_address: FieldElement, + pub sender_address: Felt, /// The hash of the cairo assembly resulting from the sierra compilation - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// The class to be declared pub contract_class: OwnedPtr, /// Resource bounds for the transaction execution @@ -241,9 +241,9 @@ pub struct BroadcastedDeclareTransactionV3 { /// The tip for the transaction pub tip: u64, /// Data needed to allow the paymaster to pay for the transaction in native tokens - pub paymaster_data: Vec, + pub paymaster_data: Vec, /// Data needed to deploy the account contract from which this tx will be initiated - pub account_deployment_data: Vec, + pub account_deployment_data: Vec, /// The storage domain of the account's nonce (an account has a nonce per da mode) pub nonce_data_availability_mode: DataAvailabilityMode, /// The storage domain of the account's balance from which fee will be charged @@ -258,17 +258,17 @@ pub struct BroadcastedDeclareTransactionV3 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct BroadcastedDeployAccountTransactionV1 { /// The maximal fee that can be charged for including the transaction - pub max_fee: FieldElement, + pub max_fee: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// The salt for the address of the deployed contract - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, /// The parameters passed to the constructor - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, /// The hash of the deployed contract's class - pub class_hash: FieldElement, + pub class_hash: Felt, /// If set to `true`, uses a query-only transaction version that's invalid for execution pub is_query: bool, } @@ -279,21 +279,21 @@ pub struct BroadcastedDeployAccountTransactionV1 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct BroadcastedDeployAccountTransactionV3 { /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// The salt for the address of the deployed contract - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, /// The parameters passed to the constructor - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, /// The hash of the deployed contract's class - pub class_hash: FieldElement, + pub class_hash: Felt, /// Resource bounds for the transaction execution pub resource_bounds: ResourceBoundsMapping, /// The tip for the transaction pub tip: u64, /// Data needed to allow the paymaster to pay for the transaction in native tokens - pub paymaster_data: Vec, + pub paymaster_data: Vec, /// The storage domain of the account's nonce (an account has a nonce per da mode) pub nonce_data_availability_mode: DataAvailabilityMode, /// The storage domain of the account's balance from which fee will be charged @@ -308,16 +308,16 @@ pub struct BroadcastedDeployAccountTransactionV3 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct BroadcastedInvokeTransactionV1 { /// Sender address - pub sender_address: FieldElement, + pub sender_address: Felt, /// The data expected by the account's `execute` function (in most usecases, this includes the /// called contract address and a function selector) - pub calldata: Vec, + pub calldata: Vec, /// The maximal fee that can be charged for including the transaction - pub max_fee: FieldElement, + pub max_fee: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// If set to `true`, uses a query-only transaction version that's invalid for execution pub is_query: bool, } @@ -328,22 +328,22 @@ pub struct BroadcastedInvokeTransactionV1 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct BroadcastedInvokeTransactionV3 { /// Sender address - pub sender_address: FieldElement, + pub sender_address: Felt, /// The data expected by the account's `execute` function (in most usecases, this includes the /// called contract address and a function selector) - pub calldata: Vec, + pub calldata: Vec, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// Resource bounds for the transaction execution pub resource_bounds: ResourceBoundsMapping, /// The tip for the transaction pub tip: u64, /// Data needed to allow the paymaster to pay for the transaction in native tokens - pub paymaster_data: Vec, + pub paymaster_data: Vec, /// Data needed to deploy the account contract from which this tx will be initiated - pub account_deployment_data: Vec, + pub account_deployment_data: Vec, /// The storage domain of the account's nonce (an account has a nonce per da mode) pub nonce_data_availability_mode: DataAvailabilityMode, /// The storage domain of the account's balance from which fee will be charged @@ -430,7 +430,7 @@ pub struct ContractErrorData { pub struct ContractStorageDiffItem { /// The contract address for which the storage changed #[serde_as(as = "UfeHex")] - pub address: FieldElement, + pub address: Felt, /// The changes in the storage of the contract pub storage_entries: Vec, } @@ -469,7 +469,7 @@ pub struct DataResources { #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareTransactionReceipt { /// The hash identifying the transaction - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The fee that was charged by the sequencer pub actual_fee: FeePayment, /// Finality status of the tx @@ -500,15 +500,15 @@ pub struct DeclareTransactionTrace { #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareTransactionV0 { /// Transaction hash - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The address of the account contract sending the declaration transaction - pub sender_address: FieldElement, + pub sender_address: Felt, /// The maximal fee that can be charged for including the transaction - pub max_fee: FieldElement, + pub max_fee: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// The hash of the declared class - pub class_hash: FieldElement, + pub class_hash: Felt, } /// Declare contract transaction v1. @@ -517,17 +517,17 @@ pub struct DeclareTransactionV0 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareTransactionV1 { /// Transaction hash - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The address of the account contract sending the declaration transaction - pub sender_address: FieldElement, + pub sender_address: Felt, /// The maximal fee that can be charged for including the transaction - pub max_fee: FieldElement, + pub max_fee: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// The hash of the declared class - pub class_hash: FieldElement, + pub class_hash: Felt, } /// Declare transaction v2. @@ -536,19 +536,19 @@ pub struct DeclareTransactionV1 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareTransactionV2 { /// Transaction hash - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The address of the account contract sending the declaration transaction - pub sender_address: FieldElement, + pub sender_address: Felt, /// The hash of the cairo assembly resulting from the sierra compilation - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, /// The maximal fee that can be charged for including the transaction - pub max_fee: FieldElement, + pub max_fee: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// The hash of the declared class - pub class_hash: FieldElement, + pub class_hash: Felt, } /// Declare transaction v3. @@ -557,25 +557,25 @@ pub struct DeclareTransactionV2 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareTransactionV3 { /// Transaction hash - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The address of the account contract sending the declaration transaction - pub sender_address: FieldElement, + pub sender_address: Felt, /// The hash of the cairo assembly resulting from the sierra compilation - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// The hash of the declared class - pub class_hash: FieldElement, + pub class_hash: Felt, /// Resource bounds for the transaction execution pub resource_bounds: ResourceBoundsMapping, /// The tip for the transaction pub tip: u64, /// Data needed to allow the paymaster to pay for the transaction in native tokens - pub paymaster_data: Vec, + pub paymaster_data: Vec, /// Data needed to deploy the account contract from which this tx will be initiated - pub account_deployment_data: Vec, + pub account_deployment_data: Vec, /// The storage domain of the account's nonce (an account has a nonce per da mode) pub nonce_data_availability_mode: DataAvailabilityMode, /// The storage domain of the account's balance from which fee will be charged @@ -591,17 +591,17 @@ pub struct DeclareTransactionV3 { pub struct DeclaredClassItem { /// The hash of the declared class #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, /// The cairo assembly hash corresponding to the declared class #[serde_as(as = "UfeHex")] - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, } /// Deploy account transaction receipt. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeployAccountTransactionReceipt { /// The hash identifying the transaction - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The fee that was charged by the sequencer pub actual_fee: FeePayment, /// Finality status of the tx @@ -614,7 +614,7 @@ pub struct DeployAccountTransactionReceipt { pub execution_resources: ExecutionResources, pub execution_result: ExecutionResult, /// The address of the deployed contract - pub contract_address: FieldElement, + pub contract_address: Felt, } /// The execution trace of a deploy account transaction. @@ -637,19 +637,19 @@ pub struct DeployAccountTransactionTrace { #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeployAccountTransactionV1 { /// Transaction hash - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The maximal fee that can be charged for including the transaction - pub max_fee: FieldElement, + pub max_fee: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// The salt for the address of the deployed contract - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, /// The parameters passed to the constructor - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, /// The hash of the deployed contract's class - pub class_hash: FieldElement, + pub class_hash: Felt, } /// Deploy account transaction. @@ -658,23 +658,23 @@ pub struct DeployAccountTransactionV1 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeployAccountTransactionV3 { /// Transaction hash - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// The salt for the address of the deployed contract - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, /// The parameters passed to the constructor - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, /// The hash of the deployed contract's class - pub class_hash: FieldElement, + pub class_hash: Felt, /// Resource bounds for the transaction execution pub resource_bounds: ResourceBoundsMapping, /// The tip for the transaction pub tip: u64, /// Data needed to allow the paymaster to pay for the transaction in native tokens - pub paymaster_data: Vec, + pub paymaster_data: Vec, /// The storage domain of the account's nonce (an account has a nonce per da mode) pub nonce_data_availability_mode: DataAvailabilityMode, /// The storage domain of the account's balance from which fee will be charged @@ -688,22 +688,22 @@ pub struct DeployAccountTransactionV3 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeployTransaction { /// Transaction hash - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// Version of the transaction scheme - pub version: FieldElement, + pub version: Felt, /// The salt for the address of the deployed contract - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, /// The parameters passed to the constructor - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, /// The hash of the deployed contract's class - pub class_hash: FieldElement, + pub class_hash: Felt, } /// Deploy transaction receipt. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeployTransactionReceipt { /// The hash identifying the transaction - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The fee that was charged by the sequencer pub actual_fee: FeePayment, /// Finality status of the tx @@ -716,7 +716,7 @@ pub struct DeployTransactionReceipt { pub execution_resources: ExecutionResources, pub execution_result: ExecutionResult, /// The address of the deployed contract - pub contract_address: FieldElement, + pub contract_address: Felt, } /// Deployed contract item. @@ -726,10 +726,10 @@ pub struct DeployTransactionReceipt { pub struct DeployedContractItem { /// The address of the contract #[serde_as(as = "UfeHex")] - pub address: FieldElement, + pub address: Felt, /// The hash of the contract code #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } /// Emitted event. @@ -742,23 +742,23 @@ pub struct DeployedContractItem { pub struct EmittedEvent { /// From address #[serde_as(as = "UfeHex")] - pub from_address: FieldElement, + pub from_address: Felt, /// Keys #[serde_as(as = "Vec")] - pub keys: Vec, + pub keys: Vec, /// Data #[serde_as(as = "Vec")] - pub data: Vec, + pub data: Vec, /// The hash of the block in which the event was emitted #[serde(skip_serializing_if = "Option::is_none")] #[serde_as(as = "Option")] - pub block_hash: Option, + pub block_hash: Option, /// The number of the block in which the event was emitted #[serde(skip_serializing_if = "Option::is_none")] pub block_number: Option, /// The transaction that emitted the event #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] @@ -795,13 +795,13 @@ pub struct EntryPointsByType { pub struct Event { /// From address #[serde_as(as = "UfeHex")] - pub from_address: FieldElement, + pub from_address: Felt, /// Keys #[serde_as(as = "Vec")] - pub keys: Vec, + pub keys: Vec, /// Data #[serde_as(as = "Vec")] - pub data: Vec, + pub data: Vec, } /// Event filter. @@ -820,11 +820,11 @@ pub struct EventFilter { /// From contract #[serde(skip_serializing_if = "Option::is_none")] #[serde_as(as = "Option")] - pub address: Option, + pub address: Option, /// The values used to filter the events #[serde(skip_serializing_if = "Option::is_none")] #[serde_as(as = "Option>>")] - pub keys: Option>>, + pub keys: Option>>, } /// Events request. @@ -868,22 +868,22 @@ pub struct ExecutionResources { pub struct FeeEstimate { /// The Ethereum gas consumption of the transaction #[serde_as(as = "UfeHex")] - pub gas_consumed: FieldElement, + pub gas_consumed: Felt, /// The gas price (in wei or fri, depending on the tx version) that was used in the cost /// estimation #[serde_as(as = "UfeHex")] - pub gas_price: FieldElement, + pub gas_price: Felt, /// The Ethereum data gas consumption of the transaction #[serde_as(as = "UfeHex")] - pub data_gas_consumed: FieldElement, + pub data_gas_consumed: Felt, /// The data gas price (in wei or fri, depending on the tx version) that was used in the cost /// estimation #[serde_as(as = "UfeHex")] - pub data_gas_price: FieldElement, + pub data_gas_price: Felt, /// The estimated fee for the transaction (in wei or fri, depending on the tx version), equals /// to gas_consumed*gas_price + data_gas_consumed*data_gas_price #[serde_as(as = "UfeHex")] - pub overall_fee: FieldElement, + pub overall_fee: Felt, /// Units in which the fee is given pub unit: PriceUnit, } @@ -897,7 +897,7 @@ pub struct FeeEstimate { pub struct FeePayment { /// Amount paid #[serde_as(as = "UfeHex")] - pub amount: FieldElement, + pub amount: Felt, /// Units in which the fee is given pub unit: PriceUnit, } @@ -909,7 +909,7 @@ pub struct FeePayment { pub struct FlattenedSierraClass { /// The list of sierra instructions of which the program consists #[serde_as(as = "Vec")] - pub sierra_program: Vec, + pub sierra_program: Vec, /// The version of the contract class object. Currently, the Starknet os supports version 0.1.0 pub contract_class_version: String, /// Entry points by type @@ -927,13 +927,13 @@ pub struct FlattenedSierraClass { pub struct FunctionCall { /// Contract address #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, /// Entry point selector #[serde_as(as = "UfeHex")] - pub entry_point_selector: FieldElement, + pub entry_point_selector: Felt, /// The parameters passed to the function #[serde_as(as = "Vec")] - pub calldata: Vec, + pub calldata: Vec, } #[serde_as] @@ -942,24 +942,24 @@ pub struct FunctionCall { pub struct FunctionInvocation { /// Contract address #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, /// Entry point selector #[serde_as(as = "UfeHex")] - pub entry_point_selector: FieldElement, + pub entry_point_selector: Felt, /// The parameters passed to the function #[serde_as(as = "Vec")] - pub calldata: Vec, + pub calldata: Vec, /// The address of the invoking contract. 0 for the root invocation #[serde_as(as = "UfeHex")] - pub caller_address: FieldElement, + pub caller_address: Felt, /// The hash of the class being called #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, pub entry_point_type: EntryPointType, pub call_type: CallType, /// The value returned from the function invocation #[serde_as(as = "Vec")] - pub result: Vec, + pub result: Vec, /// The calls made by this invocation pub calls: Vec, /// The events emitted in this invocation @@ -982,7 +982,7 @@ pub enum FunctionStateMutability { #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeTransactionReceipt { /// The hash identifying the transaction - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The fee that was charged by the sequencer pub actual_fee: FeePayment, /// Finality status of the tx @@ -1014,17 +1014,17 @@ pub struct InvokeTransactionTrace { #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeTransactionV0 { /// Transaction hash - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The maximal fee that can be charged for including the transaction - pub max_fee: FieldElement, + pub max_fee: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Contract address - pub contract_address: FieldElement, + pub contract_address: Felt, /// Entry point selector - pub entry_point_selector: FieldElement, + pub entry_point_selector: Felt, /// The parameters passed to the function - pub calldata: Vec, + pub calldata: Vec, } /// Invoke transaction v1. @@ -1033,18 +1033,18 @@ pub struct InvokeTransactionV0 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeTransactionV1 { /// Transaction hash - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// Sender address - pub sender_address: FieldElement, + pub sender_address: Felt, /// The data expected by the account's `execute` function (in most usecases, this includes the /// called contract address and a function selector) - pub calldata: Vec, + pub calldata: Vec, /// The maximal fee that can be charged for including the transaction - pub max_fee: FieldElement, + pub max_fee: Felt, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, } /// Invoke transaction v3. @@ -1053,24 +1053,24 @@ pub struct InvokeTransactionV1 { #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeTransactionV3 { /// Transaction hash - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// Sender address - pub sender_address: FieldElement, + pub sender_address: Felt, /// The data expected by the account's `execute` function (in most usecases, this includes the /// called contract address and a function selector) - pub calldata: Vec, + pub calldata: Vec, /// Signature - pub signature: Vec, + pub signature: Vec, /// Nonce - pub nonce: FieldElement, + pub nonce: Felt, /// Resource bounds for the transaction execution pub resource_bounds: ResourceBoundsMapping, /// The tip for the transaction pub tip: u64, /// Data needed to allow the paymaster to pay for the transaction in native tokens - pub paymaster_data: Vec, + pub paymaster_data: Vec, /// Data needed to deploy the account contract from which this tx will be initiated - pub account_deployment_data: Vec, + pub account_deployment_data: Vec, /// The storage domain of the account's nonce (an account has a nonce per da mode) pub nonce_data_availability_mode: DataAvailabilityMode, /// The storage domain of the account's balance from which fee will be charged @@ -1090,18 +1090,18 @@ pub enum L1DataAvailabilityMode { #[derive(Debug, Clone, PartialEq, Eq)] pub struct L1HandlerTransaction { /// Transaction hash - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// Version of the transaction scheme - pub version: FieldElement, + pub version: Felt, /// The L1->L2 message nonce field of the sn core L1 contract at the time the transaction was /// sent pub nonce: u64, /// Contract address - pub contract_address: FieldElement, + pub contract_address: Felt, /// Entry point selector - pub entry_point_selector: FieldElement, + pub entry_point_selector: Felt, /// The parameters passed to the function - pub calldata: Vec, + pub calldata: Vec, } /// L1 handler transaction receipt. @@ -1112,7 +1112,7 @@ pub struct L1HandlerTransactionReceipt { /// The message hash as it appears on the L1 core contract pub message_hash: Hash256, /// The hash identifying the transaction - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The fee that was charged by the sequencer pub actual_fee: FeePayment, /// Finality status of the tx @@ -1148,7 +1148,7 @@ pub struct LegacyContractEntryPoint { pub offset: u64, /// A unique identifier of the entry point (function) in the program #[serde_as(as = "UfeHex")] - pub selector: FieldElement, + pub selector: Felt, } /// Deprecated entry points by type. @@ -1268,13 +1268,13 @@ pub struct MsgFromL1 { pub from_address: EthAddress, /// The target L2 address the message is sent to #[serde_as(as = "UfeHex")] - pub to_address: FieldElement, + pub to_address: Felt, /// The selector of the l1_handler in invoke in the target contract #[serde_as(as = "UfeHex")] - pub entry_point_selector: FieldElement, + pub entry_point_selector: Felt, /// The payload of the message #[serde_as(as = "Vec")] - pub payload: Vec, + pub payload: Vec, } /// Message to L1. @@ -1284,13 +1284,13 @@ pub struct MsgFromL1 { pub struct MsgToL1 { /// The address of the L2 contract sending the message #[serde_as(as = "UfeHex")] - pub from_address: FieldElement, + pub from_address: Felt, /// The target L1 address the message is sent to #[serde_as(as = "UfeHex")] - pub to_address: FieldElement, + pub to_address: Felt, /// The payload of the message #[serde_as(as = "Vec")] - pub payload: Vec, + pub payload: Vec, } /// Extra information on why trace is not available. Either it wasn't executed yet (received), or @@ -1310,10 +1310,10 @@ pub struct NoTraceAvailableErrorData { pub struct NonceUpdate { /// The address of the contract #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, /// The nonce for the given address at the end of the block #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, } /// Orderedevent. @@ -1327,10 +1327,10 @@ pub struct OrderedEvent { pub order: u64, /// Keys #[serde_as(as = "Vec")] - pub keys: Vec, + pub keys: Vec, /// Data #[serde_as(as = "Vec")] - pub data: Vec, + pub data: Vec, } /// Orderedmessage. @@ -1344,13 +1344,13 @@ pub struct OrderedMessage { pub order: u64, /// The address of the L2 contract sending the message #[serde_as(as = "UfeHex")] - pub from_address: FieldElement, + pub from_address: Felt, /// The target L1 address the message is sent to #[serde_as(as = "UfeHex")] - pub to_address: FieldElement, + pub to_address: Felt, /// The payload of the message #[serde_as(as = "Vec")] - pub payload: Vec, + pub payload: Vec, } /// Pending block with transactions and receipts. @@ -1365,12 +1365,12 @@ pub struct PendingBlockWithReceipts { pub transactions: Vec, /// The hash of this block's parent #[serde_as(as = "UfeHex")] - pub parent_hash: FieldElement, + pub parent_hash: Felt, /// The time in which the block was created, encoded in Unix time pub timestamp: u64, /// The Starknet identity of the sequencer submitting this block #[serde_as(as = "UfeHex")] - pub sequencer_address: FieldElement, + pub sequencer_address: Felt, /// The price of L1 gas in the block pub l1_gas_price: ResourcePrice, /// The price of L1 data gas in the block @@ -1391,15 +1391,15 @@ pub struct PendingBlockWithReceipts { pub struct PendingBlockWithTxHashes { /// The hashes of the transactions included in this block #[serde_as(as = "Vec")] - pub transactions: Vec, + pub transactions: Vec, /// The hash of this block's parent #[serde_as(as = "UfeHex")] - pub parent_hash: FieldElement, + pub parent_hash: Felt, /// The time in which the block was created, encoded in Unix time pub timestamp: u64, /// The Starknet identity of the sequencer submitting this block #[serde_as(as = "UfeHex")] - pub sequencer_address: FieldElement, + pub sequencer_address: Felt, /// The price of L1 gas in the block pub l1_gas_price: ResourcePrice, /// The price of L1 data gas in the block @@ -1422,12 +1422,12 @@ pub struct PendingBlockWithTxs { pub transactions: Vec, /// The hash of this block's parent #[serde_as(as = "UfeHex")] - pub parent_hash: FieldElement, + pub parent_hash: Felt, /// The time in which the block was created, encoded in Unix time pub timestamp: u64, /// The Starknet identity of the sequencer submitting this block #[serde_as(as = "UfeHex")] - pub sequencer_address: FieldElement, + pub sequencer_address: Felt, /// The price of L1 gas in the block pub l1_gas_price: ResourcePrice, /// The price of L1 data gas in the block @@ -1447,7 +1447,7 @@ pub struct PendingBlockWithTxs { pub struct PendingStateUpdate { /// The previous global state root #[serde_as(as = "UfeHex")] - pub old_root: FieldElement, + pub old_root: Felt, /// State diff pub state_diff: StateDiff, } @@ -1470,10 +1470,10 @@ pub enum PriceUnit { pub struct ReplacedClassItem { /// The address of the contract whose class was replaced #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, /// The new class hash #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } #[serde_as] @@ -1503,10 +1503,10 @@ pub struct ResourceBoundsMapping { pub struct ResourcePrice { /// The price of one unit of the given resource, denominated in fri (10^-18 strk) #[serde_as(as = "UfeHex")] - pub price_in_fri: FieldElement, + pub price_in_fri: Felt, /// The price of one unit of the given resource, denominated in wei #[serde_as(as = "UfeHex")] - pub price_in_wei: FieldElement, + pub price_in_wei: Felt, } /// Result page request. @@ -1551,7 +1551,7 @@ pub enum SequencerTransactionStatus { pub struct SierraEntryPoint { /// A unique identifier of the entry point (function) in the program #[serde_as(as = "UfeHex")] - pub selector: FieldElement, + pub selector: Felt, /// The index of the function in the program pub function_idx: u64, } @@ -1721,7 +1721,7 @@ pub struct StateDiff { pub storage_diffs: Vec, /// Deprecated declared classes #[serde_as(as = "Vec")] - pub deprecated_declared_classes: Vec, + pub deprecated_declared_classes: Vec, /// Declared classes pub declared_classes: Vec, /// Deployed contracts @@ -1739,13 +1739,13 @@ pub struct StateDiff { pub struct StateUpdate { /// Block hash #[serde_as(as = "UfeHex")] - pub block_hash: FieldElement, + pub block_hash: Felt, /// The previous global state root #[serde_as(as = "UfeHex")] - pub old_root: FieldElement, + pub old_root: Felt, /// The new global state root #[serde_as(as = "UfeHex")] - pub new_root: FieldElement, + pub new_root: Felt, /// State diff pub state_diff: StateDiff, } @@ -1757,10 +1757,10 @@ pub struct StateUpdate { pub struct StorageEntry { /// The key of the changed value #[serde_as(as = "UfeHex")] - pub key: FieldElement, + pub key: Felt, /// The new value applied to the given address #[serde_as(as = "UfeHex")] - pub value: FieldElement, + pub value: Felt, } /// Sync status. @@ -1772,17 +1772,17 @@ pub struct StorageEntry { pub struct SyncStatus { /// The hash of the block from which the sync started #[serde_as(as = "UfeHex")] - pub starting_block_hash: FieldElement, + pub starting_block_hash: Felt, /// The number (height) of the block from which the sync started pub starting_block_num: u64, /// The hash of the current block being synchronized #[serde_as(as = "UfeHex")] - pub current_block_hash: FieldElement, + pub current_block_hash: Felt, /// The number (height) of the current block being synchronized pub current_block_num: u64, /// The hash of the estimated highest block to be synchronized #[serde_as(as = "UfeHex")] - pub highest_block_hash: FieldElement, + pub highest_block_hash: Felt, /// The number (height) of the estimated highest block to be synchronized pub highest_block_num: u64, } @@ -1834,7 +1834,7 @@ pub struct TransactionReceiptWithBlockInfo { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct TransactionTraceWithHash { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub trace_root: TransactionTrace, } @@ -2009,14 +2009,14 @@ pub struct GetClassAtRequest { /// The hash of the requested block, or number (height) of the requested block, or a block tag pub block_id: BlockId, /// The address of the contract whose class definition will be returned - pub contract_address: FieldElement, + pub contract_address: Felt, } /// Reference version of [GetClassAtRequest]. #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetClassAtRequestRef<'a> { pub block_id: &'a BlockId, - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } /// Request for method starknet_getClassHashAt @@ -2025,14 +2025,14 @@ pub struct GetClassHashAtRequest { /// The hash of the requested block, or number (height) of the requested block, or a block tag pub block_id: BlockId, /// The address of the contract whose class hash will be returned - pub contract_address: FieldElement, + pub contract_address: Felt, } /// Reference version of [GetClassHashAtRequest]. #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetClassHashAtRequestRef<'a> { pub block_id: &'a BlockId, - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } /// Request for method starknet_getClass @@ -2041,14 +2041,14 @@ pub struct GetClassRequest { /// The hash of the requested block, or number (height) of the requested block, or a block tag pub block_id: BlockId, /// The hash of the requested contract class - pub class_hash: FieldElement, + pub class_hash: Felt, } /// Reference version of [GetClassRequest]. #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetClassRequestRef<'a> { pub block_id: &'a BlockId, - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, } /// Request for method starknet_getEvents @@ -2069,14 +2069,14 @@ pub struct GetNonceRequest { /// The hash of the requested block, or number (height) of the requested block, or a block tag pub block_id: BlockId, /// The address of the contract whose nonce we're seeking - pub contract_address: FieldElement, + pub contract_address: Felt, } /// Reference version of [GetNonceRequest]. #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetNonceRequestRef<'a> { pub block_id: &'a BlockId, - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } /// Request for method starknet_getStateUpdate @@ -2096,9 +2096,9 @@ pub struct GetStateUpdateRequestRef<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetStorageAtRequest { /// The address of the contract to read from - pub contract_address: FieldElement, + pub contract_address: Felt, /// The key to the storage value for the given contract - pub key: FieldElement, + pub key: Felt, /// The hash of the requested block, or number (height) of the requested block, or a block tag pub block_id: BlockId, } @@ -2106,8 +2106,8 @@ pub struct GetStorageAtRequest { /// Reference version of [GetStorageAtRequest]. #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetStorageAtRequestRef<'a> { - pub contract_address: &'a FieldElement, - pub key: &'a FieldElement, + pub contract_address: &'a Felt, + pub key: &'a Felt, pub block_id: &'a BlockId, } @@ -2129,37 +2129,37 @@ pub struct GetTransactionByBlockIdAndIndexRequestRef<'a> { /// Request for method starknet_getTransactionByHash #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetTransactionByHashRequest { - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } /// Reference version of [GetTransactionByHashRequest]. #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetTransactionByHashRequestRef<'a> { - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } /// Request for method starknet_getTransactionReceipt #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetTransactionReceiptRequest { - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } /// Reference version of [GetTransactionReceiptRequest]. #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetTransactionReceiptRequestRef<'a> { - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } /// Request for method starknet_getTransactionStatus #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetTransactionStatusRequest { - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } /// Reference version of [GetTransactionStatusRequest]. #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetTransactionStatusRequestRef<'a> { - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } /// Request for method starknet_simulateTransactions @@ -2206,13 +2206,13 @@ pub struct TraceBlockTransactionsRequestRef<'a> { /// Request for method starknet_traceTransaction #[derive(Debug, Clone, PartialEq, Eq)] pub struct TraceTransactionRequest { - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } /// Reference version of [TraceTransactionRequest]. #[derive(Debug, Clone, PartialEq, Eq)] pub struct TraceTransactionRequestRef<'a> { - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } impl Serialize for BroadcastedDeclareTransactionV1 { @@ -2222,24 +2222,24 @@ impl Serialize for BroadcastedDeclareTransactionV1 { struct Tagged<'a> { pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub sender_address: &'a FieldElement, + pub sender_address: &'a Felt, #[serde_as(as = "UfeHex")] - pub max_fee: &'a FieldElement, + pub max_fee: &'a Felt, #[serde_as(as = "UfeHex")] - pub version: &'a FieldElement, + pub version: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, pub contract_class: &'a CompressedLegacyContractClass, } let r#type = "DECLARE"; let version = &(if self.is_query { - FieldElement::ONE + QUERY_VERSION_OFFSET + Felt::ONE + QUERY_VERSION_OFFSET } else { - FieldElement::ONE + Felt::ONE }); let tagged = Tagged { @@ -2264,15 +2264,15 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV1 { struct Tagged { pub r#type: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "UfeHex")] - pub max_fee: FieldElement, + pub max_fee: Felt, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, pub contract_class: CompressedLegacyContractClass, } @@ -2284,9 +2284,9 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV1 { } } - let is_query = if tagged.version == FieldElement::ONE { + let is_query = if tagged.version == Felt::ONE { false - } else if tagged.version == FieldElement::ONE + QUERY_VERSION_OFFSET { + } else if tagged.version == Felt::ONE + QUERY_VERSION_OFFSET { true } else { return Err(serde::de::Error::custom("invalid `version` value")); @@ -2310,26 +2310,26 @@ impl Serialize for BroadcastedDeclareTransactionV2 { struct Tagged<'a> { pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub sender_address: &'a FieldElement, + pub sender_address: &'a Felt, #[serde_as(as = "UfeHex")] - pub compiled_class_hash: &'a FieldElement, + pub compiled_class_hash: &'a Felt, #[serde_as(as = "UfeHex")] - pub max_fee: &'a FieldElement, + pub max_fee: &'a Felt, #[serde_as(as = "UfeHex")] - pub version: &'a FieldElement, + pub version: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, pub contract_class: &'a FlattenedSierraClass, } let r#type = "DECLARE"; let version = &(if self.is_query { - FieldElement::TWO + QUERY_VERSION_OFFSET + Felt::TWO + QUERY_VERSION_OFFSET } else { - FieldElement::TWO + Felt::TWO }); let tagged = Tagged { @@ -2355,17 +2355,17 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV2 { struct Tagged { pub r#type: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "UfeHex")] - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, #[serde_as(as = "UfeHex")] - pub max_fee: FieldElement, + pub max_fee: Felt, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, pub contract_class: FlattenedSierraClass, } @@ -2377,9 +2377,9 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV2 { } } - let is_query = if tagged.version == FieldElement::TWO { + let is_query = if tagged.version == Felt::TWO { false - } else if tagged.version == FieldElement::TWO + QUERY_VERSION_OFFSET { + } else if tagged.version == Felt::TWO + QUERY_VERSION_OFFSET { true } else { return Err(serde::de::Error::custom("invalid `version` value")); @@ -2404,23 +2404,23 @@ impl Serialize for BroadcastedDeclareTransactionV3 { struct Tagged<'a> { pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub sender_address: &'a FieldElement, + pub sender_address: &'a Felt, #[serde_as(as = "UfeHex")] - pub compiled_class_hash: &'a FieldElement, + pub compiled_class_hash: &'a Felt, #[serde_as(as = "UfeHex")] - pub version: &'a FieldElement, + pub version: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, pub contract_class: &'a FlattenedSierraClass, pub resource_bounds: &'a ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: &'a u64, #[serde_as(as = "[UfeHex]")] - pub paymaster_data: &'a [FieldElement], + pub paymaster_data: &'a [Felt], #[serde_as(as = "[UfeHex]")] - pub account_deployment_data: &'a [FieldElement], + pub account_deployment_data: &'a [Felt], pub nonce_data_availability_mode: &'a DataAvailabilityMode, pub fee_data_availability_mode: &'a DataAvailabilityMode, } @@ -2428,9 +2428,9 @@ impl Serialize for BroadcastedDeclareTransactionV3 { let r#type = "DECLARE"; let version = &(if self.is_query { - FieldElement::THREE + QUERY_VERSION_OFFSET + Felt::THREE + QUERY_VERSION_OFFSET } else { - FieldElement::THREE + Felt::THREE }); let tagged = Tagged { @@ -2461,23 +2461,23 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV3 { struct Tagged { pub r#type: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "UfeHex")] - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, pub contract_class: FlattenedSierraClass, pub resource_bounds: ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: u64, #[serde_as(as = "Vec")] - pub paymaster_data: Vec, + pub paymaster_data: Vec, #[serde_as(as = "Vec")] - pub account_deployment_data: Vec, + pub account_deployment_data: Vec, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, } @@ -2490,9 +2490,9 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV3 { } } - let is_query = if tagged.version == FieldElement::THREE { + let is_query = if tagged.version == Felt::THREE { false - } else if tagged.version == FieldElement::THREE + QUERY_VERSION_OFFSET { + } else if tagged.version == Felt::THREE + QUERY_VERSION_OFFSET { true } else { return Err(serde::de::Error::custom("invalid `version` value")); @@ -2522,27 +2522,27 @@ impl Serialize for BroadcastedDeployAccountTransactionV1 { struct Tagged<'a> { pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub max_fee: &'a FieldElement, + pub max_fee: &'a Felt, #[serde_as(as = "UfeHex")] - pub version: &'a FieldElement, + pub version: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, #[serde_as(as = "UfeHex")] - pub contract_address_salt: &'a FieldElement, + pub contract_address_salt: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub constructor_calldata: &'a [FieldElement], + pub constructor_calldata: &'a [Felt], #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, } let r#type = "DEPLOY_ACCOUNT"; let version = &(if self.is_query { - FieldElement::ONE + QUERY_VERSION_OFFSET + Felt::ONE + QUERY_VERSION_OFFSET } else { - FieldElement::ONE + Felt::ONE }); let tagged = Tagged { @@ -2568,19 +2568,19 @@ impl<'de> Deserialize<'de> for BroadcastedDeployAccountTransactionV1 { struct Tagged { pub r#type: Option, #[serde_as(as = "UfeHex")] - pub max_fee: FieldElement, + pub max_fee: Felt, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, #[serde_as(as = "UfeHex")] - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, #[serde_as(as = "Vec")] - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } let tagged = Tagged::deserialize(deserializer)?; @@ -2591,9 +2591,9 @@ impl<'de> Deserialize<'de> for BroadcastedDeployAccountTransactionV1 { } } - let is_query = if tagged.version == FieldElement::ONE { + let is_query = if tagged.version == Felt::ONE { false - } else if tagged.version == FieldElement::ONE + QUERY_VERSION_OFFSET { + } else if tagged.version == Felt::ONE + QUERY_VERSION_OFFSET { true } else { return Err(serde::de::Error::custom("invalid `version` value")); @@ -2618,22 +2618,22 @@ impl Serialize for BroadcastedDeployAccountTransactionV3 { struct Tagged<'a> { pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub version: &'a FieldElement, + pub version: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, #[serde_as(as = "UfeHex")] - pub contract_address_salt: &'a FieldElement, + pub contract_address_salt: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub constructor_calldata: &'a [FieldElement], + pub constructor_calldata: &'a [Felt], #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, pub resource_bounds: &'a ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: &'a u64, #[serde_as(as = "[UfeHex]")] - pub paymaster_data: &'a [FieldElement], + pub paymaster_data: &'a [Felt], pub nonce_data_availability_mode: &'a DataAvailabilityMode, pub fee_data_availability_mode: &'a DataAvailabilityMode, } @@ -2641,9 +2641,9 @@ impl Serialize for BroadcastedDeployAccountTransactionV3 { let r#type = "DEPLOY_ACCOUNT"; let version = &(if self.is_query { - FieldElement::THREE + QUERY_VERSION_OFFSET + Felt::THREE + QUERY_VERSION_OFFSET } else { - FieldElement::THREE + Felt::THREE }); let tagged = Tagged { @@ -2673,22 +2673,22 @@ impl<'de> Deserialize<'de> for BroadcastedDeployAccountTransactionV3 { struct Tagged { pub r#type: Option, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, #[serde_as(as = "UfeHex")] - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, #[serde_as(as = "Vec")] - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, pub resource_bounds: ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: u64, #[serde_as(as = "Vec")] - pub paymaster_data: Vec, + pub paymaster_data: Vec, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, } @@ -2701,9 +2701,9 @@ impl<'de> Deserialize<'de> for BroadcastedDeployAccountTransactionV3 { } } - let is_query = if tagged.version == FieldElement::THREE { + let is_query = if tagged.version == Felt::THREE { false - } else if tagged.version == FieldElement::THREE + QUERY_VERSION_OFFSET { + } else if tagged.version == Felt::THREE + QUERY_VERSION_OFFSET { true } else { return Err(serde::de::Error::custom("invalid `version` value")); @@ -2732,25 +2732,25 @@ impl Serialize for BroadcastedInvokeTransactionV1 { struct Tagged<'a> { pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub sender_address: &'a FieldElement, + pub sender_address: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub calldata: &'a [FieldElement], + pub calldata: &'a [Felt], #[serde_as(as = "UfeHex")] - pub max_fee: &'a FieldElement, + pub max_fee: &'a Felt, #[serde_as(as = "UfeHex")] - pub version: &'a FieldElement, + pub version: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, } let r#type = "INVOKE"; let version = &(if self.is_query { - FieldElement::ONE + QUERY_VERSION_OFFSET + Felt::ONE + QUERY_VERSION_OFFSET } else { - FieldElement::ONE + Felt::ONE }); let tagged = Tagged { @@ -2775,17 +2775,17 @@ impl<'de> Deserialize<'de> for BroadcastedInvokeTransactionV1 { struct Tagged { pub r#type: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "Vec")] - pub calldata: Vec, + pub calldata: Vec, #[serde_as(as = "UfeHex")] - pub max_fee: FieldElement, + pub max_fee: Felt, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, } let tagged = Tagged::deserialize(deserializer)?; @@ -2796,9 +2796,9 @@ impl<'de> Deserialize<'de> for BroadcastedInvokeTransactionV1 { } } - let is_query = if tagged.version == FieldElement::ONE { + let is_query = if tagged.version == Felt::ONE { false - } else if tagged.version == FieldElement::ONE + QUERY_VERSION_OFFSET { + } else if tagged.version == Felt::ONE + QUERY_VERSION_OFFSET { true } else { return Err(serde::de::Error::custom("invalid `version` value")); @@ -2822,22 +2822,22 @@ impl Serialize for BroadcastedInvokeTransactionV3 { struct Tagged<'a> { pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub sender_address: &'a FieldElement, + pub sender_address: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub calldata: &'a [FieldElement], + pub calldata: &'a [Felt], #[serde_as(as = "UfeHex")] - pub version: &'a FieldElement, + pub version: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, pub resource_bounds: &'a ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: &'a u64, #[serde_as(as = "[UfeHex]")] - pub paymaster_data: &'a [FieldElement], + pub paymaster_data: &'a [Felt], #[serde_as(as = "[UfeHex]")] - pub account_deployment_data: &'a [FieldElement], + pub account_deployment_data: &'a [Felt], pub nonce_data_availability_mode: &'a DataAvailabilityMode, pub fee_data_availability_mode: &'a DataAvailabilityMode, } @@ -2845,9 +2845,9 @@ impl Serialize for BroadcastedInvokeTransactionV3 { let r#type = "INVOKE"; let version = &(if self.is_query { - FieldElement::THREE + QUERY_VERSION_OFFSET + Felt::THREE + QUERY_VERSION_OFFSET } else { - FieldElement::THREE + Felt::THREE }); let tagged = Tagged { @@ -2877,22 +2877,22 @@ impl<'de> Deserialize<'de> for BroadcastedInvokeTransactionV3 { struct Tagged { pub r#type: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "Vec")] - pub calldata: Vec, + pub calldata: Vec, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, pub resource_bounds: ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: u64, #[serde_as(as = "Vec")] - pub paymaster_data: Vec, + pub paymaster_data: Vec, #[serde_as(as = "Vec")] - pub account_deployment_data: Vec, + pub account_deployment_data: Vec, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, } @@ -2905,9 +2905,9 @@ impl<'de> Deserialize<'de> for BroadcastedInvokeTransactionV3 { } } - let is_query = if tagged.version == FieldElement::THREE { + let is_query = if tagged.version == Felt::THREE { false - } else if tagged.version == FieldElement::THREE + QUERY_VERSION_OFFSET { + } else if tagged.version == Felt::THREE + QUERY_VERSION_OFFSET { true } else { return Err(serde::de::Error::custom("invalid `version` value")); @@ -2936,7 +2936,7 @@ impl Serialize for DeclareTransactionReceipt { struct Tagged<'a> { pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub actual_fee: &'a FeePayment, pub finality_status: &'a TransactionFinalityStatus, pub messages_sent: &'a [MsgToL1], @@ -2970,7 +2970,7 @@ impl<'de> Deserialize<'de> for DeclareTransactionReceipt { struct Tagged { pub r#type: Option, #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub actual_fee: FeePayment, pub finality_status: TransactionFinalityStatus, pub messages_sent: Vec, @@ -3066,18 +3066,18 @@ impl Serialize for DeclareTransactionV0 { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub sender_address: &'a FieldElement, + pub sender_address: &'a Felt, #[serde_as(as = "UfeHex")] - pub max_fee: &'a FieldElement, + pub max_fee: &'a Felt, #[serde_as(as = "NumAsHex")] pub version: &'a u64, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, } let r#type = "DECLARE"; @@ -3105,18 +3105,18 @@ impl<'de> Deserialize<'de> for DeclareTransactionV0 { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "UfeHex")] - pub max_fee: FieldElement, + pub max_fee: Felt, #[serde_as(as = "Option")] pub version: Option, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } let tagged = Tagged::deserialize(deserializer)?; @@ -3149,20 +3149,20 @@ impl Serialize for DeclareTransactionV1 { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub sender_address: &'a FieldElement, + pub sender_address: &'a Felt, #[serde_as(as = "UfeHex")] - pub max_fee: &'a FieldElement, + pub max_fee: &'a Felt, #[serde_as(as = "NumAsHex")] pub version: &'a u64, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, } let r#type = "DECLARE"; @@ -3191,20 +3191,20 @@ impl<'de> Deserialize<'de> for DeclareTransactionV1 { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "UfeHex")] - pub max_fee: FieldElement, + pub max_fee: Felt, #[serde_as(as = "Option")] pub version: Option, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } let tagged = Tagged::deserialize(deserializer)?; @@ -3238,22 +3238,22 @@ impl Serialize for DeclareTransactionV2 { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub sender_address: &'a FieldElement, + pub sender_address: &'a Felt, #[serde_as(as = "UfeHex")] - pub compiled_class_hash: &'a FieldElement, + pub compiled_class_hash: &'a Felt, #[serde_as(as = "UfeHex")] - pub max_fee: &'a FieldElement, + pub max_fee: &'a Felt, #[serde_as(as = "NumAsHex")] pub version: &'a u64, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, } let r#type = "DECLARE"; @@ -3283,22 +3283,22 @@ impl<'de> Deserialize<'de> for DeclareTransactionV2 { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "UfeHex")] - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, #[serde_as(as = "UfeHex")] - pub max_fee: FieldElement, + pub max_fee: Felt, #[serde_as(as = "Option")] pub version: Option, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } let tagged = Tagged::deserialize(deserializer)?; @@ -3333,27 +3333,27 @@ impl Serialize for DeclareTransactionV3 { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub sender_address: &'a FieldElement, + pub sender_address: &'a Felt, #[serde_as(as = "UfeHex")] - pub compiled_class_hash: &'a FieldElement, + pub compiled_class_hash: &'a Felt, #[serde_as(as = "NumAsHex")] pub version: &'a u64, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, pub resource_bounds: &'a ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: &'a u64, #[serde_as(as = "[UfeHex]")] - pub paymaster_data: &'a [FieldElement], + pub paymaster_data: &'a [Felt], #[serde_as(as = "[UfeHex]")] - pub account_deployment_data: &'a [FieldElement], + pub account_deployment_data: &'a [Felt], pub nonce_data_availability_mode: &'a DataAvailabilityMode, pub fee_data_availability_mode: &'a DataAvailabilityMode, } @@ -3390,27 +3390,27 @@ impl<'de> Deserialize<'de> for DeclareTransactionV3 { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "UfeHex")] - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, #[serde_as(as = "Option")] pub version: Option, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, pub resource_bounds: ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: u64, #[serde_as(as = "Vec")] - pub paymaster_data: Vec, + pub paymaster_data: Vec, #[serde_as(as = "Vec")] - pub account_deployment_data: Vec, + pub account_deployment_data: Vec, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, } @@ -3452,7 +3452,7 @@ impl Serialize for DeployAccountTransactionReceipt { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub actual_fee: &'a FeePayment, pub finality_status: &'a TransactionFinalityStatus, pub messages_sent: &'a [MsgToL1], @@ -3462,7 +3462,7 @@ impl Serialize for DeployAccountTransactionReceipt { pub execution_result: &'a ExecutionResult, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } let r#type = "DEPLOY_ACCOUNT"; @@ -3489,7 +3489,7 @@ impl<'de> Deserialize<'de> for DeployAccountTransactionReceipt { #[derive(Deserialize)] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub actual_fee: FeePayment, pub finality_status: TransactionFinalityStatus, pub messages_sent: Vec, @@ -3499,7 +3499,7 @@ impl<'de> Deserialize<'de> for DeployAccountTransactionReceipt { pub execution_result: ExecutionResult, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, } let tagged = Tagged::deserialize(deserializer)?; @@ -3593,22 +3593,22 @@ impl Serialize for DeployAccountTransactionV1 { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub max_fee: &'a FieldElement, + pub max_fee: &'a Felt, #[serde_as(as = "NumAsHex")] pub version: &'a u64, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, #[serde_as(as = "UfeHex")] - pub contract_address_salt: &'a FieldElement, + pub contract_address_salt: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub constructor_calldata: &'a [FieldElement], + pub constructor_calldata: &'a [Felt], #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, } let r#type = "DEPLOY_ACCOUNT"; @@ -3638,22 +3638,22 @@ impl<'de> Deserialize<'de> for DeployAccountTransactionV1 { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub max_fee: FieldElement, + pub max_fee: Felt, #[serde_as(as = "Option")] pub version: Option, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, #[serde_as(as = "UfeHex")] - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, #[serde_as(as = "Vec")] - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } let tagged = Tagged::deserialize(deserializer)?; @@ -3688,25 +3688,25 @@ impl Serialize for DeployAccountTransactionV3 { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub r#type: &'a str, #[serde_as(as = "NumAsHex")] pub version: &'a u64, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, #[serde_as(as = "UfeHex")] - pub contract_address_salt: &'a FieldElement, + pub contract_address_salt: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub constructor_calldata: &'a [FieldElement], + pub constructor_calldata: &'a [Felt], #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, pub resource_bounds: &'a ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: &'a u64, #[serde_as(as = "[UfeHex]")] - pub paymaster_data: &'a [FieldElement], + pub paymaster_data: &'a [Felt], pub nonce_data_availability_mode: &'a DataAvailabilityMode, pub fee_data_availability_mode: &'a DataAvailabilityMode, } @@ -3742,25 +3742,25 @@ impl<'de> Deserialize<'de> for DeployAccountTransactionV3 { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub r#type: Option, #[serde_as(as = "Option")] pub version: Option, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, #[serde_as(as = "UfeHex")] - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, #[serde_as(as = "Vec")] - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, pub resource_bounds: ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: u64, #[serde_as(as = "Vec")] - pub paymaster_data: Vec, + pub paymaster_data: Vec, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, } @@ -3801,16 +3801,16 @@ impl Serialize for DeployTransaction { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, #[serde_as(as = "UfeHex")] - pub version: &'a FieldElement, + pub version: &'a Felt, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub contract_address_salt: &'a FieldElement, + pub contract_address_salt: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub constructor_calldata: &'a [FieldElement], + pub constructor_calldata: &'a [Felt], #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, } let r#type = "DEPLOY"; @@ -3835,16 +3835,16 @@ impl<'de> Deserialize<'de> for DeployTransaction { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, #[serde_as(as = "Vec")] - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } let tagged = Tagged::deserialize(deserializer)?; @@ -3871,7 +3871,7 @@ impl Serialize for DeployTransactionReceipt { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub actual_fee: &'a FeePayment, pub finality_status: &'a TransactionFinalityStatus, pub messages_sent: &'a [MsgToL1], @@ -3881,7 +3881,7 @@ impl Serialize for DeployTransactionReceipt { pub execution_result: &'a ExecutionResult, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } let r#type = "DEPLOY"; @@ -3908,7 +3908,7 @@ impl<'de> Deserialize<'de> for DeployTransactionReceipt { #[derive(Deserialize)] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub actual_fee: FeePayment, pub finality_status: TransactionFinalityStatus, pub messages_sent: Vec, @@ -3918,7 +3918,7 @@ impl<'de> Deserialize<'de> for DeployTransactionReceipt { pub execution_result: ExecutionResult, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, } let tagged = Tagged::deserialize(deserializer)?; @@ -3949,7 +3949,7 @@ impl Serialize for InvokeTransactionReceipt { struct Tagged<'a> { pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub actual_fee: &'a FeePayment, pub finality_status: &'a TransactionFinalityStatus, pub messages_sent: &'a [MsgToL1], @@ -3983,7 +3983,7 @@ impl<'de> Deserialize<'de> for InvokeTransactionReceipt { struct Tagged { pub r#type: Option, #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub actual_fee: FeePayment, pub finality_status: TransactionFinalityStatus, pub messages_sent: Vec, @@ -4083,20 +4083,20 @@ impl Serialize for InvokeTransactionV0 { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub max_fee: &'a FieldElement, + pub max_fee: &'a Felt, #[serde_as(as = "NumAsHex")] pub version: &'a u64, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, #[serde_as(as = "UfeHex")] - pub entry_point_selector: &'a FieldElement, + pub entry_point_selector: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub calldata: &'a [FieldElement], + pub calldata: &'a [Felt], } let r#type = "INVOKE"; @@ -4125,20 +4125,20 @@ impl<'de> Deserialize<'de> for InvokeTransactionV0 { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub max_fee: FieldElement, + pub max_fee: Felt, #[serde_as(as = "Option")] pub version: Option, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, #[serde_as(as = "UfeHex")] - pub entry_point_selector: FieldElement, + pub entry_point_selector: Felt, #[serde_as(as = "Vec")] - pub calldata: Vec, + pub calldata: Vec, } let tagged = Tagged::deserialize(deserializer)?; @@ -4172,20 +4172,20 @@ impl Serialize for InvokeTransactionV1 { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub sender_address: &'a FieldElement, + pub sender_address: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub calldata: &'a [FieldElement], + pub calldata: &'a [Felt], #[serde_as(as = "UfeHex")] - pub max_fee: &'a FieldElement, + pub max_fee: &'a Felt, #[serde_as(as = "NumAsHex")] pub version: &'a u64, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, } let r#type = "INVOKE"; @@ -4214,20 +4214,20 @@ impl<'de> Deserialize<'de> for InvokeTransactionV1 { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "Vec")] - pub calldata: Vec, + pub calldata: Vec, #[serde_as(as = "UfeHex")] - pub max_fee: FieldElement, + pub max_fee: Felt, #[serde_as(as = "Option")] pub version: Option, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, } let tagged = Tagged::deserialize(deserializer)?; @@ -4261,25 +4261,25 @@ impl Serialize for InvokeTransactionV3 { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub sender_address: &'a FieldElement, + pub sender_address: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub calldata: &'a [FieldElement], + pub calldata: &'a [Felt], #[serde_as(as = "NumAsHex")] pub version: &'a u64, #[serde_as(as = "[UfeHex]")] - pub signature: &'a [FieldElement], + pub signature: &'a [Felt], #[serde_as(as = "UfeHex")] - pub nonce: &'a FieldElement, + pub nonce: &'a Felt, pub resource_bounds: &'a ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: &'a u64, #[serde_as(as = "[UfeHex]")] - pub paymaster_data: &'a [FieldElement], + pub paymaster_data: &'a [Felt], #[serde_as(as = "[UfeHex]")] - pub account_deployment_data: &'a [FieldElement], + pub account_deployment_data: &'a [Felt], pub nonce_data_availability_mode: &'a DataAvailabilityMode, pub fee_data_availability_mode: &'a DataAvailabilityMode, } @@ -4315,25 +4315,25 @@ impl<'de> Deserialize<'de> for InvokeTransactionV3 { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "Vec")] - pub calldata: Vec, + pub calldata: Vec, #[serde_as(as = "Option")] pub version: Option, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, pub resource_bounds: ResourceBoundsMapping, #[serde_as(as = "NumAsHex")] pub tip: u64, #[serde_as(as = "Vec")] - pub paymaster_data: Vec, + pub paymaster_data: Vec, #[serde_as(as = "Vec")] - pub account_deployment_data: Vec, + pub account_deployment_data: Vec, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, } @@ -4374,18 +4374,18 @@ impl Serialize for L1HandlerTransaction { #[derive(Serialize)] struct Tagged<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, #[serde_as(as = "UfeHex")] - pub version: &'a FieldElement, + pub version: &'a Felt, pub r#type: &'a str, #[serde_as(as = "NumAsHex")] pub nonce: &'a u64, #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, #[serde_as(as = "UfeHex")] - pub entry_point_selector: &'a FieldElement, + pub entry_point_selector: &'a Felt, #[serde_as(as = "[UfeHex]")] - pub calldata: &'a [FieldElement], + pub calldata: &'a [Felt], } let r#type = "L1_HANDLER"; @@ -4411,18 +4411,18 @@ impl<'de> Deserialize<'de> for L1HandlerTransaction { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, pub r#type: Option, #[serde_as(as = "NumAsHex")] pub nonce: u64, #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, #[serde_as(as = "UfeHex")] - pub entry_point_selector: FieldElement, + pub entry_point_selector: Felt, #[serde_as(as = "Vec")] - pub calldata: Vec, + pub calldata: Vec, } let tagged = Tagged::deserialize(deserializer)?; @@ -4452,7 +4452,7 @@ impl Serialize for L1HandlerTransactionReceipt { pub r#type: &'a str, pub message_hash: &'a Hash256, #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, pub actual_fee: &'a FeePayment, pub finality_status: &'a TransactionFinalityStatus, pub messages_sent: &'a [MsgToL1], @@ -4488,7 +4488,7 @@ impl<'de> Deserialize<'de> for L1HandlerTransactionReceipt { pub r#type: Option, pub message_hash: Hash256, #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub actual_fee: FeePayment, pub finality_status: TransactionFinalityStatus, pub messages_sent: Vec, @@ -5543,7 +5543,7 @@ impl Serialize for GetClassAtRequest { #[serde(transparent)] struct Field1<'a> { #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } use serde::ser::SerializeSeq; @@ -5574,7 +5574,7 @@ impl<'a> Serialize for GetClassAtRequestRef<'a> { #[serde(transparent)] struct Field1<'a> { #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } use serde::ser::SerializeSeq; @@ -5599,7 +5599,7 @@ impl<'de> Deserialize<'de> for GetClassAtRequest { struct AsObject { pub block_id: BlockId, #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, } #[derive(Deserialize)] @@ -5613,7 +5613,7 @@ impl<'de> Deserialize<'de> for GetClassAtRequest { #[serde(transparent)] struct Field1 { #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, } let temp = serde_json::Value::deserialize(deserializer)?; @@ -5660,7 +5660,7 @@ impl Serialize for GetClassHashAtRequest { #[serde(transparent)] struct Field1<'a> { #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } use serde::ser::SerializeSeq; @@ -5691,7 +5691,7 @@ impl<'a> Serialize for GetClassHashAtRequestRef<'a> { #[serde(transparent)] struct Field1<'a> { #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } use serde::ser::SerializeSeq; @@ -5716,7 +5716,7 @@ impl<'de> Deserialize<'de> for GetClassHashAtRequest { struct AsObject { pub block_id: BlockId, #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, } #[derive(Deserialize)] @@ -5730,7 +5730,7 @@ impl<'de> Deserialize<'de> for GetClassHashAtRequest { #[serde(transparent)] struct Field1 { #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, } let temp = serde_json::Value::deserialize(deserializer)?; @@ -5777,7 +5777,7 @@ impl Serialize for GetClassRequest { #[serde(transparent)] struct Field1<'a> { #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, } use serde::ser::SerializeSeq; @@ -5808,7 +5808,7 @@ impl<'a> Serialize for GetClassRequestRef<'a> { #[serde(transparent)] struct Field1<'a> { #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, + pub class_hash: &'a Felt, } use serde::ser::SerializeSeq; @@ -5833,7 +5833,7 @@ impl<'de> Deserialize<'de> for GetClassRequest { struct AsObject { pub block_id: BlockId, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } #[derive(Deserialize)] @@ -5847,7 +5847,7 @@ impl<'de> Deserialize<'de> for GetClassRequest { #[serde(transparent)] struct Field1 { #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } let temp = serde_json::Value::deserialize(deserializer)?; @@ -5971,7 +5971,7 @@ impl Serialize for GetNonceRequest { #[serde(transparent)] struct Field1<'a> { #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } use serde::ser::SerializeSeq; @@ -6002,7 +6002,7 @@ impl<'a> Serialize for GetNonceRequestRef<'a> { #[serde(transparent)] struct Field1<'a> { #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } use serde::ser::SerializeSeq; @@ -6027,7 +6027,7 @@ impl<'de> Deserialize<'de> for GetNonceRequest { struct AsObject { pub block_id: BlockId, #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, } #[derive(Deserialize)] @@ -6041,7 +6041,7 @@ impl<'de> Deserialize<'de> for GetNonceRequest { #[serde(transparent)] struct Field1 { #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, } let temp = serde_json::Value::deserialize(deserializer)?; @@ -6159,7 +6159,7 @@ impl Serialize for GetStorageAtRequest { #[serde(transparent)] struct Field0<'a> { #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } #[serde_as] @@ -6167,7 +6167,7 @@ impl Serialize for GetStorageAtRequest { #[serde(transparent)] struct Field1<'a> { #[serde_as(as = "UfeHex")] - pub key: &'a FieldElement, + pub key: &'a Felt, } #[derive(Serialize)] @@ -6199,7 +6199,7 @@ impl<'a> Serialize for GetStorageAtRequestRef<'a> { #[serde(transparent)] struct Field0<'a> { #[serde_as(as = "UfeHex")] - pub contract_address: &'a FieldElement, + pub contract_address: &'a Felt, } #[serde_as] @@ -6207,7 +6207,7 @@ impl<'a> Serialize for GetStorageAtRequestRef<'a> { #[serde(transparent)] struct Field1<'a> { #[serde_as(as = "UfeHex")] - pub key: &'a FieldElement, + pub key: &'a Felt, } #[derive(Serialize)] @@ -6238,9 +6238,9 @@ impl<'de> Deserialize<'de> for GetStorageAtRequest { #[derive(Deserialize)] struct AsObject { #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, #[serde_as(as = "UfeHex")] - pub key: FieldElement, + pub key: Felt, pub block_id: BlockId, } @@ -6249,7 +6249,7 @@ impl<'de> Deserialize<'de> for GetStorageAtRequest { #[serde(transparent)] struct Field0 { #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, } #[serde_as] @@ -6257,7 +6257,7 @@ impl<'de> Deserialize<'de> for GetStorageAtRequest { #[serde(transparent)] struct Field1 { #[serde_as(as = "UfeHex")] - pub key: FieldElement, + pub key: Felt, } #[derive(Deserialize)] @@ -6418,7 +6418,7 @@ impl Serialize for GetTransactionByHashRequest { #[serde(transparent)] struct Field0<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } use serde::ser::SerializeSeq; @@ -6440,7 +6440,7 @@ impl<'a> Serialize for GetTransactionByHashRequestRef<'a> { #[serde(transparent)] struct Field0<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } use serde::ser::SerializeSeq; @@ -6461,7 +6461,7 @@ impl<'de> Deserialize<'de> for GetTransactionByHashRequest { #[derive(Deserialize)] struct AsObject { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } #[serde_as] @@ -6469,7 +6469,7 @@ impl<'de> Deserialize<'de> for GetTransactionByHashRequest { #[serde(transparent)] struct Field0 { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } let temp = serde_json::Value::deserialize(deserializer)?; @@ -6502,7 +6502,7 @@ impl Serialize for GetTransactionReceiptRequest { #[serde(transparent)] struct Field0<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } use serde::ser::SerializeSeq; @@ -6524,7 +6524,7 @@ impl<'a> Serialize for GetTransactionReceiptRequestRef<'a> { #[serde(transparent)] struct Field0<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } use serde::ser::SerializeSeq; @@ -6545,7 +6545,7 @@ impl<'de> Deserialize<'de> for GetTransactionReceiptRequest { #[derive(Deserialize)] struct AsObject { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } #[serde_as] @@ -6553,7 +6553,7 @@ impl<'de> Deserialize<'de> for GetTransactionReceiptRequest { #[serde(transparent)] struct Field0 { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } let temp = serde_json::Value::deserialize(deserializer)?; @@ -6586,7 +6586,7 @@ impl Serialize for GetTransactionStatusRequest { #[serde(transparent)] struct Field0<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } use serde::ser::SerializeSeq; @@ -6608,7 +6608,7 @@ impl<'a> Serialize for GetTransactionStatusRequestRef<'a> { #[serde(transparent)] struct Field0<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } use serde::ser::SerializeSeq; @@ -6629,7 +6629,7 @@ impl<'de> Deserialize<'de> for GetTransactionStatusRequest { #[derive(Deserialize)] struct AsObject { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } #[serde_as] @@ -6637,7 +6637,7 @@ impl<'de> Deserialize<'de> for GetTransactionStatusRequest { #[serde(transparent)] struct Field0 { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } let temp = serde_json::Value::deserialize(deserializer)?; @@ -6928,7 +6928,7 @@ impl Serialize for TraceTransactionRequest { #[serde(transparent)] struct Field0<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } use serde::ser::SerializeSeq; @@ -6950,7 +6950,7 @@ impl<'a> Serialize for TraceTransactionRequestRef<'a> { #[serde(transparent)] struct Field0<'a> { #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, + pub transaction_hash: &'a Felt, } use serde::ser::SerializeSeq; @@ -6971,7 +6971,7 @@ impl<'de> Deserialize<'de> for TraceTransactionRequest { #[derive(Deserialize)] struct AsObject { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } #[serde_as] @@ -6979,7 +6979,7 @@ impl<'de> Deserialize<'de> for TraceTransactionRequest { #[serde(transparent)] struct Field0 { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } let temp = serde_json::Value::deserialize(deserializer)?; diff --git a/starknet-core/src/types/contract/legacy.rs b/starknet-core/src/types/contract/legacy.rs index 6b3eb797..56cab605 100644 --- a/starknet-core/src/types/contract/legacy.rs +++ b/starknet-core/src/types/contract/legacy.rs @@ -5,7 +5,7 @@ use crate::{ serde::{num_hex::u64 as u64_hex, unsigned_field_element::UfeHex}, types::{ contract::{ComputeClassHashError, JsonError}, - FieldElement, FunctionStateMutability, LegacyContractAbiEntry, LegacyContractEntryPoint, + Felt, FunctionStateMutability, LegacyContractAbiEntry, LegacyContractEntryPoint, LegacyEntryPointsByType, LegacyEventAbiEntry, LegacyEventAbiType, LegacyFunctionAbiEntry, LegacyFunctionAbiType, LegacyStructAbiEntry, LegacyStructAbiType, LegacyStructMember, LegacyTypedParameter, @@ -24,7 +24,7 @@ use crate::types::{contract::CompressProgramError, CompressedLegacyContractClass #[cfg(feature = "std")] use flate2::{write::GzEncoder, Compression}; -const API_VERSION: FieldElement = FieldElement::ZERO; +const API_VERSION: Felt = Felt::ZERO; #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] @@ -55,12 +55,12 @@ pub struct LegacyProgram { #[serde(skip_serializing_if = "Option::is_none")] pub compiler_version: Option, #[serde_as(as = "Vec")] - pub data: Vec, + pub data: Vec, pub debug_info: Option, pub hints: BTreeMap>, pub identifiers: BTreeMap, pub main_scope: String, - // Impossible to use [FieldElement] here as by definition field elements are smaller + // Impossible to use [Felt] here as by definition field elements are smaller // than prime pub prime: String, pub reference_manager: LegacyReferenceManager, @@ -72,7 +72,7 @@ pub struct LegacyProgram { pub struct RawLegacyEntryPoint { pub offset: LegacyEntrypointOffset, #[serde_as(as = "UfeHex")] - pub selector: FieldElement, + pub selector: Felt, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -280,17 +280,19 @@ struct AttributeForHintedHash; impl From for u64 { fn from(value: LegacyEntrypointOffset) -> Self { match value { - LegacyEntrypointOffset::U64AsHex(inner) => inner, - LegacyEntrypointOffset::U64AsInt(inner) => inner, + LegacyEntrypointOffset::U64AsHex(inner) | LegacyEntrypointOffset::U64AsInt(inner) => { + inner + } } } } -impl From for FieldElement { +impl From for Felt { fn from(value: LegacyEntrypointOffset) -> Self { match value { - LegacyEntrypointOffset::U64AsHex(inner) => inner.into(), - LegacyEntrypointOffset::U64AsInt(inner) => inner.into(), + LegacyEntrypointOffset::U64AsHex(inner) | LegacyEntrypointOffset::U64AsInt(inner) => { + inner.into() + } } } } @@ -392,7 +394,7 @@ impl<'de> Deserialize<'de> for RawLegacyAbiEntry { } impl LegacyContractClass { - pub fn class_hash(&self) -> Result { + pub fn class_hash(&self) -> Result { let mut elements = Vec::new(); elements.push(API_VERSION); @@ -447,7 +449,7 @@ impl LegacyContractClass { Ok(compute_hash_on_elements(&elements)) } - pub fn hinted_class_hash(&self) -> Result { + pub fn hinted_class_hash(&self) -> Result { #[serde_as] #[derive(Serialize)] struct ContractArtifactForHash<'a> { @@ -499,7 +501,7 @@ impl LegacyProgram { #[serde(skip_serializing_if = "Option::is_none")] compiler_version: &'a Option, #[serde_as(as = "Vec")] - data: &'a Vec, + data: &'a Vec, // Needed due to pathfinder bug: // https://github.com/eqlabs/pathfinder/issues/1371 debug_info: EmptyDebugInfo, @@ -609,7 +611,7 @@ impl SerializeAs for ProgramForHintedHash { #[serde(skip_serializing_if = "Option::is_none")] compiler_version: &'a Option, #[serde_as(as = "Vec")] - data: &'a Vec, + data: &'a Vec, debug_info: &'a Option, hints: &'a BTreeMap>, identifiers: &'a BTreeMap, @@ -911,7 +913,7 @@ mod tests { let computed_hash = artifact.class_hash().unwrap(); let hashes: ContractHashes = serde_json::from_str(raw_hashes).unwrap(); - let expected_hash = FieldElement::from_hex_be(&hashes.class_hash).unwrap(); + let expected_hash = Felt::from_hex(&hashes.class_hash).unwrap(); assert_eq!(computed_hash, expected_hash); } @@ -956,7 +958,7 @@ mod tests { let computed_hash = artifact.hinted_class_hash().unwrap(); let hashes: ContractHashes = serde_json::from_str(raw_hashes).unwrap(); - let expected_hash = FieldElement::from_hex_be(&hashes.hinted_class_hash).unwrap(); + let expected_hash = Felt::from_hex(&hashes.hinted_class_hash).unwrap(); assert_eq!(computed_hash, expected_hash); } diff --git a/starknet-core/src/types/contract/mod.rs b/starknet-core/src/types/contract/mod.rs index 6772ef92..24046f9b 100644 --- a/starknet-core/src/types/contract/mod.rs +++ b/starknet-core/src/types/contract/mod.rs @@ -7,7 +7,7 @@ use starknet_crypto::{poseidon_hash_many, PoseidonHasher}; use crate::{ serde::unsigned_field_element::UfeHex, - types::{EntryPointsByType, FieldElement, FlattenedSierraClass, SierraEntryPoint}, + types::{EntryPointsByType, Felt, FlattenedSierraClass, SierraEntryPoint}, utils::{ cairo_short_string_to_felt, normalize_address, starknet_keccak, CairoShortStringToFeltError, }, @@ -17,19 +17,19 @@ use crate::{ pub mod legacy; /// Cairo string for "CONTRACT_CLASS_V0.1.0" -const PREFIX_CONTRACT_CLASS_V0_1_0: FieldElement = FieldElement::from_mont([ - 5800711240972404213, - 15539482671244488427, - 18446734822722598327, +const PREFIX_CONTRACT_CLASS_V0_1_0: Felt = Felt::from_raw([ 37302452645455172, + 18446734822722598327, + 15539482671244488427, + 5800711240972404213, ]); /// Cairo string for "COMPILED_CLASS_V1" -const PREFIX_COMPILED_CLASS_V1: FieldElement = FieldElement::from_mont([ - 2291010424822318237, - 1609463842841646376, - 18446744073709549462, +const PREFIX_COMPILED_CLASS_V1: Felt = Felt::from_raw([ 324306817650036332, + 18446744073709549462, + 1609463842841646376, + 2291010424822318237, ]); #[derive(Debug, Clone, Serialize)] @@ -46,7 +46,7 @@ pub enum ContractArtifact { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct SierraClass { #[serde_as(as = "Vec")] - pub sierra_program: Vec, + pub sierra_program: Vec, pub sierra_program_debug_info: SierraClassDebugInfo, pub contract_class_version: String, pub entry_points_by_type: EntryPointsByType, @@ -60,7 +60,7 @@ pub struct CompiledClass { pub prime: String, pub compiler_version: String, #[serde_as(as = "Vec")] - pub bytecode: Vec, + pub bytecode: Vec, /// Represents the structure of the bytecode segments, using a nested list of segment lengths. /// For example, [2, [3, 4]] represents a bytecode with 2 segments, the first is a leaf of /// length 2 and the second is a node with 2 children of lengths 3 and 4. @@ -121,7 +121,7 @@ pub struct PythonicHint { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct CompiledClassEntrypoint { #[serde_as(as = "UfeHex")] - pub selector: FieldElement, + pub selector: Felt, pub offset: u64, pub builtins: Vec, } @@ -265,7 +265,7 @@ enum BytecodeSegmentStructure { /// Represents a leaf in the bytecode segment tree. struct BytecodeLeaf { // NOTE: change this to a slice? - data: Vec, + data: Vec, } /// Internal structure used for post-Sierra-1.5.0 CASM hash calculation. @@ -410,7 +410,7 @@ pub use errors::{ pub use errors::CompressProgramError; impl SierraClass { - pub fn class_hash(&self) -> Result { + pub fn class_hash(&self) -> Result { // Technically we don't have to use the Pythonic JSON style here. Doing this just to align // with the official `cairo-lang` CLI. // @@ -457,7 +457,7 @@ impl SierraClass { } impl FlattenedSierraClass { - pub fn class_hash(&self) -> FieldElement { + pub fn class_hash(&self) -> Felt { let mut hasher = PoseidonHasher::new(); hasher.update(PREFIX_CONTRACT_CLASS_V0_1_0); @@ -481,7 +481,7 @@ impl FlattenedSierraClass { } impl CompiledClass { - pub fn class_hash(&self) -> Result { + pub fn class_hash(&self) -> Result { let mut hasher = PoseidonHasher::new(); hasher.update(PREFIX_COMPILED_CLASS_V1); @@ -542,7 +542,7 @@ impl CompiledClass { fn hash_entrypoints( entrypoints: &[CompiledClassEntrypoint], - ) -> Result { + ) -> Result { let mut hasher = PoseidonHasher::new(); for entry in entrypoints.iter() { @@ -565,7 +565,7 @@ impl CompiledClass { // `visited_pcs` should be given in reverse order, and is consumed by the function. Returns the // BytecodeSegmentStructure and the total length of the processed segment. fn create_bytecode_segment_structure_inner( - bytecode: &[FieldElement], + bytecode: &[Felt], bytecode_segment_lengths: &IntOrList, visited_pcs: &mut Vec, bytecode_offset: &mut u64, @@ -649,7 +649,7 @@ impl CompiledClass { } impl BytecodeSegmentStructure { - fn hash(&self) -> FieldElement { + fn hash(&self) -> Felt { match self { Self::BytecodeLeaf(inner) => inner.hash(), Self::BytecodeSegmentedNode(inner) => inner.hash(), @@ -658,19 +658,19 @@ impl BytecodeSegmentStructure { } impl BytecodeLeaf { - fn hash(&self) -> FieldElement { + fn hash(&self) -> Felt { poseidon_hash_many(&self.data) } } impl BytecodeSegmentedNode { - fn hash(&self) -> FieldElement { + fn hash(&self) -> Felt { let mut hasher = PoseidonHasher::new(); for node in self.segments.iter() { hasher.update(node.segment_length.into()); hasher.update(node.inner_structure.hash()); } - hasher.finalize() + FieldElement::ONE + hasher.finalize() + Felt::ONE } } @@ -834,7 +834,7 @@ impl<'de> Deserialize<'de> for IntOrList { } } -fn hash_sierra_entrypoints(entrypoints: &[SierraEntryPoint]) -> FieldElement { +fn hash_sierra_entrypoints(entrypoints: &[SierraEntryPoint]) -> Felt { let mut hasher = PoseidonHasher::new(); for entry in entrypoints.iter() { @@ -931,7 +931,7 @@ mod tests { let computed_hash = sierra_class.class_hash().unwrap(); let hashes: ContractHashes = serde_json::from_str(raw_hashes).unwrap(); - let expected_hash = FieldElement::from_hex_be(&hashes.sierra_class_hash).unwrap(); + let expected_hash = Felt::from_hex(&hashes.sierra_class_hash).unwrap(); assert_eq!(computed_hash, expected_hash); } @@ -972,7 +972,7 @@ mod tests { let computed_hash = compiled_class.class_hash().unwrap(); let hashes: ContractHashes = serde_json::from_str(raw_hashes).unwrap(); - let expected_hash = FieldElement::from_hex_be(&hashes.compiled_class_hash).unwrap(); + let expected_hash = Felt::from_hex(&hashes.compiled_class_hash).unwrap(); assert_eq!(computed_hash, expected_hash); } diff --git a/starknet-core/src/types/eth_address.rs b/starknet-core/src/types/eth_address.rs index c380558a..dfc3028e 100644 --- a/starknet-core/src/types/eth_address.rs +++ b/starknet-core/src/types/eth_address.rs @@ -2,14 +2,14 @@ use alloc::{fmt::Formatter, format}; use core::str::FromStr; use serde::{de::Visitor, Deserialize, Serialize}; -use starknet_ff::FieldElement; +use starknet_types_core::felt::Felt; // 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF -const MAX_L1_ADDRESS: FieldElement = FieldElement::from_mont([ - 18406070939574861858, - 74766790688767, - 18446743936270598144, +const MAX_L1_ADDRESS: Felt = Felt::from_raw([ 461478224317121089, + 18446743936270598144, + 74766790688767, + 18406070939574861858, ]); #[derive(Debug, Clone, PartialEq, Eq)] @@ -58,7 +58,7 @@ mod errors { impl Display for FromFieldElementError { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - write!(f, "FieldElement value out of range") + write!(f, "Felt value out of range") } } @@ -79,7 +79,7 @@ impl EthAddress { hex.parse() } - pub fn from_felt(felt: &FieldElement) -> Result { + pub fn from_felt(felt: &Felt) -> Result { felt.try_into() } @@ -144,18 +144,18 @@ impl FromStr for EthAddress { } } -impl TryFrom for EthAddress { +impl TryFrom for EthAddress { type Error = FromFieldElementError; - fn try_from(value: FieldElement) -> Result { + fn try_from(value: Felt) -> Result { (&value).try_into() } } -impl TryFrom<&FieldElement> for EthAddress { +impl TryFrom<&Felt> for EthAddress { type Error = FromFieldElementError; - fn try_from(value: &FieldElement) -> Result { + fn try_from(value: &Felt) -> Result { if value <= &MAX_L1_ADDRESS { let mut buffer = [0u8; 20]; buffer.copy_from_slice(&value.to_bytes_be()[12..]); @@ -166,10 +166,10 @@ impl TryFrom<&FieldElement> for EthAddress { } } -impl From for FieldElement { +impl From for Felt { fn from(value: EthAddress) -> Self { // Safe to unwrap here as the value is never out of range - FieldElement::from_byte_slice_be(&value.inner).unwrap() + Felt::from_bytes_be_slice(&value.inner) } } @@ -196,12 +196,11 @@ impl From<[u8; 20]> for EthAddress { #[cfg(test)] mod tests { - use super::{EthAddress, FromBytesSliceError, FromFieldElementError}; + use super::{EthAddress, Felt, FromBytesSliceError, FromFieldElementError}; use alloc::vec::*; use hex_literal::hex; - use starknet_ff::FieldElement; #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] @@ -272,7 +271,7 @@ mod tests { assert_eq!( EthAddress::from_hex("0xb9fa6e54025b4f0829d8e1b42e8b846914659632").unwrap(), EthAddress::from_felt( - &FieldElement::from_hex_be("0xb9fa6e54025b4f0829d8e1b42e8b846914659632").unwrap() + &Felt::from_hex("0xb9fa6e54025b4f0829d8e1b42e8b846914659632").unwrap() ) .unwrap() ); @@ -282,7 +281,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_eth_address_from_felt_error() { match EthAddress::from_felt( - &FieldElement::from_hex_be("0x10000000000000000000000000000000000000000").unwrap(), + &Felt::from_hex("0x10000000000000000000000000000000000000000").unwrap(), ) { Ok(_) => panic!("Expected error, but got Ok"), Err(FromFieldElementError) => {} diff --git a/starknet-core/src/types/hash_256.rs b/starknet-core/src/types/hash_256.rs index c8ccc99e..dd3e31d0 100644 --- a/starknet-core/src/types/hash_256.rs +++ b/starknet-core/src/types/hash_256.rs @@ -5,7 +5,7 @@ use alloc::{ }; use serde::{de::Visitor, Deserialize, Serialize}; -use starknet_ff::FieldElement; +use starknet_types_core::felt::Felt; const HASH_256_BYTE_COUNT: usize = 32; @@ -49,7 +49,7 @@ mod errors { impl Display for ToFieldElementError { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - write!(f, "hash value out of range for FieldElement") + write!(f, "hash value out of range for Felt") } } } @@ -64,7 +64,7 @@ impl Hash256 { hex.parse() } - pub fn from_felt(felt: &FieldElement) -> Self { + pub fn from_felt(felt: &Felt) -> Self { felt.into() } @@ -148,19 +148,19 @@ impl Display for Hash256 { } } -impl From for Hash256 { - fn from(value: FieldElement) -> Self { +impl From for Hash256 { + fn from(value: Felt) -> Self { (&value).into() } } -impl From<&FieldElement> for Hash256 { - fn from(value: &FieldElement) -> Self { - value.to_bytes_be().into() +impl From<&Felt> for Hash256 { + fn from(value: &Felt) -> Self { + Self::from_bytes(value.to_bytes_be()) } } -impl TryFrom for FieldElement { +impl TryFrom for Felt { type Error = ToFieldElementError; fn try_from(value: Hash256) -> Result { @@ -168,11 +168,11 @@ impl TryFrom for FieldElement { } } -impl TryFrom<&Hash256> for FieldElement { +impl TryFrom<&Hash256> for Felt { type Error = ToFieldElementError; fn try_from(value: &Hash256) -> Result { - FieldElement::from_bytes_be(&value.inner).map_err(|_| ToFieldElementError) + Ok(Felt::from_bytes_be(&value.inner)) } } @@ -184,9 +184,7 @@ impl From<[u8; HASH_256_BYTE_COUNT]> for Hash256 { #[cfg(test)] mod tests { - use super::{FromHexError, Hash256, HASH_256_BYTE_COUNT}; - - use starknet_ff::FieldElement; + use super::{Felt, FromHexError, Hash256, HASH_256_BYTE_COUNT}; #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] @@ -227,13 +225,12 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_hash_256_from_felt() { - // Create a `FieldElement` from a hexadecimal string representation - let felt = FieldElement::from_hex_be( - "0x01a736d6ed154502257f02b1ccdf4d9d1089f80811cd6acad48e6b6a9d1f2003", - ) - .unwrap(); + // Create a `Felt` from a hexadecimal string representation + let felt = + Felt::from_hex("0x01a736d6ed154502257f02b1ccdf4d9d1089f80811cd6acad48e6b6a9d1f2003") + .unwrap(); - // Convert the `FieldElement` to bytes and then to a vector + // Convert the `Felt` to bytes and then to a vector let bytes = (felt.to_bytes_be()).to_vec(); // Convert bytes to a fixed-size array representing `Hash256` @@ -243,7 +240,7 @@ mod tests { // Convert `Hash256` bytes to `Hash256` struct let hash_256: Hash256 = hash_bytes.into(); - // Assert that the conversion from the `FieldElement` to `Hash256` is successful + // Assert that the conversion from the `Felt` to `Hash256` is successful assert_eq!(Hash256::from_felt(&felt), hash_256); } } diff --git a/starknet-core/src/types/mod.rs b/starknet-core/src/types/mod.rs index df1e6cc5..d46535bc 100644 --- a/starknet-core/src/types/mod.rs +++ b/starknet-core/src/types/mod.rs @@ -5,7 +5,7 @@ use serde_with::serde_as; use crate::serde::unsigned_field_element::UfeHex; -pub use starknet_ff::*; +pub use starknet_types_core::felt::{Felt, NonZeroFelt}; mod conversions; @@ -97,7 +97,7 @@ pub enum MaybePendingStateUpdate { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct BlockHashAndNumber { #[serde_as(as = "UfeHex")] - pub block_hash: FieldElement, + pub block_hash: Felt, pub block_number: u64, } @@ -123,7 +123,7 @@ pub struct EventsPage { pub struct InvokeTransactionResult { /// The hash of the invoke transaction #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } #[serde_as] @@ -131,10 +131,10 @@ pub struct InvokeTransactionResult { pub struct DeclareTransactionResult { /// The hash of the declare transaction #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The hash of the declared class #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } #[serde_as] @@ -142,10 +142,10 @@ pub struct DeclareTransactionResult { pub struct DeployTransactionResult { /// The hash of the deploy transaction #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The address of the new contract #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, } #[serde_as] @@ -153,16 +153,16 @@ pub struct DeployTransactionResult { pub struct DeployAccountTransactionResult { /// The hash of the deploy transaction #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, /// The address of the new contract #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, } /// Block hash, number or tag #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum BlockId { - Hash(FieldElement), + Hash(Felt), Number(u64), Tag(BlockTag), } @@ -337,7 +337,7 @@ mod errors { pub use errors::ParseMsgToL2Error; impl MaybePendingBlockWithTxHashes { - pub fn transactions(&self) -> &[FieldElement] { + pub fn transactions(&self) -> &[Felt] { match self { MaybePendingBlockWithTxHashes::Block(block) => &block.transactions, MaybePendingBlockWithTxHashes::PendingBlock(block) => &block.transactions, @@ -396,7 +396,7 @@ impl TransactionStatus { } impl Transaction { - pub fn transaction_hash(&self) -> &FieldElement { + pub fn transaction_hash(&self) -> &Felt { match self { Transaction::Invoke(tx) => tx.transaction_hash(), Transaction::L1Handler(tx) => &tx.transaction_hash, @@ -408,7 +408,7 @@ impl Transaction { } impl InvokeTransaction { - pub fn transaction_hash(&self) -> &FieldElement { + pub fn transaction_hash(&self) -> &Felt { match self { InvokeTransaction::V0(tx) => &tx.transaction_hash, InvokeTransaction::V1(tx) => &tx.transaction_hash, @@ -418,7 +418,7 @@ impl InvokeTransaction { } impl DeclareTransaction { - pub fn transaction_hash(&self) -> &FieldElement { + pub fn transaction_hash(&self) -> &Felt { match self { DeclareTransaction::V0(tx) => &tx.transaction_hash, DeclareTransaction::V1(tx) => &tx.transaction_hash, @@ -429,7 +429,7 @@ impl DeclareTransaction { } impl DeployAccountTransaction { - pub fn transaction_hash(&self) -> &FieldElement { + pub fn transaction_hash(&self) -> &Felt { match self { DeployAccountTransaction::V1(tx) => &tx.transaction_hash, DeployAccountTransaction::V3(tx) => &tx.transaction_hash, @@ -438,7 +438,7 @@ impl DeployAccountTransaction { } impl TransactionReceipt { - pub fn transaction_hash(&self) -> &FieldElement { + pub fn transaction_hash(&self) -> &Felt { match self { TransactionReceipt::Invoke(receipt) => &receipt.transaction_hash, TransactionReceipt::L1Handler(receipt) => &receipt.transaction_hash, @@ -545,7 +545,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_felt_to_string() { - let felt = FieldElement::from_dec_str("123456").unwrap(); + let felt = Felt::from_dec_str("123456").unwrap(); assert_eq!(format!("{}", felt), "123456"); assert_eq!(format!("{:x}", felt), "1e240"); @@ -580,28 +580,26 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_parse_msg_to_l2() { let l1_handler_tx = L1HandlerTransaction { - transaction_hash: FieldElement::from_hex_be( + transaction_hash: Felt::from_hex( "0x374286ae28f201e61ffbc5b022cc9701208640b405ea34ea9799f97d5d2d23c", ) .unwrap(), - version: FieldElement::ZERO, + version: Felt::ZERO, nonce: 775628, - contract_address: FieldElement::from_hex_be( + contract_address: Felt::from_hex( "0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82", ) .unwrap(), - entry_point_selector: FieldElement::from_hex_be( + entry_point_selector: Felt::from_hex( "0x2d757788a8d8d6f21d1cd40bce38a8222d70654214e96ff95d8086e684fbee5", ) .unwrap(), calldata: vec![ - FieldElement::from_hex_be("0xc3511006c04ef1d78af4c8e0e74ec18a6e64ff9e").unwrap(), - FieldElement::from_hex_be( - "0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7", - ) - .unwrap(), - FieldElement::from_hex_be("0x2c68af0bb140000").unwrap(), - FieldElement::from_hex_be("0x0").unwrap(), + Felt::from_hex("0xc3511006c04ef1d78af4c8e0e74ec18a6e64ff9e").unwrap(), + Felt::from_hex("0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7") + .unwrap(), + Felt::from_hex("0x2c68af0bb140000").unwrap(), + Felt::from_hex("0x0").unwrap(), ], }; @@ -618,17 +616,17 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_parse_msg_to_l2_empty_calldata_error() { let l1_handler_tx = L1HandlerTransaction { - transaction_hash: FieldElement::from_hex_be( + transaction_hash: Felt::from_hex( "0x374286ae28f201e61ffbc5b022cc9701208640b405ea34ea9799f97d5d2d23c", ) .unwrap(), - version: FieldElement::ZERO, + version: Felt::ZERO, nonce: 775628, - contract_address: FieldElement::from_hex_be( + contract_address: Felt::from_hex( "0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82", ) .unwrap(), - entry_point_selector: FieldElement::from_hex_be( + entry_point_selector: Felt::from_hex( "0x2d757788a8d8d6f21d1cd40bce38a8222d70654214e96ff95d8086e684fbee5", ) .unwrap(), @@ -644,30 +642,28 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_parse_msg_to_l2_from_address_out_of_range_error() { let l1_handler_tx = L1HandlerTransaction { - transaction_hash: FieldElement::from_hex_be( + transaction_hash: Felt::from_hex( "0x374286ae28f201e61ffbc5b022cc9701208640b405ea34ea9799f97d5d2d23c", ) .unwrap(), - version: FieldElement::ZERO, + version: Felt::ZERO, nonce: 775628, - contract_address: FieldElement::from_hex_be( + contract_address: Felt::from_hex( "0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82", ) .unwrap(), - entry_point_selector: FieldElement::from_hex_be( + entry_point_selector: Felt::from_hex( "0x2d757788a8d8d6f21d1cd40bce38a8222d70654214e96ff95d8086e684fbee5", ) .unwrap(), calldata: vec![ // Incorrect from address format, causing the conversion error // Max address + 1 - FieldElement::from_hex_be("0x10000000000000000000000000000000000000000").unwrap(), - FieldElement::from_hex_be( - "0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7", - ) - .unwrap(), - FieldElement::from_hex_be("0x2c68af0bb140000").unwrap(), - FieldElement::from_hex_be("0x0").unwrap(), + Felt::from_hex("0x10000000000000000000000000000000000000000").unwrap(), + Felt::from_hex("0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7") + .unwrap(), + Felt::from_hex("0x2c68af0bb140000").unwrap(), + Felt::from_hex("0x0").unwrap(), ], }; diff --git a/starknet-core/src/types/msg.rs b/starknet-core/src/types/msg.rs index f57b39c8..e1f1ce04 100644 --- a/starknet-core/src/types/msg.rs +++ b/starknet-core/src/types/msg.rs @@ -1,16 +1,16 @@ use alloc::vec::*; use sha3::{Digest, Keccak256}; -use starknet_ff::FieldElement; +use starknet_types_core::felt::Felt; use super::{EthAddress, Hash256, MsgToL1}; #[derive(Debug, Clone)] pub struct MsgToL2 { pub from_address: EthAddress, - pub to_address: FieldElement, - pub selector: FieldElement, - pub payload: Vec, + pub to_address: Felt, + pub selector: Felt, + pub payload: Vec, pub nonce: u64, } @@ -92,21 +92,19 @@ mod tests { let msg = MsgToL2 { from_address: EthAddress::from_hex("0xc3511006C04EF1d78af4C8E0e74Ec18A6E64Ff9e") .unwrap(), - to_address: FieldElement::from_hex_be( + to_address: Felt::from_hex( "0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82", ) .unwrap(), - selector: FieldElement::from_hex_be( + selector: Felt::from_hex( "0x2d757788a8d8d6f21d1cd40bce38a8222d70654214e96ff95d8086e684fbee5", ) .unwrap(), payload: vec![ - FieldElement::from_hex_be( - "0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7", - ) - .unwrap(), - FieldElement::from_hex_be("0x2c68af0bb140000").unwrap(), - FieldElement::from_hex_be("0x0").unwrap(), + Felt::from_hex("0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7") + .unwrap(), + Felt::from_hex("0x2c68af0bb140000").unwrap(), + Felt::from_hex("0x0").unwrap(), ], nonce: 775628, }; @@ -125,21 +123,21 @@ mod tests { // Goerli-1 tx (L2): 4e0bbc07ff29e5df13dfbcb7e4746fdde52c3649a6a69bd86b15397769722fd let msg = MsgToL1 { - from_address: FieldElement::from_hex_be( + from_address: Felt::from_hex( "0x0164cba33fb7152531f6b4cfc3fff26b4d7b26b4900e0881042edd607b428a92", ) .unwrap(), - to_address: FieldElement::from_hex_be( + to_address: Felt::from_hex( "0x000000000000000000000000b6dbfaa86bb683152e4fc2401260f9ca249519c0", ) .unwrap(), payload: vec![ - FieldElement::from_hex_be("0x0").unwrap(), - FieldElement::from_hex_be("0x0").unwrap(), - FieldElement::from_hex_be("0x0182b8").unwrap(), - FieldElement::from_hex_be("0x0").unwrap(), - FieldElement::from_hex_be("0x0384").unwrap(), - FieldElement::from_hex_be("0x0").unwrap(), + Felt::from_hex("0x0").unwrap(), + Felt::from_hex("0x0").unwrap(), + Felt::from_hex("0x0182b8").unwrap(), + Felt::from_hex("0x0").unwrap(), + Felt::from_hex("0x0384").unwrap(), + Felt::from_hex("0x0").unwrap(), ], }; diff --git a/starknet-core/src/types/receipt_block.rs b/starknet-core/src/types/receipt_block.rs index 56bd1ba5..4287e2e6 100644 --- a/starknet-core/src/types/receipt_block.rs +++ b/starknet-core/src/types/receipt_block.rs @@ -1,16 +1,13 @@ use serde::{Deserialize, Serialize}; use serde_with::serde_as; -use crate::types::FieldElement; +use starknet_types_core::felt::Felt; /// A more idiomatic way to access `execution_status` and `revert_reason`. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ReceiptBlock { Pending, - Block { - block_hash: FieldElement, - block_number: u64, - }, + Block { block_hash: Felt, block_number: u64 }, } impl ReceiptBlock { @@ -33,7 +30,7 @@ impl ReceiptBlock { /// Returns `None` if block is not `Block`. /// /// A more idiomatic way of accessing the block hash is to match the `Block` enum variant. - pub fn block_hash(&self) -> Option { + pub fn block_hash(&self) -> Option { match self { ReceiptBlock::Pending => None, ReceiptBlock::Block { block_hash, .. } => Some(*block_hash), @@ -61,7 +58,7 @@ impl Serialize for ReceiptBlock { struct Raw<'a> { #[serde_as(as = "Option")] #[serde(skip_serializing_if = "Option::is_none")] - block_hash: Option<&'a FieldElement>, + block_hash: Option<&'a Felt>, #[serde(skip_serializing_if = "Option::is_none")] block_number: Option<&'a u64>, } @@ -95,7 +92,7 @@ impl<'de> Deserialize<'de> for ReceiptBlock { struct Raw { #[serde_as(as = "Option")] #[serde(skip_serializing_if = "Option::is_none")] - block_hash: Option, + block_hash: Option, #[serde(skip_serializing_if = "Option::is_none")] block_number: Option, } diff --git a/starknet-core/src/types/serde_impls.rs b/starknet-core/src/types/serde_impls.rs index 589cadb3..95a5221f 100644 --- a/starknet-core/src/types/serde_impls.rs +++ b/starknet-core/src/types/serde_impls.rs @@ -151,9 +151,10 @@ impl<'de> Deserialize<'de> for SyncStatusType { } mod block_id { - use crate::{serde::unsigned_field_element::UfeHex, types::FieldElement}; + use crate::serde::unsigned_field_element::UfeHex; use serde::{Deserialize, Deserializer, Serialize}; use serde_with::serde_as; + use starknet_types_core::felt::Felt; use crate::types::{BlockId, BlockTag}; @@ -170,7 +171,7 @@ mod block_id { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct BlockHash { #[serde_as(as = "UfeHex")] - block_hash: FieldElement, + block_hash: Felt, } #[derive(Serialize, Deserialize)] @@ -400,9 +401,10 @@ mod enum_ser_impls { mod tests { use serde::Deserialize; use serde_with::serde_as; + use starknet_types_core::felt::Felt; use super::{ - super::{BlockId, BlockTag, FieldElement}, + super::{BlockId, BlockTag}, NumAsHex, }; @@ -411,7 +413,7 @@ mod tests { fn test_blockid_serde() { for (block_id, json) in [ ( - BlockId::Hash(FieldElement::from_hex_be("0x1234").unwrap()), + BlockId::Hash(Felt::from_hex("0x1234").unwrap()), "{\"block_hash\":\"0x1234\"}", ), (BlockId::Number(1234), "{\"block_number\":1234}"), diff --git a/starknet-core/src/types/u256.rs b/starknet-core/src/types/u256.rs index eea783cb..7f731e3e 100644 --- a/starknet-core/src/types/u256.rs +++ b/starknet-core/src/types/u256.rs @@ -1,7 +1,8 @@ use core::{fmt::Display, str}; use crypto_bigint::{ArrayEncoding, CheckedAdd, CheckedMul, CheckedSub, Zero}; -use starknet_ff::FieldElement; + +use crate::types::Felt; /// 256-bit unsiged integer. /// @@ -242,8 +243,8 @@ impl From for U256 { } } -impl From for U256 { - fn from(value: FieldElement) -> Self { +impl From for U256 { + fn from(value: Felt) -> Self { Self(crypto_bigint::U256::from_be_byte_array( value.to_bytes_be().into(), )) @@ -276,10 +277,7 @@ mod tests { assert_eq!(u256_value, 123u32.into()); assert_eq!(u256_value, 123u64.into()); assert_eq!(u256_value, 123u128.into()); - assert_eq!( - u256_value, - FieldElement::from_dec_str("123").unwrap().into() - ); + assert_eq!(u256_value, Felt::from_dec_str("123").unwrap().into()); } #[test] diff --git a/starknet-core/src/utils.rs b/starknet-core/src/utils.rs index ab836ed5..c1fa8273 100644 --- a/starknet-core/src/utils.rs +++ b/starknet-core/src/utils.rs @@ -1,27 +1,29 @@ use alloc::string::*; -use crate::{crypto::compute_hash_on_elements, types::FieldElement}; +use crate::crypto::compute_hash_on_elements; use sha3::{Digest, Keccak256}; use starknet_crypto::pedersen_hash; +use starknet_types_core::felt::Felt; +use starknet_types_core::felt::NonZeroFelt; const DEFAULT_ENTRY_POINT_NAME: &str = "__default__"; const DEFAULT_L1_ENTRY_POINT_NAME: &str = "__l1_default__"; // 2 ** 251 - 256 -const ADDR_BOUND: FieldElement = FieldElement::from_mont([ - 18446743986131443745, - 160989183, - 18446744073709255680, +const ADDR_BOUND: NonZeroFelt = NonZeroFelt::from_raw([ 576459263475590224, + 18446744073709255680, + 160989183, + 18446743986131443745, ]); // Cairo string of "STARKNET_CONTRACT_ADDRESS" -const CONTRACT_ADDRESS_PREFIX: FieldElement = FieldElement::from_mont([ - 3829237882463328880, - 17289941567720117366, - 8635008616843941496, +const CONTRACT_ADDRESS_PREFIX: Felt = Felt::from_raw([ 533439743893157637, + 8635008616843941496, + 17289941567720117366, + 3829237882463328880, ]); /// The uniqueness settings for UDC deployments. @@ -33,8 +35,8 @@ pub enum UdcUniqueness { #[derive(Debug, Clone)] pub struct UdcUniqueSettings { - pub deployer_address: FieldElement, - pub udc_contract_address: FieldElement, + pub deployer_address: Felt, + pub udc_contract_address: Felt, } mod errors { @@ -95,7 +97,7 @@ mod errors { pub use errors::{CairoShortStringToFeltError, NonAsciiNameError, ParseCairoShortStringError}; /// A variant of eth-keccak that computes a value that fits in a Starknet field element. -pub fn starknet_keccak(data: &[u8]) -> FieldElement { +pub fn starknet_keccak(data: &[u8]) -> Felt { let mut hasher = Keccak256::new(); hasher.update(data); let mut hash = hasher.finalize(); @@ -104,12 +106,12 @@ pub fn starknet_keccak(data: &[u8]) -> FieldElement { hash[0] &= 0b00000011; // Because we know hash is always 32 bytes - FieldElement::from_bytes_be(unsafe { &*(hash[..].as_ptr() as *const [u8; 32]) }).unwrap() + Felt::from_bytes_be(unsafe { &*(hash[..].as_ptr() as *const [u8; 32]) }) } -pub fn get_selector_from_name(func_name: &str) -> Result { +pub fn get_selector_from_name(func_name: &str) -> Result { if func_name == DEFAULT_ENTRY_POINT_NAME || func_name == DEFAULT_L1_ENTRY_POINT_NAME { - Ok(FieldElement::ZERO) + Ok(Felt::ZERO) } else { let name_bytes = func_name.as_bytes(); if name_bytes.is_ascii() { @@ -120,10 +122,7 @@ pub fn get_selector_from_name(func_name: &str) -> Result Result { +pub fn get_storage_var_address(var_name: &str, args: &[Felt]) -> Result { let var_name_bytes = var_name.as_bytes(); if var_name_bytes.is_ascii() { let mut res = starknet_keccak(var_name_bytes); @@ -136,8 +135,8 @@ pub fn get_storage_var_address( } } -/// Converts Cairo short string to [FieldElement]. -pub fn cairo_short_string_to_felt(str: &str) -> Result { +/// Converts Cairo short string to [Felt]. +pub fn cairo_short_string_to_felt(str: &str) -> Result { if !str.is_ascii() { return Err(CairoShortStringToFeltError::NonAsciiCharacter); } @@ -151,12 +150,12 @@ pub fn cairo_short_string_to_felt(str: &str) -> Result Result { - if felt == &FieldElement::ZERO { +/// Converts [Felt] to Cairo short string. +pub fn parse_cairo_short_string(felt: &Felt) -> Result { + if felt == &Felt::ZERO { return Ok(String::new()); } @@ -182,11 +181,11 @@ pub fn parse_cairo_short_string(felt: &FieldElement) -> Result FieldElement { + salt: Felt, + class_hash: Felt, + constructor_calldata: &[Felt], + deployer_address: Felt, +) -> Felt { normalize_address(compute_hash_on_elements(&[ CONTRACT_ADDRESS_PREFIX, deployer_address, @@ -198,14 +197,14 @@ pub fn get_contract_address( /// Computes the target contract address for deployments through the Universal Deploy Contract. pub fn get_udc_deployed_address( - salt: FieldElement, - class_hash: FieldElement, + salt: Felt, + class_hash: Felt, uniqueness: &UdcUniqueness, - constructor_calldata: &[FieldElement], -) -> FieldElement { + constructor_calldata: &[Felt], +) -> Felt { match uniqueness { UdcUniqueness::NotUnique => { - get_contract_address(salt, class_hash, constructor_calldata, FieldElement::ZERO) + get_contract_address(salt, class_hash, constructor_calldata, Felt::ZERO) } UdcUniqueness::Unique(settings) => { let unique_salt = pedersen_hash(&settings.deployer_address, &salt); @@ -219,8 +218,8 @@ pub fn get_udc_deployed_address( } } -pub fn normalize_address(address: FieldElement) -> FieldElement { - address % ADDR_BOUND +pub fn normalize_address(address: Felt) -> Felt { + address.mod_floor(&ADDR_BOUND) } #[cfg(test)] @@ -232,10 +231,9 @@ mod tests { fn test_starknet_keccak() { // Generated from `cairo-lang` let data = b"execute"; - let expected_hash = FieldElement::from_hex_be( - "0240060cdb34fcc260f41eac7474ee1d7c80b7e3607daff9ac67c7ea2ebb1c44", - ) - .unwrap(); + let expected_hash = + Felt::from_hex("0240060cdb34fcc260f41eac7474ee1d7c80b7e3607daff9ac67c7ea2ebb1c44") + .unwrap(); let hash = starknet_keccak(data); @@ -247,10 +245,9 @@ mod tests { fn test_get_selector_from_name() { // Generated from `cairo-lang` let func_name = "execute"; - let expected_selector = FieldElement::from_hex_be( - "0240060cdb34fcc260f41eac7474ee1d7c80b7e3607daff9ac67c7ea2ebb1c44", - ) - .unwrap(); + let expected_selector = + Felt::from_hex("0240060cdb34fcc260f41eac7474ee1d7c80b7e3607daff9ac67c7ea2ebb1c44") + .unwrap(); let selector = get_selector_from_name(func_name).unwrap(); @@ -260,10 +257,9 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_get_default_selector() { - let default_selector = FieldElement::from_hex_be( - "0000000000000000000000000000000000000000000000000000000000000000", - ) - .unwrap(); + let default_selector = + Felt::from_hex("0000000000000000000000000000000000000000000000000000000000000000") + .unwrap(); assert_eq!( get_selector_from_name("__default__").unwrap(), @@ -291,10 +287,9 @@ mod tests { fn test_get_storage_var_address() { // Generated from `cairo-lang` let var_name = "balance"; - let expected_addr = FieldElement::from_hex_be( - "0x0206f38f7e4f15e87567361213c28f235cccdaa1d7fd34c9db1dfe9489c6a091", - ) - .unwrap(); + let expected_addr = + Felt::from_hex("0x0206f38f7e4f15e87567361213c28f235cccdaa1d7fd34c9db1dfe9489c6a091") + .unwrap(); let addr = get_storage_var_address(var_name, &[]).unwrap(); @@ -306,10 +301,9 @@ mod tests { fn test_get_storage_var_address_with_args() { // Generated from `cairo-lang` let var_name = "balanceOf"; - let expected_addr = FieldElement::from_hex_be( - "0x07de334d65aa93d9185729b424025918b18892418c85b802775d1f0d2be30a1d", - ) - .unwrap(); + let expected_addr = + Felt::from_hex("0x07de334d65aa93d9185729b424025918b18892418c85b802775d1f0d2be30a1d") + .unwrap(); let addr = get_storage_var_address(var_name, &[1234u64.into()]).unwrap(); @@ -333,7 +327,7 @@ mod tests { for (str, felt_dec) in data.into_iter() { assert_eq!( cairo_short_string_to_felt(str).unwrap(), - FieldElement::from_dec_str(felt_dec).unwrap() + Felt::from_dec_str(felt_dec).unwrap() ); } } @@ -372,7 +366,7 @@ mod tests { for (str, felt_dec) in data.into_iter() { assert_eq!( - parse_cairo_short_string(&FieldElement::from_dec_str(felt_dec).unwrap()).unwrap(), + parse_cairo_short_string(&Felt::from_dec_str(felt_dec).unwrap()).unwrap(), str ); } @@ -383,7 +377,7 @@ mod tests { fn test_parse_cairo_short_string_too_long() { assert!(matches!( parse_cairo_short_string( - &FieldElement::from_hex_be( + &Felt::from_hex( "0x0111111111111111111111111111111111111111111111111111111111111111" ) .unwrap() @@ -397,7 +391,7 @@ mod tests { fn test_parse_cairo_short_string_unexpected_null() { assert!(matches!( parse_cairo_short_string( - &FieldElement::from_hex_be( + &Felt::from_hex( "0x0011111111111111111111111111111111111111111111111111111111110011" ) .unwrap() @@ -411,21 +405,19 @@ mod tests { fn test_get_contract_address() { assert_eq!( get_contract_address( - FieldElement::from_hex_be( + Felt::from_hex( "0x0018a7a329d1d85b621350f2b5fc9c64b2e57dfe708525f0aff2c90de1e5b9c8" ) .unwrap(), - FieldElement::from_hex_be( + Felt::from_hex( "0x0750cd490a7cd1572411169eaa8be292325990d33c5d4733655fe6b926985062" ) .unwrap(), - &[FieldElement::ONE], - FieldElement::ZERO + &[Felt::ONE], + Felt::ZERO ), - FieldElement::from_hex_be( - "0x00da27ef7c3869c3a6cc6a0f7bf07a51c3e590825adba8a51cae27d815839eec" - ) - .unwrap() + Felt::from_hex("0x00da27ef7c3869c3a6cc6a0f7bf07a51c3e590825adba8a51cae27d815839eec") + .unwrap() ) } @@ -433,23 +425,17 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_udc_address_not_unique() { let address = get_udc_deployed_address( - FieldElement::from_hex_be( - "0x06df0e9a9842d97ff3f4c6de7494d6e69d0a107a72150f9c53d59515b91ed9cb", - ) - .unwrap(), - FieldElement::from_hex_be( - "0x0562fc1d911530d18a86ea3ef4be50018923898d3c573288c5abb9c2344459ed", - ) - .unwrap(), + Felt::from_hex("0x06df0e9a9842d97ff3f4c6de7494d6e69d0a107a72150f9c53d59515b91ed9cb") + .unwrap(), + Felt::from_hex("0x0562fc1d911530d18a86ea3ef4be50018923898d3c573288c5abb9c2344459ed") + .unwrap(), &UdcUniqueness::NotUnique, - &[FieldElement::from_hex_be("0x1234").unwrap()], + &[Felt::from_hex("0x1234").unwrap()], ); assert_eq!( - FieldElement::from_hex_be( - "0x0288e5952d2f2f0e897ea0c5401c6e9f584a89eebfb08b5b26f090a8bbf67eb6", - ) - .unwrap(), + Felt::from_hex("0x0288e5952d2f2f0e897ea0c5401c6e9f584a89eebfb08b5b26f090a8bbf67eb6",) + .unwrap(), address ); } @@ -458,32 +444,26 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_udc_address_unique() { let address = get_udc_deployed_address( - FieldElement::from_hex_be( - "0x01f65976b95bf17ae1cb04afc9fc1eeee26d3e1aaa1f30aa535bf261e4322ab8", - ) - .unwrap(), - FieldElement::from_hex_be( - "0x0562fc1d911530d18a86ea3ef4be50018923898d3c573288c5abb9c2344459ed", - ) - .unwrap(), + Felt::from_hex("0x01f65976b95bf17ae1cb04afc9fc1eeee26d3e1aaa1f30aa535bf261e4322ab8") + .unwrap(), + Felt::from_hex("0x0562fc1d911530d18a86ea3ef4be50018923898d3c573288c5abb9c2344459ed") + .unwrap(), &UdcUniqueness::Unique(UdcUniqueSettings { - deployer_address: FieldElement::from_hex_be( + deployer_address: Felt::from_hex( "0x00b1461de04c6a1aa3375bdf9b7723a8779c082ffe21311d683a0b15c078b5dc", ) .unwrap(), - udc_contract_address: FieldElement::from_hex_be( + udc_contract_address: Felt::from_hex( "0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf", ) .unwrap(), }), - &[FieldElement::from_hex_be("0x1234").unwrap()], + &[Felt::from_hex("0x1234").unwrap()], ); assert_eq!( - FieldElement::from_hex_be( - "0x02406943b25942021f213b047c8765e531dddce3b981722f7aeb2ca137e18dbf", - ) - .unwrap(), + Felt::from_hex("0x02406943b25942021f213b047c8765e531dddce3b981722f7aeb2ca137e18dbf",) + .unwrap(), address ); } diff --git a/starknet-crypto-codegen/Cargo.toml b/starknet-crypto-codegen/Cargo.toml index 08c2c067..a0065269 100644 --- a/starknet-crypto-codegen/Cargo.toml +++ b/starknet-crypto-codegen/Cargo.toml @@ -17,5 +17,5 @@ proc-macro = true [dependencies] starknet-curve = { version = "0.4.2", path = "../starknet-curve" } -starknet-ff = { version = "0.3.7", path = "../starknet-ff", default-features = false } -syn = { version = "2.0.15", default-features = false } +syn = "2.0.55" +starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve"] } diff --git a/starknet-crypto-codegen/src/pedersen.rs b/starknet-crypto-codegen/src/pedersen.rs index 66e5a3bf..ab0cb007 100644 --- a/starknet-crypto-codegen/src/pedersen.rs +++ b/starknet-crypto-codegen/src/pedersen.rs @@ -4,10 +4,8 @@ use std::fmt::Write; use proc_macro::TokenStream; -use starknet_curve::{ - curve_params::{PEDERSEN_P0, PEDERSEN_P1, PEDERSEN_P2, PEDERSEN_P3}, - AffinePoint, -}; +use starknet_curve::curve_params::{PEDERSEN_P0, PEDERSEN_P1, PEDERSEN_P2, PEDERSEN_P3}; +use starknet_types_core::curve::{AffinePoint, ProjectivePoint}; use syn::{parse_macro_input, LitInt}; pub fn lookup_table(input: TokenStream) -> TokenStream { @@ -40,26 +38,26 @@ fn push_points( writeln!( buf, - "pub const CURVE_CONSTS_{name}: [::starknet_curve::AffinePoint; {len}] = [" + "pub const CURVE_CONSTS_{name}: [starknet_types_core::curve::AffinePoint; {len}] = [" )?; let mut bits_left = max_bits; - let mut outer_point = base; + let mut outer_point = ProjectivePoint::from_affine(base.x(), base.y()).unwrap(); while bits_left > 0 { let eat_bits = std::cmp::min(bits_left, bits); let table_size = (1 << eat_bits) - 1; // Loop through each possible bit combination except zero - let mut inner_point = outer_point; + let mut inner_point = outer_point.clone(); for _ in 1..(table_size + 1) { - push_point(buf, &inner_point)?; + push_point(buf, &inner_point.to_affine().unwrap())?; inner_point += &outer_point; } // Shift outer point #bits times bits_left -= eat_bits; for _i in 0..bits { - outer_point.double_assign(); + outer_point += outer_point.clone(); } } @@ -68,22 +66,24 @@ fn push_points( } fn push_point(buf: &mut String, p: &AffinePoint) -> std::fmt::Result { - let x = p.x.into_mont(); - let y = p.y.into_mont(); - writeln!(buf, "::starknet_curve::AffinePoint {{")?; - writeln!(buf, "x: ::starknet_ff::FieldElement::from_mont([")?; + let x = p.x().to_raw(); + let y = p.y().to_raw(); + writeln!( + buf, + "starknet_types_core::curve::AffinePoint::new_unchecked(" + )?; + writeln!(buf, "starknet_types_core::felt::Felt::from_raw([")?; writeln!(buf, "{},", x[0])?; writeln!(buf, "{},", x[1])?; writeln!(buf, "{},", x[2])?; writeln!(buf, "{},", x[3])?; writeln!(buf, "]),")?; - writeln!(buf, "y: ::starknet_ff::FieldElement::from_mont([")?; + writeln!(buf, "starknet_types_core::felt::Felt::from_raw([")?; writeln!(buf, "{},", y[0])?; writeln!(buf, "{},", y[1])?; writeln!(buf, "{},", y[2])?; writeln!(buf, "{},", y[3])?; writeln!(buf, "]),")?; - writeln!(buf, "infinity: false,")?; - writeln!(buf, "}},")?; + writeln!(buf, "),")?; Ok(()) } diff --git a/starknet-crypto-codegen/src/poseidon/mod.rs b/starknet-crypto-codegen/src/poseidon/mod.rs index 7eec0f8b..2a11c2c5 100644 --- a/starknet-crypto-codegen/src/poseidon/mod.rs +++ b/starknet-crypto-codegen/src/poseidon/mod.rs @@ -4,7 +4,7 @@ use std::fmt::Write; use proc_macro::TokenStream; -use starknet_ff::FieldElement; +use starknet_types_core::felt::Felt; mod params; @@ -14,7 +14,7 @@ const PARTIAL_ROUNDS: usize = 83; pub fn poseidon_consts() -> TokenStream { let round_keys = params::RAW_ROUND_KEYS .iter() - .map(|key| key.map(|num| FieldElement::from_dec_str(num).expect("Invalid round key"))) + .map(|key| key.map(|num| Felt::from_dec_str(num).expect("Invalid round key"))) .collect::>(); let flat = round_keys.iter().flatten().cloned().collect::>(); @@ -35,7 +35,7 @@ pub fn poseidon_consts() -> TokenStream { buffer.parse().expect("Invalid code generated") } -pub fn compress_roundkeys(rcs: &[[FieldElement; 3]]) -> Vec { +pub fn compress_roundkeys(rcs: &[[Felt; 3]]) -> Vec { let mut result = Vec::new(); // Add first full rounds @@ -54,11 +54,11 @@ pub fn compress_roundkeys(rcs: &[[FieldElement; 3]]) -> Vec { result } -pub fn compress_roundkeys_partial(rcs: &[[FieldElement; 3]]) -> Vec { +pub fn compress_roundkeys_partial(rcs: &[[Felt; 3]]) -> Vec { let mut result = Vec::new(); let mut idx = FULL_ROUNDS / 2; - let mut state: [FieldElement; 3] = [FieldElement::ZERO; 3]; + let mut state: [Felt; 3] = [Felt::ZERO; 3]; // Add keys for partial rounds for _ in 0..PARTIAL_ROUNDS { @@ -71,13 +71,13 @@ pub fn compress_roundkeys_partial(rcs: &[[FieldElement; 3]]) -> Vec Vec String { +pub fn generate_code(name: &str, rcs: &[Felt]) -> String { let mut buf = String::with_capacity(1024 * 1024); - writeln!(buf, "pub const {}: [FieldElement; {}] = [", name, rcs.len()).unwrap(); + writeln!(buf, "pub const {}: [Felt; {}] = [", name, rcs.len()).unwrap(); rcs.iter().for_each(|num| { writeln!( buf, - "FieldElement::from_mont([{}]),", - num.into_mont().map(|ele| format!("{ele}")).join(",") + "Felt::from_raw([{}]),", + num.to_raw().map(|ele| format!("{ele}")).join(",") ) .unwrap(); }); diff --git a/starknet-crypto/Cargo.toml b/starknet-crypto/Cargo.toml index 8a90ca80..2a9e285d 100644 --- a/starknet-crypto/Cargo.toml +++ b/starknet-crypto/Cargo.toml @@ -16,21 +16,21 @@ exclude = ["test-data/**"] [dependencies] starknet-crypto-codegen = { version = "0.3.3", path = "../starknet-crypto-codegen" } starknet-curve = { version = "0.4.2", path = "../starknet-curve" } -starknet-ff = { version = "0.3.7", path = "../starknet-ff", default-features = false } crypto-bigint = { version = "0.5.1", default-features = false, features = ["generic-array", "zeroize"] } hmac = { version = "0.12.1", default-features = false } num-bigint = { version = "0.4.3", default-features = false } num-integer = { version = "0.1.45", default-features = false } -num-traits = { version = "0.2.15", default-features = false } +num-traits = { version = "0.2.18", default-features = false } rfc6979 = { version = "0.4.0", default-features = false } sha2 = { version = "0.10.6", default-features = false } zeroize = { version = "1.6.0", default-features = false } hex = { version = "0.4.3", default-features = false, optional = true } +starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve"] } [features] default = ["std", "signature-display"] std = [] -alloc = ["hex?/alloc"] +alloc = ["hex?/alloc", "starknet-types-core/alloc"] signature-display = ["dep:hex", "alloc"] [dev-dependencies] @@ -39,6 +39,7 @@ hex = "0.4.3" hex-literal = "0.4.1" serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0.96" +starknet-types-core = { version = "0.1.3", default-features = false, features = ["alloc"] } [target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen-test = "0.3.34" diff --git a/starknet-crypto/README.md b/starknet-crypto/README.md index 54fb2ff6..c4790d62 100644 --- a/starknet-crypto/README.md +++ b/starknet-crypto/README.md @@ -21,15 +21,15 @@ For instructions on running the benchmarks yourself, check out [this page](../BE ### Native ```log -ecdsa_get_public_key time: [52.416 µs 52.456 µs 52.506 µs] -ecdsa_recover time: [233.25 µs 234.29 µs 235.43 µs] -ecdsa_sign time: [87.730 µs 87.967 µs 88.211 µs] -ecdsa_verify time: [239.97 µs 240.65 µs 241.46 µs] -pedersen_hash time: [15.635 µs 15.668 µs 15.695 µs] -poseidon_hash time: [4.6606 µs 4.6828 µs 4.7052 µs] -poseidon_hash_single time: [4.7146 µs 4.7243 µs 4.7341 µs] -poseidon_hash_many time: [10.101 µs 10.419 µs 10.713 µs] -rfc6979_generate_k time: [4.7230 µs 4.7346 µs 4.7469 µs] +ecdsa_get_public_key time: [62.223 µs 62.231 µs 62.240 µs] +ecdsa_recover time: [253.15 µs 253.47 µs 254.13 µs] +ecdsa_sign time: [95.633 µs 95.649 µs 95.668 µs] +ecdsa_verify time: [255.70 µs 255.77 µs 255.84 µs] +pedersen_hash time: [13.021 µs 13.023 µs 13.024 µs] +poseidon_hash time: [5.0139 µs 5.0148 µs 5.0155 µs] +poseidon_hash_single time: [5.0239 µs 5.0381 µs 5.0543 µs] +poseidon_hash_many time: [10.077 µs 10.087 µs 10.100 µs] +rfc6979_generate_k time: [4.5806 µs 4.5821 µs 4.5836 µs] ``` ### WebAssembly @@ -46,15 +46,15 @@ wasmtime-cli 21.0.1 (cedf9aa0f 2024-05-22) `wasmtime` results: ```log -ecdsa_get_public_key time: [264.92 µs 265.06 µs 265.21 µs] -ecdsa_recover time: [921.34 µs 922.06 µs 922.88 µs] -ecdsa_sign time: [311.44 µs 311.58 µs 311.72 µs] -ecdsa_verify time: [916.04 µs 917.13 µs 918.73 µs] -pedersen_hash time: [71.713 µs 71.751 µs 71.795 µs] -poseidon_hash time: [19.333 µs 19.359 µs 19.381 µs] -poseidon_hash_single time: [19.223 µs 19.234 µs 19.245 µs] -poseidon_hash_many time: [39.004 µs 39.048 µs 39.089 µs] -rfc6979_generate_k time: [11.798 µs 11.807 µs 11.817 µs] +ecdsa_get_public_key time: [333.64 µs 334.07 µs 334.48 µs] +ecdsa_recover time: [1.1177 ms 1.1207 ms 1.1248 ms] +ecdsa_sign time: [386.33 µs 387.42 µs 388.68 µs] +ecdsa_verify time: [1.1246 ms 1.1280 ms 1.1320 ms] +pedersen_hash time: [64.934 µs 64.962 µs 64.993 µs] +poseidon_hash time: [20.745 µs 20.772 µs 20.825 µs] +poseidon_hash_single time: [20.790 µs 20.813 µs 20.837 µs] +poseidon_hash_many time: [41.878 µs 41.911 µs 41.945 µs] +rfc6979_generate_k time: [11.564 µs 11.566 µs 11.569 µs] ``` ## Credits diff --git a/starknet-crypto/benches/ecdsa_get_public_key.rs b/starknet-crypto/benches/ecdsa_get_public_key.rs index bbffb15e..77b4149e 100644 --- a/starknet-crypto/benches/ecdsa_get_public_key.rs +++ b/starknet-crypto/benches/ecdsa_get_public_key.rs @@ -1,11 +1,12 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use hex_literal::hex; -use starknet_crypto::{get_public_key, FieldElement}; +use starknet_crypto::get_public_key; +use starknet_types_core::felt::Felt; pub fn criterion_benchmark(c: &mut Criterion) { let private_key = hex!("04a724706e80e5ea88b9ee60a7ede83cbc2de27da0659bef2929381a298b672d"); - let private_key = FieldElement::from_bytes_be(&private_key).unwrap(); + let private_key = Felt::from_bytes_be(&private_key); c.bench_function("ecdsa_get_public_key", |b| { b.iter(|| { diff --git a/starknet-crypto/benches/ecdsa_recover.rs b/starknet-crypto/benches/ecdsa_recover.rs index 598e47cb..a59a852a 100644 --- a/starknet-crypto/benches/ecdsa_recover.rs +++ b/starknet-crypto/benches/ecdsa_recover.rs @@ -1,19 +1,14 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use starknet_crypto::{recover, sign, FieldElement}; +use starknet_crypto::{recover, sign}; +use starknet_types_core::felt::Felt; pub fn criterion_benchmark(c: &mut Criterion) { - let private_key = FieldElement::from_hex_be( - "0000000000000000000000000000000000000000000000000000000000000001", - ) - .unwrap(); - let message = FieldElement::from_hex_be( - "0000000000000000000000000000000000000000000000000000000000000001", - ) - .unwrap(); - let k = FieldElement::from_hex_be( - "0000000000000000000000000000000000000000000000000000000000000001", - ) - .unwrap(); + let private_key = + Felt::from_hex("0000000000000000000000000000000000000000000000000000000000000001").unwrap(); + let message = + Felt::from_hex("0000000000000000000000000000000000000000000000000000000000000001").unwrap(); + let k = + Felt::from_hex("0000000000000000000000000000000000000000000000000000000000000001").unwrap(); let signature = sign(&private_key, &message, &k).unwrap(); diff --git a/starknet-crypto/benches/ecdsa_sign.rs b/starknet-crypto/benches/ecdsa_sign.rs index 67a3cd2e..26351332 100644 --- a/starknet-crypto/benches/ecdsa_sign.rs +++ b/starknet-crypto/benches/ecdsa_sign.rs @@ -1,15 +1,16 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use hex_literal::hex; -use starknet_crypto::{sign, FieldElement}; +use starknet_crypto::sign; +use starknet_types_core::felt::Felt; pub fn criterion_benchmark(c: &mut Criterion) { let private_key = hex!("04a724706e80e5ea88b9ee60a7ede83cbc2de27da0659bef2929381a298b672d"); let message = hex!("010aaf60f545a5b9a55463fbb56f35dfdfe8010ff1d95283afe1b14e07cb8f61"); let k = hex!("075414c392c57a61417fc1702ad6fa83d12541690963915646617b59451972b3"); - let private_key = FieldElement::from_bytes_be(&private_key).unwrap(); - let message = FieldElement::from_bytes_be(&message).unwrap(); - let k = FieldElement::from_bytes_be(&k).unwrap(); + let private_key = Felt::from_bytes_be(&private_key); + let message = Felt::from_bytes_be(&message); + let k = Felt::from_bytes_be(&k); c.bench_function("ecdsa_sign", |b| { b.iter(|| { diff --git a/starknet-crypto/benches/ecdsa_verify.rs b/starknet-crypto/benches/ecdsa_verify.rs index 86f03b9a..744532e7 100644 --- a/starknet-crypto/benches/ecdsa_verify.rs +++ b/starknet-crypto/benches/ecdsa_verify.rs @@ -1,6 +1,7 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use hex_literal::hex; -use starknet_crypto::{verify, FieldElement}; +use starknet_crypto::verify; +use starknet_types_core::felt::Felt; pub fn criterion_benchmark(c: &mut Criterion) { let stark_key = hex!("0565ee8f4203a04fbd5de77c678bc3738538f35c0871e377cdc45fcfa79e6bd9"); @@ -8,10 +9,10 @@ pub fn criterion_benchmark(c: &mut Criterion) { let r_bytes = hex!("03879bf25e6919880960131bb3b614c40d942791f83dac999d28028824c2d712"); let s_bytes = hex!("01f2a4527241c802e0885cf3aeac5bdfdbb559c09a45e1b745addae358f6c03b"); - let stark_key = FieldElement::from_bytes_be(&stark_key).unwrap(); - let msg_hash = FieldElement::from_bytes_be(&msg_hash).unwrap(); - let r_bytes = FieldElement::from_bytes_be(&r_bytes).unwrap(); - let s_bytes = FieldElement::from_bytes_be(&s_bytes).unwrap(); + let stark_key = Felt::from_bytes_be(&stark_key); + let msg_hash = Felt::from_bytes_be(&msg_hash); + let r_bytes = Felt::from_bytes_be(&r_bytes); + let s_bytes = Felt::from_bytes_be(&s_bytes); c.bench_function("ecdsa_verify", |b| { b.iter(|| { diff --git a/starknet-crypto/benches/pedersen_hash.rs b/starknet-crypto/benches/pedersen_hash.rs index d3899037..cc6a3ff1 100644 --- a/starknet-crypto/benches/pedersen_hash.rs +++ b/starknet-crypto/benches/pedersen_hash.rs @@ -1,6 +1,7 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use hex_literal::hex; -use starknet_crypto::{pedersen_hash, FieldElement}; +use starknet_crypto::pedersen_hash; +use starknet_types_core::felt::Felt; // Benchmark taken from pathfinder for performance comparison: // https://github.com/eqlabs/pathfinder/blob/b091cb889e624897dbb0cbec3c1df9a9e411eb1e/crates/pedersen/benches/pedersen.rs @@ -9,8 +10,8 @@ pub fn criterion_benchmark(c: &mut Criterion) { let e0 = hex!("03d937c035c878245caf64531a5756109c53068da139362728feb561405371cb"); let e1 = hex!("0208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a"); - let e0 = FieldElement::from_bytes_be(&e0).unwrap(); - let e1 = FieldElement::from_bytes_be(&e1).unwrap(); + let e0 = Felt::from_bytes_be(&e0); + let e1 = Felt::from_bytes_be(&e1); c.bench_function("pedersen_hash", |b| { b.iter(|| { diff --git a/starknet-crypto/benches/poseidon_hash.rs b/starknet-crypto/benches/poseidon_hash.rs index c81a370f..b43d56e2 100644 --- a/starknet-crypto/benches/poseidon_hash.rs +++ b/starknet-crypto/benches/poseidon_hash.rs @@ -1,15 +1,16 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use hex_literal::hex; -use starknet_crypto::{poseidon_hash, poseidon_hash_many, poseidon_hash_single, FieldElement}; +use starknet_crypto::{poseidon_hash, poseidon_hash_many, poseidon_hash_single}; +use starknet_types_core::felt::Felt; pub fn criterion_benchmark(c: &mut Criterion) { let e0 = hex!("03d937c035c878245caf64531a5756109c53068da139362728feb561405371cb"); let e1 = hex!("0208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a"); let e2 = hex!("013126bb6143939a9da42c90ce6f4a48f8430f9955a62367571a348e9c65177c"); - let e0 = FieldElement::from_bytes_be(&e0).unwrap(); - let e1 = FieldElement::from_bytes_be(&e1).unwrap(); - let e2 = FieldElement::from_bytes_be(&e2).unwrap(); + let e0 = Felt::from_bytes_be(&e0); + let e1 = Felt::from_bytes_be(&e1); + let e2 = Felt::from_bytes_be(&e2); c.bench_function("poseidon_hash", |b| { b.iter(|| { diff --git a/starknet-crypto/benches/rfc6979_generate_k.rs b/starknet-crypto/benches/rfc6979_generate_k.rs index e28c28e7..ddcb93cc 100644 --- a/starknet-crypto/benches/rfc6979_generate_k.rs +++ b/starknet-crypto/benches/rfc6979_generate_k.rs @@ -1,15 +1,16 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use hex_literal::hex; -use starknet_crypto::{rfc6979_generate_k, FieldElement}; +use starknet_crypto::rfc6979_generate_k; +use starknet_types_core::felt::Felt; pub fn criterion_benchmark(c: &mut Criterion) { let message_hash = hex!("010b559a3b4dc1b7137d90521cb413b397ff07963214d128a92d65aec7182f68"); let private_key = hex!("07e3184f4bef18f371bc53fc412dff1b30dbc94f758490fb8e2349bae647a642"); let seed = hex!("03fe27199aaad4e700559e2436a919f4de70def585a6deb2f4c087fdf6a27c1b"); - let message_hash = FieldElement::from_bytes_be(&message_hash).unwrap(); - let private_key = FieldElement::from_bytes_be(&private_key).unwrap(); - let seed = FieldElement::from_bytes_be(&seed).unwrap(); + let message_hash = Felt::from_bytes_be(&message_hash); + let private_key = Felt::from_bytes_be(&private_key); + let seed = Felt::from_bytes_be(&seed); c.bench_function("rfc6979_generate_k", |b| { b.iter(|| { diff --git a/starknet-crypto/src/ecdsa.rs b/starknet-crypto/src/ecdsa.rs index 38673941..ea5c4f7c 100644 --- a/starknet-crypto/src/ecdsa.rs +++ b/starknet-crypto/src/ecdsa.rs @@ -1,38 +1,37 @@ -use starknet_curve::{ - curve_params::{EC_ORDER, GENERATOR}, - AffinePoint, ProjectivePoint, -}; +use starknet_curve::curve_params::{ALPHA, BETA, EC_ORDER, GENERATOR}; use crate::{ fe_utils::{add_unbounded, bigint_mul_mod_floor, mod_inverse, mul_mod_floor}, - FieldElement, RecoverError, SignError, VerifyError, + RecoverError, SignError, VerifyError, }; +use starknet_types_core::curve::{AffinePoint, ProjectivePoint}; +use starknet_types_core::felt::Felt; -const ELEMENT_UPPER_BOUND: FieldElement = FieldElement::from_mont([ - 18446743986131435553, - 160989183, - 18446744073709255680, +const ELEMENT_UPPER_BOUND: Felt = Felt::from_raw([ 576459263475450960, + 18446744073709255680, + 160989183, + 18446743986131435553, ]); /// Stark ECDSA signature #[derive(Debug)] pub struct Signature { /// The `r` value of a signature - pub r: FieldElement, + pub r: Felt, /// The `s` value of a signature - pub s: FieldElement, + pub s: Felt, } /// Stark ECDSA signature with `v` #[derive(Debug)] pub struct ExtendedSignature { /// The `r` value of a signature - pub r: FieldElement, + pub r: Felt, /// The `s` value of a signature - pub s: FieldElement, + pub s: Felt, /// The `v` value of a signature - pub v: FieldElement, + pub v: Felt, } impl From for Signature { @@ -74,8 +73,11 @@ impl core::fmt::Display for ExtendedSignature { /// ### Arguments /// /// * `private_key`: The private key -pub fn get_public_key(private_key: &FieldElement) -> FieldElement { - mul_by_bits(&GENERATOR, private_key).x +pub fn get_public_key(private_key: &Felt) -> Felt { + mul_by_bits(&GENERATOR, private_key) + .to_affine() + .unwrap() + .x() } /// Computes ECDSA signature given a Stark private key and message hash. @@ -85,21 +87,17 @@ pub fn get_public_key(private_key: &FieldElement) -> FieldElement { /// * `private_key`: The private key /// * `message`: The message hash /// * `k`: A random `k` value. You **MUST NOT** use the same `k` on different signatures -pub fn sign( - private_key: &FieldElement, - message: &FieldElement, - k: &FieldElement, -) -> Result { +pub fn sign(private_key: &Felt, message: &Felt, k: &Felt) -> Result { if message >= &ELEMENT_UPPER_BOUND { return Err(SignError::InvalidMessageHash); } - if k == &FieldElement::ZERO { + if k == &Felt::ZERO { return Err(SignError::InvalidK); } - let full_r = mul_by_bits(&GENERATOR, k); - let r = full_r.x; - if r == FieldElement::ZERO || r >= ELEMENT_UPPER_BOUND { + let full_r = mul_by_bits(&GENERATOR, k).to_affine().unwrap(); + let r = full_r.x(); + if r == Felt::ZERO || r >= ELEMENT_UPPER_BOUND { return Err(SignError::InvalidK); } @@ -108,13 +106,15 @@ pub fn sign( let s = mul_mod_floor(&r, private_key, &EC_ORDER); let s = add_unbounded(&s, message); let s = bigint_mul_mod_floor(s, &k_inv, &EC_ORDER); - if s == FieldElement::ZERO || s >= ELEMENT_UPPER_BOUND { + if s == Felt::ZERO || s >= ELEMENT_UPPER_BOUND { return Err(SignError::InvalidK); } - let v = full_r.y & FieldElement::ONE; - - Ok(ExtendedSignature { r, s, v }) + Ok(ExtendedSignature { + r, + s, + v: (full_r.y().to_bigint() & Felt::ONE.to_bigint()).into(), + }) } /// Verifies if a signature is valid over a message hash given a public key. Returns an error @@ -126,29 +126,27 @@ pub fn sign( /// * `message`: The message hash /// * `r`: The `r` value of the signature /// * `s`: The `s` value of the signature -pub fn verify( - public_key: &FieldElement, - message: &FieldElement, - r: &FieldElement, - s: &FieldElement, -) -> Result { +pub fn verify(public_key: &Felt, message: &Felt, r: &Felt, s: &Felt) -> Result { if message >= &ELEMENT_UPPER_BOUND { return Err(VerifyError::InvalidMessageHash); } - if r == &FieldElement::ZERO || r >= &ELEMENT_UPPER_BOUND { + if r == &Felt::ZERO || r >= &ELEMENT_UPPER_BOUND { return Err(VerifyError::InvalidR); } - if s == &FieldElement::ZERO || s >= &ELEMENT_UPPER_BOUND { + if s == &Felt::ZERO || s >= &ELEMENT_UPPER_BOUND { return Err(VerifyError::InvalidS); } - let full_public_key = match AffinePoint::from_x(*public_key) { - Some(value) => value, - None => return Err(VerifyError::InvalidPublicKey), - }; + let full_public_key = AffinePoint::new( + *public_key, + (public_key.square() * public_key + ALPHA * public_key + BETA) + .sqrt() + .ok_or(VerifyError::InvalidPublicKey)?, + ) + .unwrap(); let w = mod_inverse(s, &EC_ORDER); - if w == FieldElement::ZERO || w >= ELEMENT_UPPER_BOUND { + if w == Felt::ZERO || w >= ELEMENT_UPPER_BOUND { return Err(VerifyError::InvalidS); } @@ -158,7 +156,8 @@ pub fn verify( let rw = mul_mod_floor(r, &w, &EC_ORDER); let rw_q = mul_by_bits(&full_public_key, &rw); - Ok((&zw_g + &rw_q).x == *r || (&zw_g - &rw_q).x == *r) + Ok((&zw_g + &rw_q).to_affine().unwrap().x() == *r + || (&zw_g - &rw_q).to_affine().unwrap().x() == *r) } /// Recovers the public key from a message and (r, s, v) signature parameters @@ -169,47 +168,61 @@ pub fn verify( /// * `r_bytes`: The `r` value of the signature /// * `s_bytes`: The `s` value of the signature /// * `v_bytes`: The `v` value of the signature -pub fn recover( - message: &FieldElement, - r: &FieldElement, - s: &FieldElement, - v: &FieldElement, -) -> Result { +pub fn recover(message: &Felt, r: &Felt, s: &Felt, v: &Felt) -> Result { if message >= &ELEMENT_UPPER_BOUND { return Err(RecoverError::InvalidMessageHash); } - if r == &FieldElement::ZERO || r >= &ELEMENT_UPPER_BOUND { + if r == &Felt::ZERO || r >= &ELEMENT_UPPER_BOUND { return Err(RecoverError::InvalidR); } - if s == &FieldElement::ZERO || s >= &EC_ORDER { + if s == &Felt::ZERO || s >= &EC_ORDER { return Err(RecoverError::InvalidS); } - if v > &FieldElement::ONE { + if v > &Felt::ONE { return Err(RecoverError::InvalidV); } - let mut full_r = AffinePoint::from_x(*r).ok_or(RecoverError::InvalidR)?; - if (full_r.y & FieldElement::ONE) != *v { - full_r.y = -full_r.y; + let full_r = AffinePoint::new( + *r, + (r * r * r + ALPHA * r + BETA) + .sqrt() + .ok_or(RecoverError::InvalidR)?, + ) + .unwrap(); + + let mut full_r_y = full_r.y(); + + let mut bits = [false; 256]; + + for (i, (&a, &b)) in full_r + .y() + .to_bits_le() + .iter() + .zip(Felt::ONE.to_bits_le().iter()) + .enumerate() + { + bits[i] = a && b; } - let full_rs = mul_by_bits(&full_r, s); + + if bits != v.to_bits_le() { + full_r_y = -full_r.y(); + } + + let full_rs = mul_by_bits(&AffinePoint::new(full_r.x(), full_r_y).unwrap(), s); let zg = mul_by_bits(&GENERATOR, message); let r_inv = mod_inverse(r, &EC_ORDER); let rs_zg = &full_rs - &zg; - let k = mul_by_bits(&rs_zg, &r_inv); + let k = mul_by_bits(&rs_zg.to_affine().unwrap(), &r_inv); - Ok(k.x) + Ok(k.to_affine().unwrap().x()) } #[inline(always)] -fn mul_by_bits(x: &AffinePoint, y: &FieldElement) -> AffinePoint { - let x = ProjectivePoint::from_affine_point(x); - let y = y.to_bits_le(); - let z = &x * &y; - AffinePoint::from(&z) +fn mul_by_bits(x: &AffinePoint, y: &Felt) -> ProjectivePoint { + &ProjectivePoint::from_affine(x.x(), x.y()).unwrap() * *y } #[cfg(test)] diff --git a/starknet-crypto/src/fe_utils.rs b/starknet-crypto/src/fe_utils.rs index 7fe285c6..6efa5ce7 100644 --- a/starknet-crypto/src/fe_utils.rs +++ b/starknet-crypto/src/fe_utils.rs @@ -4,33 +4,25 @@ use num_bigint::BigInt; use num_integer::Integer; use num_traits::{One, Zero}; -use crate::FieldElement; +use starknet_types_core::felt::Felt; // These are inefficient and crappy implementations of crypto math operations because I have // absolutely no idea how to do them without using `num-bigint`. But hey it works!!! // // Contributions are welcome. Please help us get rid of this junk :) -pub fn add_unbounded(augend: &FieldElement, addend: &FieldElement) -> BigInt { +pub fn add_unbounded(augend: &Felt, addend: &Felt) -> BigInt { let augend = BigInt::from_bytes_be(num_bigint::Sign::Plus, &augend.to_bytes_be()); let addend = BigInt::from_bytes_be(num_bigint::Sign::Plus, &addend.to_bytes_be()); augend.add(addend) } -pub fn mul_mod_floor( - multiplicand: &FieldElement, - multiplier: &FieldElement, - modulus: &FieldElement, -) -> FieldElement { +pub fn mul_mod_floor(multiplicand: &Felt, multiplier: &Felt, modulus: &Felt) -> Felt { let multiplicand = BigInt::from_bytes_be(num_bigint::Sign::Plus, &multiplicand.to_bytes_be()); bigint_mul_mod_floor(multiplicand, multiplier, modulus) } -pub fn bigint_mul_mod_floor( - multiplicand: BigInt, - multiplier: &FieldElement, - modulus: &FieldElement, -) -> FieldElement { +pub fn bigint_mul_mod_floor(multiplicand: BigInt, multiplier: &Felt, modulus: &Felt) -> Felt { let multiplier = BigInt::from_bytes_be(num_bigint::Sign::Plus, &multiplier.to_bytes_be()); let modulus = BigInt::from_bytes_be(num_bigint::Sign::Plus, &modulus.to_bytes_be()); @@ -40,10 +32,10 @@ pub fn bigint_mul_mod_floor( let mut result = [0u8; 32]; result[(32 - buffer.len())..].copy_from_slice(&buffer[..]); - FieldElement::from_bytes_be(&result).unwrap() + Felt::from_bytes_be(&result) } -pub fn mod_inverse(operand: &FieldElement, modulus: &FieldElement) -> FieldElement { +pub fn mod_inverse(operand: &Felt, modulus: &Felt) -> Felt { let operand = BigInt::from_bytes_be(num_bigint::Sign::Plus, &operand.to_bytes_be()); let modulus = BigInt::from_bytes_be(num_bigint::Sign::Plus, &modulus.to_bytes_be()); @@ -63,5 +55,5 @@ pub fn mod_inverse(operand: &FieldElement, modulus: &FieldElement) -> FieldEleme let mut result = [0u8; 32]; result[(32 - buffer.len())..].copy_from_slice(&buffer[..]); - FieldElement::from_bytes_be(&result).unwrap() + Felt::from_bytes_be(&result) } diff --git a/starknet-crypto/src/lib.rs b/starknet-crypto/src/lib.rs index 2dd3182f..16470b64 100644 --- a/starknet-crypto/src/lib.rs +++ b/starknet-crypto/src/lib.rs @@ -15,7 +15,7 @@ mod rfc6979; #[cfg(test)] mod test_utils; -pub use starknet_ff::FieldElement; +pub use starknet_types_core::felt::Felt; pub use pedersen_hash::pedersen_hash; diff --git a/starknet-crypto/src/pedersen_hash.rs b/starknet-crypto/src/pedersen_hash.rs index 87ab7ca8..a5026750 100644 --- a/starknet-crypto/src/pedersen_hash.rs +++ b/starknet-crypto/src/pedersen_hash.rs @@ -1,17 +1,16 @@ -use starknet_curve::{curve_params, AffinePoint, ProjectivePoint}; -use starknet_ff::FieldElement; +use starknet_curve::curve_params; +use starknet_types_core::curve::{AffinePoint, ProjectivePoint}; +use starknet_types_core::felt::Felt; use crate::pedersen_points::*; -const SHIFT_POINT: ProjectivePoint = ProjectivePoint::from_affine_point(&curve_params::SHIFT_POINT); - /// Computes the Starkware version of the Pedersen hash of x and y. All inputs are little-endian. /// /// ### Arguments /// /// * `x`: The x coordinate /// * `y`: The y coordinate -pub fn pedersen_hash(x: &FieldElement, y: &FieldElement) -> FieldElement { +pub fn pedersen_hash(x: &Felt, y: &Felt) -> Felt { let x = x.to_bits_le(); let y = y.to_bits_le(); @@ -25,7 +24,6 @@ pub fn pedersen_hash(x: &FieldElement, y: &FieldElement) -> FieldElement { .iter() .rev() .fold(0, |acc, &bit| (acc << 1) + bit as usize); - if offset > 0 { // Table lookup at 'offset-1' in table for chunk 'i' *acc += &prep[i * table_size + offset - 1]; @@ -34,14 +32,20 @@ pub fn pedersen_hash(x: &FieldElement, y: &FieldElement) -> FieldElement { }; // Compute hash - let mut acc = SHIFT_POINT; + let mut acc = + ProjectivePoint::from_affine(curve_params::SHIFT_POINT.x(), curve_params::SHIFT_POINT.y()) + .unwrap(); + add_points(&mut acc, &x[..248], &CURVE_CONSTS_P0); // Add a_low * P1 add_points(&mut acc, &x[248..252], &CURVE_CONSTS_P1); // Add a_high * P2 add_points(&mut acc, &y[..248], &CURVE_CONSTS_P2); // Add b_low * P3 add_points(&mut acc, &y[248..252], &CURVE_CONSTS_P3); // Add b_high * P4 + // Convert to affine + let result = acc.to_affine().unwrap(); + // Return x-coordinate - AffinePoint::from(&acc).x + result.x() } #[cfg(test)] diff --git a/starknet-crypto/src/poseidon_hash.rs b/starknet-crypto/src/poseidon_hash.rs index 235cc829..c8b15bd9 100644 --- a/starknet-crypto/src/poseidon_hash.rs +++ b/starknet-crypto/src/poseidon_hash.rs @@ -2,7 +2,7 @@ // https://github.com/eqlabs/pathfinder/blob/00a1a74a90a7b8a7f1d07ac3e616be1cb39cf8f1/crates/stark_poseidon/src/lib.rs use starknet_crypto_codegen::poseidon_consts; -use starknet_ff::FieldElement; +use starknet_types_core::felt::Felt; poseidon_consts!(); @@ -11,8 +11,8 @@ poseidon_consts!(); /// Using this hasher is the same as calling [poseidon_hash_many]. #[derive(Debug, Default)] pub struct PoseidonHasher { - state: [FieldElement; 3], - buffer: Option, + state: [Felt; 3], + buffer: Option, } impl PoseidonHasher { @@ -22,7 +22,7 @@ impl PoseidonHasher { } /// Absorbs message into the hash. - pub fn update(&mut self, msg: FieldElement) { + pub fn update(&mut self, msg: Felt) { match self.buffer.take() { Some(previous_message) => { self.state[0] += previous_message; @@ -36,15 +36,15 @@ impl PoseidonHasher { } /// Finishes and returns hash. - pub fn finalize(mut self) -> FieldElement { + pub fn finalize(mut self) -> Felt { // Applies padding match self.buffer.take() { Some(last_message) => { self.state[0] += last_message; - self.state[1] += FieldElement::ONE; + self.state[1] += Felt::ONE; } None => { - self.state[0] += FieldElement::ONE; + self.state[0] += Felt::ONE; } } poseidon_permute_comp(&mut self.state); @@ -54,26 +54,26 @@ impl PoseidonHasher { } /// Computes the Starknet Poseidon hash of x and y. -pub fn poseidon_hash(x: FieldElement, y: FieldElement) -> FieldElement { - let mut state = [x, y, FieldElement::TWO]; +pub fn poseidon_hash(x: Felt, y: Felt) -> Felt { + let mut state = [x, y, Felt::TWO]; poseidon_permute_comp(&mut state); state[0] } -/// Computes the Starknet Poseidon hash of a single [FieldElement]. -pub fn poseidon_hash_single(x: FieldElement) -> FieldElement { - let mut state = [x, FieldElement::ZERO, FieldElement::ONE]; +/// Computes the Starknet Poseidon hash of a single [Felt]. +pub fn poseidon_hash_single(x: Felt) -> Felt { + let mut state = [x, Felt::ZERO, Felt::ONE]; poseidon_permute_comp(&mut state); state[0] } -/// Computes the Starknet Poseidon hash of an arbitrary number of [FieldElement]s. +/// Computes the Starknet Poseidon hash of an arbitrary number of [Felt]s. /// /// Using this function is the same as using [PoseidonHasher]. -pub fn poseidon_hash_many(msgs: &[FieldElement]) -> FieldElement { - let mut state = [FieldElement::ZERO, FieldElement::ZERO, FieldElement::ZERO]; +pub fn poseidon_hash_many(msgs: &[Felt]) -> Felt { + let mut state = [Felt::ZERO, Felt::ZERO, Felt::ZERO]; let mut iter = msgs.chunks_exact(2); for msg in iter.by_ref() { @@ -85,14 +85,14 @@ pub fn poseidon_hash_many(msgs: &[FieldElement]) -> FieldElement { if r.len() == 1 { state[0] += r[0]; } - state[r.len()] += FieldElement::ONE; + state[r.len()] += Felt::ONE; poseidon_permute_comp(&mut state); state[0] } /// Poseidon permutation function. -pub fn poseidon_permute_comp(state: &mut [FieldElement; 3]) { +pub fn poseidon_permute_comp(state: &mut [Felt; 3]) { let mut idx = 0; // Full rounds @@ -117,15 +117,15 @@ pub fn poseidon_permute_comp(state: &mut [FieldElement; 3]) { /// Linear layer for MDS matrix M = ((3,1,1), (1,-1,1), (1,1,2)) /// Given state vector x, it returns Mx, optimized by precomputing t. #[inline(always)] -fn mix(state: &mut [FieldElement; 3]) { +fn mix(state: &mut [Felt; 3]) { let t = state[0] + state[1] + state[2]; state[0] = t + state[0].double(); state[1] = t - state[1].double(); - state[2] = t - FieldElement::THREE * state[2]; + state[2] = t - Felt::THREE * state[2]; } #[inline] -fn round_comp(state: &mut [FieldElement; 3], idx: usize, full: bool) { +fn round_comp(state: &mut [Felt; 3], idx: usize, full: bool) { if full { state[0] += POSEIDON_COMP_CONSTS[idx]; state[1] += POSEIDON_COMP_CONSTS[idx + 1]; @@ -150,32 +150,20 @@ mod tests { // Test data generated from `cairo-lang` v0.11.0 let test_data = [ ( - FieldElement::from_hex_be( - "0xb662f9017fa7956fd70e26129b1833e10ad000fd37b4d9f4e0ce6884b7bbe", - ) - .unwrap(), - FieldElement::from_hex_be( - "0x1fe356bf76102cdae1bfbdc173602ead228b12904c00dad9cf16e035468bea", - ) - .unwrap(), - FieldElement::from_hex_be( - "0x75540825a6ecc5dc7d7c2f5f868164182742227f1367d66c43ee51ec7937a81", - ) - .unwrap(), + Felt::from_hex("0xb662f9017fa7956fd70e26129b1833e10ad000fd37b4d9f4e0ce6884b7bbe") + .unwrap(), + Felt::from_hex("0x1fe356bf76102cdae1bfbdc173602ead228b12904c00dad9cf16e035468bea") + .unwrap(), + Felt::from_hex("0x75540825a6ecc5dc7d7c2f5f868164182742227f1367d66c43ee51ec7937a81") + .unwrap(), ), ( - FieldElement::from_hex_be( - "0xf4e01b2032298f86b539e3d3ac05ced20d2ef275273f9325f8827717156529", - ) - .unwrap(), - FieldElement::from_hex_be( - "0x587bc46f5f58e0511b93c31134652a689d761a9e7f234f0f130c52e4679f3a", - ) - .unwrap(), - FieldElement::from_hex_be( - "0xbdb3180fdcfd6d6f172beb401af54dd71b6569e6061767234db2b777adf98b", - ) - .unwrap(), + Felt::from_hex("0xf4e01b2032298f86b539e3d3ac05ced20d2ef275273f9325f8827717156529") + .unwrap(), + Felt::from_hex("0x587bc46f5f58e0511b93c31134652a689d761a9e7f234f0f130c52e4679f3a") + .unwrap(), + Felt::from_hex("0xbdb3180fdcfd6d6f172beb401af54dd71b6569e6061767234db2b777adf98b") + .unwrap(), ), ]; @@ -190,24 +178,16 @@ mod tests { // Test data generated from `cairo-lang` v0.11.0 let test_data = [ ( - FieldElement::from_hex_be( - "0x9dad5d6f502ccbcb6d34ede04f0337df3b98936aaf782f4cc07d147e3a4fd6", - ) - .unwrap(), - FieldElement::from_hex_be( - "0x11222854783f17f1c580ff64671bc3868de034c236f956216e8ed4ab7533455", - ) - .unwrap(), + Felt::from_hex("0x9dad5d6f502ccbcb6d34ede04f0337df3b98936aaf782f4cc07d147e3a4fd6") + .unwrap(), + Felt::from_hex("0x11222854783f17f1c580ff64671bc3868de034c236f956216e8ed4ab7533455") + .unwrap(), ), ( - FieldElement::from_hex_be( - "0x3164a8e2181ff7b83391b4a86bc8967f145c38f10f35fc74e9359a0c78f7b6", - ) - .unwrap(), - FieldElement::from_hex_be( - "0x79ad7aa7b98d47705446fa01865942119026ac748d67a5840f06948bce2306b", - ) - .unwrap(), + Felt::from_hex("0x3164a8e2181ff7b83391b4a86bc8967f145c38f10f35fc74e9359a0c78f7b6") + .unwrap(), + Felt::from_hex("0x79ad7aa7b98d47705446fa01865942119026ac748d67a5840f06948bce2306b") + .unwrap(), ), ]; @@ -223,47 +203,43 @@ mod tests { let test_data = [ ( vec![ - FieldElement::from_hex_be( + Felt::from_hex( "0x9bf52404586087391c5fbb42538692e7ca2149bac13c145ae4230a51a6fc47", ) .unwrap(), - FieldElement::from_hex_be( + Felt::from_hex( "0x40304159ee9d2d611120fbd7c7fb8020cc8f7a599bfa108e0e085222b862c0", ) .unwrap(), - FieldElement::from_hex_be( + Felt::from_hex( "0x46286e4f3c450761d960d6a151a9c0988f9e16f8a48d4c0a85817c009f806a", ) .unwrap(), ], - FieldElement::from_hex_be( - "0x1ec38b38dc88bac7b0ed6ff6326f975a06a59ac601b417745fd412a5d38e4f7", - ) - .unwrap(), + Felt::from_hex("0x1ec38b38dc88bac7b0ed6ff6326f975a06a59ac601b417745fd412a5d38e4f7") + .unwrap(), ), ( vec![ - FieldElement::from_hex_be( + Felt::from_hex( "0xbdace8883922662601b2fd197bb660b081fcf383ede60725bd080d4b5f2fd3", ) .unwrap(), - FieldElement::from_hex_be( + Felt::from_hex( "0x1eb1daaf3fdad326b959dec70ced23649cdf8786537cee0c5758a1a4229097", ) .unwrap(), - FieldElement::from_hex_be( + Felt::from_hex( "0x869ca04071b779d6f940cdf33e62d51521e19223ab148ef571856ff3a44ff1", ) .unwrap(), - FieldElement::from_hex_be( + Felt::from_hex( "0x533e6df8d7c4b634b1f27035c8676a7439c635e1fea356484de7f0de677930", ) .unwrap(), ], - FieldElement::from_hex_be( - "0x2520b8f910174c3e650725baacad4efafaae7623c69a0b5513d75e500f36624", - ) - .unwrap(), + Felt::from_hex("0x2520b8f910174c3e650725baacad4efafaae7623c69a0b5513d75e500f36624") + .unwrap(), ), ]; diff --git a/starknet-crypto/src/rfc6979.rs b/starknet-crypto/src/rfc6979.rs index 5b2f5f60..af2897a9 100644 --- a/starknet-crypto/src/rfc6979.rs +++ b/starknet-crypto/src/rfc6979.rs @@ -1,10 +1,9 @@ use crypto_bigint::{ArrayEncoding, ByteArray, Integer, U256}; use hmac::digest::Digest; use sha2::digest::{crypto_common::BlockSizeUser, FixedOutputReset, HashMarker}; +use starknet_types_core::felt::Felt; use zeroize::{Zeroize, Zeroizing}; -use crate::FieldElement; - const EC_ORDER: U256 = U256::from_be_hex("0800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f"); @@ -15,11 +14,7 @@ const EC_ORDER: U256 = /// * `message_hash`: message hash /// * `private_key`: private key /// * `seed`: extra seed for additional entropy -pub fn generate_k( - message_hash: &FieldElement, - private_key: &FieldElement, - seed: Option<&FieldElement>, -) -> FieldElement { +pub fn generate_k(message_hash: &Felt, private_key: &Felt, seed: Option<&Felt>) -> Felt { // The message hash padding as implemented in `cairo-lang` is not needed here. The hash is // padded in `cairo-lang` only to make sure the lowest 4 bits won't get truncated, but here it's // never getting truncated anyways. @@ -49,7 +44,7 @@ pub fn generate_k( let mut buffer = [0u8; 32]; buffer[..].copy_from_slice(&k.to_be_byte_array()[..]); - FieldElement::from_bytes_be(&buffer).unwrap() + Felt::from_bytes_be(&buffer) } // Modified from upstream `rfc6979::generate_k` with a hard-coded right bit shift. The more diff --git a/starknet-crypto/src/test_utils.rs b/starknet-crypto/src/test_utils.rs index cbe0f8ef..b1e36f14 100644 --- a/starknet-crypto/src/test_utils.rs +++ b/starknet-crypto/src/test_utils.rs @@ -1,6 +1,6 @@ -use crate::FieldElement; +use starknet_types_core::felt::Felt; -pub fn field_element_from_be_hex(hex: &str) -> FieldElement { +pub fn field_element_from_be_hex(hex: &str) -> Felt { let decoded = hex::decode(hex.trim_start_matches("0x")).unwrap(); if decoded.len() > 32 { @@ -10,5 +10,5 @@ pub fn field_element_from_be_hex(hex: &str) -> FieldElement { let mut buffer = [0u8; 32]; buffer[(32 - decoded.len())..].copy_from_slice(&decoded[..]); - FieldElement::from_bytes_be(&buffer).unwrap() + Felt::from_bytes_be(&buffer) } diff --git a/starknet-curve/Cargo.toml b/starknet-curve/Cargo.toml index ed60a50d..ddefc7d4 100644 --- a/starknet-curve/Cargo.toml +++ b/starknet-curve/Cargo.toml @@ -13,4 +13,4 @@ Stark curve keywords = ["ethereum", "starknet", "web3", "no_std"] [dependencies] -starknet-ff = { version = "0.3.7", path = "../starknet-ff", default-features = false } +starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve"] } diff --git a/starknet-curve/src/curve_params.rs b/starknet-curve/src/curve_params.rs index c9938f7f..5368cbc4 100644 --- a/starknet-curve/src/curve_params.rs +++ b/starknet-curve/src/curve_params.rs @@ -1,116 +1,113 @@ -use starknet_ff::FieldElement; +use starknet_types_core::curve::AffinePoint; +use starknet_types_core::felt::Felt; -use crate::ec_point::AffinePoint; - -pub const EC_ORDER: FieldElement = FieldElement::from_mont([ - 8939893405601011193, - 1143265896874747514, - 9, +pub const EC_ORDER: Felt = Felt::from_raw([ 369010039416812937, + 9, + 1143265896874747514, + 8939893405601011193, ]); -pub const ALPHA: FieldElement = FieldElement::from_mont([ - 18446744073709551585, +pub const ALPHA: Felt = Felt::from_raw([ + 576460752303422960, 18446744073709551615, 18446744073709551615, - 576460752303422960, + 18446744073709551585, ]); -pub const BETA: FieldElement = FieldElement::from_mont([ - 3863487492851900874, - 7432612994240712710, - 12360725113329547591, +pub const BETA: Felt = Felt::from_raw([ 88155977965380735, + 12360725113329547591, + 7432612994240712710, + 3863487492851900874, ]); -pub const GENERATOR: AffinePoint = AffinePoint { - x: FieldElement::from_mont([ - 14484022957141291997, - 5884444832209845738, - 299981207024966779, +pub const GENERATOR: AffinePoint = AffinePoint::new_unchecked( + Felt::from_raw([ 232005955912912577, + 299981207024966779, + 5884444832209845738, + 14484022957141291997, ]), - y: FieldElement::from_mont([ - 6241159653446987914, - 664812301889158119, - 18147424675297964973, + Felt::from_raw([ 405578048423154473, + 18147424675297964973, + 664812301889158119, + 6241159653446987914, ]), - infinity: false, -}; +); -pub const SHIFT_POINT: AffinePoint = AffinePoint { - x: FieldElement::from_mont([ - 1933903796324928314, - 7739989395386261137, - 1641324389046377921, +pub const SHIFT_POINT: AffinePoint = AffinePoint::new_unchecked( + Felt::from_raw([ 316327189671755572, + 1641324389046377921, + 7739989395386261137, + 1933903796324928314, ]), - y: FieldElement::from_mont([ - 14252083571674603243, - 12587053260418384210, - 4798858472748676776, + Felt::from_raw([ 81375596133053150, + 4798858472748676776, + 12587053260418384210, + 14252083571674603243, ]), - infinity: false, -}; -pub const PEDERSEN_P0: AffinePoint = AffinePoint { - x: FieldElement::from_mont([ - 3602345268353203007, - 13758484295849329960, - 518715844721862878, +); + +pub const PEDERSEN_P0: AffinePoint = AffinePoint::new_unchecked( + Felt::from_raw([ 241691544791834578, + 518715844721862878, + 13758484295849329960, + 3602345268353203007, ]), - y: FieldElement::from_mont([ - 13441546676070136227, - 13001553326386915570, - 433857700841878496, + Felt::from_raw([ 368891789801938570, + 433857700841878496, + 13001553326386915570, + 13441546676070136227, ]), - infinity: false, -}; -pub const PEDERSEN_P1: AffinePoint = AffinePoint { - x: FieldElement::from_mont([ - 16491878934996302286, - 12382025591154462459, - 10043949394709899044, +); + +pub const PEDERSEN_P1: AffinePoint = AffinePoint::new_unchecked( + Felt::from_raw([ 253000153565733272, + 10043949394709899044, + 12382025591154462459, + 16491878934996302286, ]), - y: FieldElement::from_mont([ - 13950428914333633429, - 2545498000137298346, - 5191292837124484988, + Felt::from_raw([ 285630633187035523, + 5191292837124484988, + 2545498000137298346, + 13950428914333633429, ]), - infinity: false, -}; -pub const PEDERSEN_P2: AffinePoint = AffinePoint { - x: FieldElement::from_mont([ - 1203723169299412240, - 18195981508842736832, - 12916675983929588442, +); + +pub const PEDERSEN_P2: AffinePoint = AffinePoint::new_unchecked( + Felt::from_raw([ 338510149841406402, + 12916675983929588442, + 18195981508842736832, + 1203723169299412240, ]), - y: FieldElement::from_mont([ - 12352616181161700245, - 11743524503750604092, - 11088962269971685343, + Felt::from_raw([ 161068411212710156, + 11088962269971685343, + 11743524503750604092, + 12352616181161700245, ]), - infinity: false, -}; -pub const PEDERSEN_P3: AffinePoint = AffinePoint { - x: FieldElement::from_mont([ - 1145636535101238356, - 10664803185694787051, - 299781701614706065, +); + +pub const PEDERSEN_P3: AffinePoint = AffinePoint::new_unchecked( + Felt::from_raw([ 425493972656615276, + 299781701614706065, + 10664803185694787051, + 1145636535101238356, ]), - y: FieldElement::from_mont([ - 8187986478389849302, - 4428713245976508844, - 6033691581221864148, + Felt::from_raw([ 345457391846365716, + 6033691581221864148, + 4428713245976508844, + 8187986478389849302, ]), - infinity: false, -}; +); diff --git a/starknet-curve/src/ec_point.rs b/starknet-curve/src/ec_point.rs deleted file mode 100644 index 6500480e..00000000 --- a/starknet-curve/src/ec_point.rs +++ /dev/null @@ -1,296 +0,0 @@ -use starknet_ff::FieldElement; - -use crate::curve_params::{ALPHA, BETA}; - -use core::ops; - -/// A point on an elliptic curve over [FieldElement]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct AffinePoint { - pub x: FieldElement, - pub y: FieldElement, - pub infinity: bool, -} - -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct ProjectivePoint { - pub x: FieldElement, - pub y: FieldElement, - pub z: FieldElement, - pub infinity: bool, -} - -impl AffinePoint { - pub fn from_x(x: FieldElement) -> Option { - let y_squared = x * x * x + ALPHA * x + BETA; - y_squared.sqrt().map(|y| Self { - x, - y, - infinity: false, - }) - } - - fn identity() -> AffinePoint { - Self { - x: FieldElement::ZERO, - y: FieldElement::ZERO, - infinity: true, - } - } - - pub fn double_assign(&mut self) { - if self.infinity { - return; - } - - // l = (3x^2+a)/2y with a=1 from stark curve - let lambda = { - let dividend = FieldElement::THREE * (self.x * self.x) + FieldElement::ONE; - let divisor_inv = self.y.double().invert().unwrap(); - dividend * divisor_inv - }; - - let result_x = (lambda * lambda) - self.x - self.x; - self.y = lambda * (self.x - result_x) - self.y; - self.x = result_x; - } -} - -impl From<&ProjectivePoint> for AffinePoint { - fn from(p: &ProjectivePoint) -> Self { - let zinv = p.z.invert().unwrap(); - Self { - x: p.x * zinv, - y: p.y * zinv, - infinity: false, - } - } -} - -impl ops::Add<&AffinePoint> for &AffinePoint { - type Output = AffinePoint; - - fn add(self, rhs: &AffinePoint) -> Self::Output { - let mut copy = *self; - copy += rhs; - copy - } -} - -impl ops::AddAssign<&AffinePoint> for AffinePoint { - fn add_assign(&mut self, rhs: &AffinePoint) { - if rhs.infinity { - return; - } - if self.infinity { - *self = *rhs; - return; - } - if self.x == rhs.x { - if self.y == rhs.y { - self.double_assign(); - } else { - *self = AffinePoint::identity(); - } - return; - } - - let lambda = (rhs.y - self.y) * (rhs.x - self.x).invert().unwrap(); - - let result_x = lambda * lambda - self.x - rhs.x; - - self.y = lambda * (self.x - result_x) - self.y; - self.x = result_x; - } -} - -impl ops::Neg for &AffinePoint { - type Output = AffinePoint; - - fn neg(self) -> AffinePoint { - AffinePoint { - x: self.x, - y: -self.y, - infinity: self.infinity, - } - } -} - -impl ops::Sub<&AffinePoint> for &AffinePoint { - type Output = AffinePoint; - - fn sub(self, rhs: &AffinePoint) -> Self::Output { - let mut copy = *self; - copy -= rhs; - copy - } -} - -impl ops::SubAssign<&AffinePoint> for AffinePoint { - fn sub_assign(&mut self, rhs: &AffinePoint) { - *self += &-rhs; - } -} - -impl ops::Mul<&[bool]> for &AffinePoint { - type Output = AffinePoint; - - #[allow(clippy::suspicious_arithmetic_impl)] - fn mul(self, rhs: &[bool]) -> Self::Output { - let mut product = AffinePoint::identity(); - for b in rhs.iter().rev().skip_while(|b| !*b) { - product.double_assign(); - if *b { - product += self; - } - } - - product - } -} - -impl ProjectivePoint { - pub const fn from_affine_point(p: &AffinePoint) -> Self { - Self { - x: p.x, - y: p.y, - z: FieldElement::ONE, - infinity: p.infinity, - } - } - - fn identity() -> ProjectivePoint { - Self { - x: FieldElement::ZERO, - y: FieldElement::ZERO, - z: FieldElement::ONE, - infinity: true, - } - } - - pub fn double_assign(&mut self) { - if self.infinity { - return; - } - - // t=3x^2+az^2 with a=1 from stark curve - let t = FieldElement::THREE * self.x * self.x + self.z * self.z; - let u = self.y.double() * self.z; - let v = u.double() * self.x * self.y; - let w = t * t - v.double(); - - let uy = u * self.y; - - let x = u * w; - let y = t * (v - w) - (uy * uy).double(); - let z = u * u * u; - - self.x = x; - self.y = y; - self.z = z; - } -} - -impl From<&AffinePoint> for ProjectivePoint { - fn from(p: &AffinePoint) -> Self { - Self::from_affine_point(p) - } -} - -impl ops::AddAssign<&AffinePoint> for ProjectivePoint { - fn add_assign(&mut self, rhs: &AffinePoint) { - if rhs.infinity { - return; - } - if self.infinity { - *self = Self::from_affine_point(rhs); - return; - } - let u0 = self.x; - let u1 = rhs.x * self.z; - let t0 = self.y; - let t1 = rhs.y * self.z; - if u0 == u1 { - if t0 != t1 { - self.infinity = true; - } else { - self.double_assign(); - } - return; - } - - let t = t0 - t1; - let u = u0 - u1; - let u2 = u * u; - - let v = self.z; - let w = t * t * v - u2 * (u0 + u1); - let u3 = u * u2; - - let x = u * w; - let y = t * (u0 * u2 - w) - t0 * u3; - let z = u3 * v; - - self.x = x; - self.y = y; - self.z = z; - } -} - -impl ops::AddAssign<&ProjectivePoint> for ProjectivePoint { - fn add_assign(&mut self, rhs: &ProjectivePoint) { - if rhs.infinity { - return; - } - if self.infinity { - *self = *rhs; - return; - } - let u0 = self.x * rhs.z; - let u1 = rhs.x * self.z; - if u0 == u1 { - if self.y == rhs.y { - self.double_assign(); - } else { - *self = ProjectivePoint::identity(); - } - return; - } - - let t0 = self.y * rhs.z; - let t1 = rhs.y * self.z; - let t = t0 - t1; - - let u = u0 - u1; - let u2 = u * u; - - let v = self.z * rhs.z; - let w = t * t * v - u2 * (u0 + u1); - let u3 = u * u2; - - let x = u * w; - let y = t * (u0 * u2 - w) - t0 * u3; - let z = u3 * v; - - self.x = x; - self.y = y; - self.z = z; - } -} - -impl ops::Mul<&[bool]> for &ProjectivePoint { - type Output = ProjectivePoint; - - #[allow(clippy::suspicious_arithmetic_impl)] - fn mul(self, rhs: &[bool]) -> Self::Output { - let mut product = ProjectivePoint::identity(); - for b in rhs.iter().rev().skip_while(|b| !*b) { - product.double_assign(); - if *b { - product += self; - } - } - - product - } -} diff --git a/starknet-curve/src/lib.rs b/starknet-curve/src/lib.rs index d053fdef..a092b315 100644 --- a/starknet-curve/src/lib.rs +++ b/starknet-curve/src/lib.rs @@ -1,7 +1,4 @@ #![no_std] #![doc = include_str!("../README.md")] -mod ec_point; - pub mod curve_params; -pub use ec_point::{AffinePoint, ProjectivePoint}; diff --git a/starknet-ff/Cargo.toml b/starknet-ff/Cargo.toml deleted file mode 100644 index 29cc9d73..00000000 --- a/starknet-ff/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "starknet-ff" -version = "0.3.7" -authors = ["Jonathan LEI "] -license = "MIT OR Apache-2.0" -edition = "2021" -readme = "README.md" -repository = "https://github.com/xJonathanLEI/starknet-rs" -homepage = "https://starknet.rs/" -description = """ -Starknet field element type -""" -keywords = ["ethereum", "starknet", "web3", "no_std"] - -[package.metadata.docs.rs] -all-features = true - -[dependencies] -ark-ff = { version = "0.4.2", default-features = false } -crypto-bigint = { version = "0.5.1", default-features = false } -hex = { version = "0.4.3", default-features = false } -serde = { version = "1.0.160", optional = true, default-features = false } -bigdecimal = { version = "0.3.0", optional = true } -num-bigint = { version = "0.4.3", optional = true, default-features = false } - - -[features] -default = ["std", "serde"] -std = [] -alloc = ["serde?/alloc"] -serde = ["dep:serde", "alloc", "bigdecimal?/serde"] -bigdecimal = ["std", "dep:bigdecimal", "dep:num-bigint"] - -[target.'cfg(target_arch = "wasm32")'.dependencies] -getrandom = { version = "0.2.9", features = ["js"] } - -[target.'cfg(target_arch = "wasm32")'.dev-dependencies] -wasm-bindgen-test = "0.3.34" diff --git a/starknet-ff/README.md b/starknet-ff/README.md deleted file mode 100644 index d29502f2..00000000 --- a/starknet-ff/README.md +++ /dev/null @@ -1 +0,0 @@ -# Starknet field element type diff --git a/starknet-ff/src/fr.rs b/starknet-ff/src/fr.rs deleted file mode 100644 index 854c06c2..00000000 --- a/starknet-ff/src/fr.rs +++ /dev/null @@ -1,8 +0,0 @@ -use ark_ff::fields::{Fp256, MontBackend, MontConfig}; - -pub type Fr = Fp256>; - -#[derive(MontConfig)] -#[modulus = "3618502788666131213697322783095070105623107215331596699973092056135872020481"] -#[generator = "3"] -pub struct FrConfig; diff --git a/starknet-ff/src/lib.rs b/starknet-ff/src/lib.rs deleted file mode 100644 index 706bbcf2..00000000 --- a/starknet-ff/src/lib.rs +++ /dev/null @@ -1,1110 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] -#![allow(clippy::comparison_chain)] - -#[cfg(all(not(feature = "std"), any(test, feature = "alloc")))] -#[cfg_attr(test, macro_use)] -extern crate alloc; - -use core::{ - fmt, ops, - str::{self, FromStr}, -}; - -use crate::fr::Fr; - -use ark_ff::{ - fields::{Field, Fp256, PrimeField}, - BigInteger, BigInteger256, -}; -use crypto_bigint::{CheckedAdd, CheckedMul, NonZero, Zero, U256}; - -mod fr; - -const U256_BYTE_COUNT: usize = 32; - -#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] -pub struct FieldElement { - inner: Fr, -} - -mod from_str_error { - - #[derive(Debug)] - pub enum FromStrError { - InvalidCharacter, - OutOfRange, - } - - #[cfg(feature = "std")] - impl std::error::Error for FromStrError {} - - impl core::fmt::Display for FromStrError { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Self::InvalidCharacter => write!(f, "invalid character"), - Self::OutOfRange => write!(f, "number out of range"), - } - } - } -} -pub use from_str_error::FromStrError; - -mod from_bytes_slice_error { - - #[derive(Debug)] - pub enum FromByteSliceError { - InvalidLength, - OutOfRange, - } - - #[cfg(feature = "std")] - impl std::error::Error for FromByteSliceError {} - - impl core::fmt::Display for FromByteSliceError { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Self::InvalidLength => write!(f, "invalid length"), - Self::OutOfRange => write!(f, "number out of range"), - } - } - } -} -pub use from_bytes_slice_error::FromByteSliceError; - -mod from_byte_array_error { - #[derive(Debug)] - pub struct FromByteArrayError; - - #[cfg(feature = "std")] - impl std::error::Error for FromByteArrayError {} - - impl core::fmt::Display for FromByteArrayError { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "number out of range") - } - } -} -pub use from_byte_array_error::FromByteArrayError; - -mod value_out_of_range_error { - #[derive(Debug)] - pub struct ValueOutOfRangeError; - - #[cfg(feature = "std")] - impl std::error::Error for ValueOutOfRangeError {} - - impl core::fmt::Display for ValueOutOfRangeError { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "field element value out of range") - } - } -} -pub use value_out_of_range_error::ValueOutOfRangeError; - -struct InnerDebug<'a>(pub &'a FieldElement); - -impl FieldElement { - /// [FieldElement] constant that's equal to 0 - pub const ZERO: FieldElement = FieldElement::from_mont([0, 0, 0, 0]); - - /// [FieldElement] constant that's equal to 1 - pub const ONE: FieldElement = FieldElement::from_mont([ - 18446744073709551585, - 18446744073709551615, - 18446744073709551615, - 576460752303422960, - ]); - - /// [FieldElement] constant that's equal to 2 - pub const TWO: FieldElement = FieldElement::from_mont([ - 18446744073709551553, - 18446744073709551615, - 18446744073709551615, - 576460752303422416, - ]); - - /// [FieldElement] constant that's equal to 3 - pub const THREE: FieldElement = FieldElement::from_mont([ - 18446744073709551521, - 18446744073709551615, - 18446744073709551615, - 576460752303421872, - ]); - - /// Maximum value of [FieldElement]. Equals to 2^251 + 17 * 2^192. - pub const MAX: FieldElement = FieldElement::from_mont([32, 0, 0, 544]); - - /// Create a new [FieldElement] from its Montgomery representation - pub const fn from_mont(data: [u64; 4]) -> Self { - Self { - inner: Fp256::new_unchecked(BigInteger256::new(data)), - } - } - - pub fn from_dec_str(value: &str) -> Result { - // Ported from: - // https://github.com/paritytech/parity-common/blob/b37d0b312d39fa47c61c4430b30ca87d90e45a08/uint/src/uint.rs#L599 - - let mut res = U256::ZERO; - for b in value.bytes().map(|b| b.wrapping_sub(b'0')) { - if b > 9 { - return Err(FromStrError::InvalidCharacter); - } - let r = { - let product = res.checked_mul(&U256::from_u8(10)); - if product.is_some().into() { - product.unwrap() - } else { - return Err(FromStrError::OutOfRange); - } - }; - let r = { - let sum = r.checked_add(&U256::from_u8(b)); - if sum.is_some().into() { - sum.unwrap() - } else { - return Err(FromStrError::OutOfRange); - } - }; - res = r; - } - - Fr::from_bigint(u256_to_biginteger256(&res)) - .map(|inner| Self { inner }) - .ok_or(FromStrError::OutOfRange) - } - - pub fn from_hex_be(value: &str) -> Result { - let value = value.trim_start_matches("0x"); - - let hex_chars_len = value.len(); - let expected_hex_length = U256_BYTE_COUNT * 2; - - let parsed_bytes: [u8; U256_BYTE_COUNT] = if hex_chars_len == expected_hex_length { - let mut buffer = [0u8; U256_BYTE_COUNT]; - hex::decode_to_slice(value, &mut buffer).map_err(|_| FromStrError::InvalidCharacter)?; - buffer - } else if hex_chars_len < expected_hex_length { - let mut padded_hex = str::repeat("0", expected_hex_length - hex_chars_len); - padded_hex.push_str(value); - - let mut buffer = [0u8; U256_BYTE_COUNT]; - hex::decode_to_slice(&padded_hex, &mut buffer) - .map_err(|_| FromStrError::InvalidCharacter)?; - buffer - } else { - return Err(FromStrError::OutOfRange); - }; - - match Self::from_bytes_be(&parsed_bytes) { - Ok(value) => Ok(value), - Err(_) => Err(FromStrError::OutOfRange), - } - } - - /// Attempts to convert a big-endian byte representation of a field element into an element of - /// this prime field. Returns error if the input is not canonical (is not smaller than the - /// field's modulus). - /// - /// ### Arguments - /// - /// * `bytes`: The byte array in **big endian** format - pub fn from_bytes_be(bytes: &[u8; 32]) -> Result { - Self::from_byte_slice(bytes).ok_or(FromByteArrayError) - } - - /// Same as `from_bytes_be` except this function takes a slice. - pub fn from_byte_slice_be(bytes: &[u8]) -> Result { - if bytes.len() > U256_BYTE_COUNT { - Err(FromByteSliceError::InvalidLength) - } else { - let mut buffer = [0u8; U256_BYTE_COUNT]; - buffer[(U256_BYTE_COUNT - bytes.len())..].copy_from_slice(bytes); - Self::from_byte_slice(&buffer).ok_or(FromByteSliceError::OutOfRange) - } - } - - /// Interprets the field element as a decimal number of a certain decimal places. - #[cfg(feature = "bigdecimal")] - pub fn to_big_decimal>(&self, decimals: D) -> bigdecimal::BigDecimal { - use num_bigint::{BigInt, Sign}; - - bigdecimal::BigDecimal::new( - BigInt::from_bytes_be(Sign::Plus, &self.to_bytes_be()), - decimals.into(), - ) - } - - /// Transforms [FieldElement] into little endian bit representation. - pub fn to_bits_le(self) -> [bool; 256] { - let mut bits = [false; 256]; - for (ind_element, element) in self.inner.into_bigint().0.iter().enumerate() { - for ind_bit in 0..64 { - bits[ind_element * 64 + ind_bit] = (element >> ind_bit) & 1 == 1; - } - } - - bits - } - - /// Convert the field element into a big-endian byte representation - pub fn to_bytes_be(&self) -> [u8; 32] { - let mut buffer = [0u8; 32]; - buffer.copy_from_slice(&self.inner.into_bigint().to_bytes_be()); - - buffer - } - - /// Transforms [FieldElement] into its Montgomery representation - pub const fn into_mont(self) -> [u64; 4] { - self.inner.0 .0 - } - - pub fn invert(&self) -> Option { - self.inner.inverse().map(|inner| Self { inner }) - } - - pub fn sqrt(&self) -> Option { - self.inner.sqrt().map(|inner| Self { inner }) - } - - pub fn double(&self) -> FieldElement { - *self + *self - } - - /// Performs a floor division. It's not implemented as the `Div` trait on purpose to - /// distinguish from the "felt division". - pub fn floor_div(&self, rhs: FieldElement) -> FieldElement { - let lhs: U256 = self.into(); - let rhs: U256 = (&rhs).into(); - let is_rhs_zero: bool = rhs.is_zero().into(); - - if !is_rhs_zero { - let rhs = NonZero::from_uint(rhs); - - let div_result = lhs.div_rem(&rhs); - let (quotient, _) = div_result; - - // It's safe to unwrap here since `rem` is never out of range - FieldElement { - inner: Fr::from_bigint(u256_to_biginteger256("ient)).unwrap(), - } - } else { - // TODO: add `checked_floor_div` for panic-less use - panic!("division by zero"); - } - } - - /// For internal use only. The input must be of length [U256_BYTE_COUNT]. - fn from_byte_slice(bytes: &[u8]) -> Option { - let mut bits = [false; U256_BYTE_COUNT * 8]; - for (ind_byte, byte) in bytes.iter().enumerate() { - for ind_bit in 0..8 { - bits[ind_byte * 8 + ind_bit] = (byte >> (7 - ind_bit)) & 1 == 1; - } - } - - // No need to check range as `from_bigint` already does that - let big_int = BigInteger256::from_bits_be(&bits); - Fr::from_bigint(big_int).map(|inner| Self { inner }) - } -} - -impl Default for FieldElement { - fn default() -> Self { - Self::ZERO - } -} - -impl AsRef for FieldElement { - fn as_ref(&self) -> &FieldElement { - self - } -} - -impl ops::Add for FieldElement { - type Output = FieldElement; - - fn add(self, rhs: FieldElement) -> Self::Output { - FieldElement { - inner: self.inner + rhs.inner, - } - } -} - -impl ops::AddAssign for FieldElement { - fn add_assign(&mut self, rhs: FieldElement) { - self.inner = self.inner + rhs.inner; - } -} - -impl ops::Sub for FieldElement { - type Output = FieldElement; - - fn sub(self, rhs: FieldElement) -> Self::Output { - FieldElement { - inner: self.inner - rhs.inner, - } - } -} - -impl ops::SubAssign for FieldElement { - fn sub_assign(&mut self, rhs: FieldElement) { - self.inner = self.inner - rhs.inner; - } -} - -impl ops::Mul for FieldElement { - type Output = FieldElement; - - fn mul(self, rhs: FieldElement) -> Self::Output { - FieldElement { - inner: self.inner * rhs.inner, - } - } -} - -impl ops::MulAssign for FieldElement { - fn mul_assign(&mut self, rhs: FieldElement) { - self.inner = self.inner * rhs.inner; - } -} - -impl ops::Neg for FieldElement { - type Output = FieldElement; - - fn neg(self) -> Self::Output { - FieldElement { inner: -self.inner } - } -} - -impl ops::Rem for FieldElement { - type Output = FieldElement; - - fn rem(self, rhs: FieldElement) -> Self::Output { - if self.inner < rhs.inner { - return self; - } - - let lhs: U256 = (&self).into(); - let rhs: U256 = (&rhs).into(); - let is_rhs_zero: bool = rhs.is_zero().into(); - - if !is_rhs_zero { - let rhs = NonZero::from_uint(rhs); - - let (_, rem) = lhs.div_rem(&rhs); - - // It's safe to unwrap here since `rem` is never out of range - FieldElement { - inner: Fr::from_bigint(u256_to_biginteger256(&rem)).unwrap(), - } - } else { - // TODO: add `checked_rem` for panic-less use - panic!("division by zero"); - } - } -} - -impl ops::BitAnd for FieldElement { - type Output = FieldElement; - - fn bitand(self, rhs: FieldElement) -> Self::Output { - let lhs: U256 = (&self).into(); - let rhs: U256 = (&rhs).into(); - - // It's safe to unwrap here since the result is never out of range - FieldElement { - inner: Fr::from_bigint(u256_to_biginteger256(&(lhs & rhs))).unwrap(), - } - } -} - -impl ops::BitOr for FieldElement { - type Output = FieldElement; - - fn bitor(self, rhs: FieldElement) -> Self::Output { - let lhs: U256 = (&self).into(); - let rhs: U256 = (&rhs).into(); - - // It's safe to unwrap here since the result is never out of range - FieldElement { - inner: Fr::from_bigint(u256_to_biginteger256(&(lhs | rhs))).unwrap(), - } - } -} - -impl core::iter::Sum for FieldElement { - fn sum>(iter: I) -> Self { - let mut sum = Self::ZERO; - iter.for_each(|item| { - sum += item; - }); - sum - } -} - -impl<'a> core::iter::Sum<&'a FieldElement> for FieldElement { - fn sum>(iter: I) -> Self { - iter.copied().sum() - } -} - -impl fmt::Debug for FieldElement { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("FieldElement") - .field("inner", &InnerDebug(self)) - .finish() - } -} - -impl fmt::Display for FieldElement { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Ported from: - // https://github.com/paritytech/parity-common/blob/b37d0b312d39fa47c61c4430b30ca87d90e45a08/uint/src/uint.rs#L1650 - - let repr: U256 = self.into(); - - if repr.is_zero().into() { - return write!(f, "0"); - } - - let mut buf = [0u8; 4 * 20]; - let mut i = buf.len() - 1; - let mut current = repr; - let ten = U256::from_u8(10u8); - - loop { - let digit = if current < ten { - current.to_words()[0] as u8 - } else { - (current.checked_rem(&ten)).unwrap().to_words()[0] as u8 - }; - buf[i] = digit + b'0'; - current = current.checked_div(&ten).unwrap(); - if current.is_zero().into() { - break; - } - i -= 1; - } - - // sequence of `'0'..'9'` chars is guaranteed to be a valid UTF8 string - let s = unsafe { str::from_utf8_unchecked(&buf[i..]) }; - f.pad_integral(true, "", s) - } -} - -impl fmt::LowerHex for FieldElement { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let repr: U256 = self.into(); - - let width = if f.sign_aware_zero_pad() { - f.width().unwrap().min(64) - } else { - 1 - }; - if f.alternate() { - write!(f, "0x")?; - } - let mut latch = false; - let mut ind_nibble = 0; - for ch in u256_to_u64_array(&repr).iter().rev() { - for x in 0..16 { - let nibble = (ch & (15u64 << ((15 - x) * 4) as u64)) >> (((15 - x) * 4) as u64); - if !latch { - latch = nibble != 0 || (64 - ind_nibble <= width); - } - if latch { - write!(f, "{nibble:x}")?; - } - ind_nibble += 1; - } - } - Ok(()) - } -} - -impl fmt::UpperHex for FieldElement { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let repr: U256 = self.into(); - - let width = if f.sign_aware_zero_pad() { - f.width().unwrap().min(64) - } else { - 1 - }; - if f.alternate() { - write!(f, "0x")?; - } - let mut latch = false; - let mut ind_nibble = 0; - for ch in u256_to_u64_array(&repr).iter().rev() { - for x in 0..16 { - let nibble = (ch & (15u64 << ((15 - x) * 4) as u64)) >> (((15 - x) * 4) as u64); - if !latch { - latch = nibble != 0 || (64 - ind_nibble <= width); - } - if latch { - write!(f, "{nibble:X}")?; - } - ind_nibble += 1; - } - } - Ok(()) - } -} - -#[cfg(feature = "serde")] -mod serde_field_element { - #[cfg(feature = "std")] - use core::fmt::{Formatter, Result as FmtResult}; - - use super::*; - #[cfg(not(feature = "std"))] - use alloc::{ - fmt::{Formatter, Result as FmtResult}, - string::ToString, - }; - use serde::{de::Visitor, Deserialize, Serialize}; - - struct FieldElementVisitor; - - impl Serialize for FieldElement { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&ToString::to_string(&self)) - } - } - - impl<'de> Deserialize<'de> for FieldElement { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - deserializer.deserialize_str(FieldElementVisitor) - } - } - - impl<'de> Visitor<'de> for FieldElementVisitor { - type Value = FieldElement; - - fn expecting(&self, formatter: &mut Formatter) -> FmtResult { - write!(formatter, "string") - } - - fn visit_str(self, v: &str) -> Result - where - E: serde::de::Error, - { - FieldElement::from_str(v).map_err(serde::de::Error::custom) - } - } -} - -impl From for FieldElement { - fn from(value: u8) -> Self { - Self { - inner: Fr::from_bigint(BigInteger256::new([value as u64, 0, 0, 0])).unwrap(), - } - } -} - -impl From for FieldElement { - fn from(value: u16) -> Self { - Self { - inner: Fr::from_bigint(BigInteger256::new([value as u64, 0, 0, 0])).unwrap(), - } - } -} - -impl From for FieldElement { - fn from(value: u32) -> Self { - Self { - inner: Fr::from_bigint(BigInteger256::new([value as u64, 0, 0, 0])).unwrap(), - } - } -} - -impl From for FieldElement { - fn from(value: u64) -> Self { - Self { - inner: Fr::from_bigint(BigInteger256::new([value, 0, 0, 0])).unwrap(), - } - } -} - -impl From for FieldElement { - fn from(value: u128) -> Self { - let low = value % (u64::MAX as u128 + 1); - let high = value / (u64::MAX as u128 + 1); - - Self { - inner: Fr::from_bigint(BigInteger256::new([low as u64, high as u64, 0, 0])).unwrap(), - } - } -} - -impl From for FieldElement { - fn from(value: usize) -> Self { - Self { - inner: Fr::from_bigint(BigInteger256::new([value as u64, 0, 0, 0])).unwrap(), - } - } -} - -impl FromStr for FieldElement { - type Err = FromStrError; - - fn from_str(s: &str) -> Result { - if s.starts_with("0x") { - FieldElement::from_hex_be(s) - } else { - FieldElement::from_dec_str(s) - } - } -} - -impl TryFrom for u8 { - type Error = ValueOutOfRangeError; - - fn try_from(value: FieldElement) -> Result { - let repr = value.inner.into_bigint().0; - if repr[0] > u8::MAX as u64 || repr[1] > 0 || repr[2] > 0 || repr[3] > 0 { - Err(ValueOutOfRangeError) - } else { - Ok(repr[0] as u8) - } - } -} - -impl TryFrom for u16 { - type Error = ValueOutOfRangeError; - - fn try_from(value: FieldElement) -> Result { - let repr = value.inner.into_bigint().0; - if repr[0] > u16::MAX as u64 || repr[1] > 0 || repr[2] > 0 || repr[3] > 0 { - Err(ValueOutOfRangeError) - } else { - Ok(repr[0] as u16) - } - } -} - -impl TryFrom for u32 { - type Error = ValueOutOfRangeError; - - fn try_from(value: FieldElement) -> Result { - let repr = value.inner.into_bigint().0; - if repr[0] > u32::MAX as u64 || repr[1] > 0 || repr[2] > 0 || repr[3] > 0 { - Err(ValueOutOfRangeError) - } else { - Ok(repr[0] as u32) - } - } -} - -impl TryFrom for u64 { - type Error = ValueOutOfRangeError; - - fn try_from(value: FieldElement) -> Result { - let repr = value.inner.into_bigint().0; - if repr[1] > 0 || repr[2] > 0 || repr[3] > 0 { - Err(ValueOutOfRangeError) - } else { - Ok(repr[0]) - } - } -} - -impl TryFrom for u128 { - type Error = ValueOutOfRangeError; - - fn try_from(value: FieldElement) -> Result { - let repr = value.inner.into_bigint().0; - if repr[2] > 0 || repr[3] > 0 { - Err(ValueOutOfRangeError) - } else { - Ok((repr[0] as u128) + (repr[1] as u128) * (u64::MAX as u128 + 1)) - } - } -} - -impl From<&FieldElement> for U256 { - #[cfg(target_pointer_width = "64")] - fn from(value: &FieldElement) -> Self { - U256::from_words(value.inner.into_bigint().0) - } - - #[cfg(target_pointer_width = "32")] - fn from(value: &FieldElement) -> Self { - U256::from_words(unsafe { - core::mem::transmute::<[u64; 4], [u32; 8]>(value.inner.into_bigint().0) - }) - } -} - -impl<'a> fmt::Debug for InnerDebug<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:#064x}", self.0) - } -} - -#[inline] -fn u256_to_biginteger256(num: &U256) -> BigInteger256 { - BigInteger256::new(u256_to_u64_array(num)) -} - -#[cfg(target_pointer_width = "64")] -#[inline] -fn u256_to_u64_array(num: &U256) -> [u64; 4] { - num.to_words() -} - -#[cfg(target_pointer_width = "32")] -#[inline] -fn u256_to_u64_array(num: &U256) -> [u64; 4] { - unsafe { core::mem::transmute::<[u32; 8], [u64; 4]>(num.to_words()) } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_default_value() { - assert_eq!(FieldElement::default(), FieldElement::ZERO) - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_dec_fmt() { - let nums = [ - "0", - "1", - "10", - "11", - "3618502788666131213697322783095070105623107215331596699973092056135872020480", - ]; - - for num in nums.iter() { - assert_eq!( - &format!("{}", FieldElement::from_dec_str(num).unwrap()), - num - ); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_zero_padded_hex_fmt() { - let fe = FieldElement::from_hex_be("0x1234abcd").unwrap(); - - assert_eq!(format!("{fe:011x}"), "0001234abcd"); - assert_eq!(format!("{fe:011X}"), "0001234ABCD"); - assert_eq!(format!("{fe:08x}"), "1234abcd"); - assert_eq!(format!("{fe:06x}"), "1234abcd"); - assert_eq!(format!("{fe:#x}"), "0x1234abcd"); - assert_eq!( - format!("{fe:#064x}"), - "0x000000000000000000000000000000000000000000000000000000001234abcd" - ); - - // Ignore if requesting more than 64 nibbles (or should we not?) - assert_eq!( - format!("{fe:#0100x}"), - "0x000000000000000000000000000000000000000000000000000000001234abcd" - ); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_addition() { - let additions = [ - ["1", "1", "2"], - [ - "3618502788666131213697322783095070105623107215331596699973092056135872020480", - "1", - "0", - ], - ]; - - for item in additions.iter() { - let mut lhs = FieldElement::from_dec_str(item[0]).unwrap(); - let rhs = FieldElement::from_dec_str(item[1]).unwrap(); - let result = FieldElement::from_dec_str(item[2]).unwrap(); - assert_eq!(lhs + rhs, result); - - lhs += rhs; - assert_eq!(lhs, result); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_subtraction() { - let subtractions = [ - ["10", "7", "3"], - [ - "0", - "3618502788666131213697322783095070105623107215331596699973092056135872020480", - "1", - ], - ]; - - for item in subtractions.iter() { - let mut lhs = FieldElement::from_dec_str(item[0]).unwrap(); - let rhs = FieldElement::from_dec_str(item[1]).unwrap(); - let result = FieldElement::from_dec_str(item[2]).unwrap(); - assert_eq!(lhs - rhs, result); - - lhs -= rhs; - assert_eq!(lhs, result); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_multiplication() { - let multiplications = [ - ["2", "3", "6"], - [ - "3618502788666131213697322783095070105623107215331596699973092056135872020480", - "3618502788666131213697322783095070105623107215331596699973092056135872020480", - "1", - ], - [ - "3141592653589793238462643383279502884197169399375105820974944592307", - "8164062862089986280348253421170679821480865132823066470938446095505", - "514834056922159274131066670130609582664841480950767778400381816737396274242", - ], - ]; - - for item in multiplications.iter() { - let mut lhs = FieldElement::from_dec_str(item[0]).unwrap(); - let rhs = FieldElement::from_dec_str(item[1]).unwrap(); - let result = FieldElement::from_dec_str(item[2]).unwrap(); - assert_eq!(lhs * rhs, result); - - lhs *= rhs; - assert_eq!(lhs, result); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_remainder() { - let remainders = [["123456", "100", "56"], ["7", "3", "1"], ["3", "6", "3"]]; - - for item in remainders.iter() { - assert_eq!( - FieldElement::from_dec_str(item[0]).unwrap() - % FieldElement::from_dec_str(item[1]).unwrap(), - FieldElement::from_dec_str(item[2]).unwrap() - ); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_bitwise_and() { - let operands = [[123456_u64, 567890], [613221132151, 4523451]]; - - for item in operands.iter() { - let lhs: FieldElement = item[0].into(); - let rhs: FieldElement = item[1].into(); - assert_eq!(lhs & rhs, (item[0] & item[1]).into()); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_bitwise_or() { - let operands = [[123456_u64, 567890], [613221132151, 4523451]]; - - for item in operands.iter() { - let lhs: FieldElement = item[0].into(); - let rhs: FieldElement = item[1].into(); - assert_eq!(lhs | rhs, (item[0] | item[1]).into()); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_iter_sum() { - let elements = [FieldElement::ONE, FieldElement::TWO, FieldElement::THREE]; - - assert_eq!( - elements.iter().sum::(), - FieldElement::from_dec_str("6").unwrap() - ); - assert_eq!( - elements.into_iter().sum::(), - FieldElement::from_dec_str("6").unwrap() - ); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_floor_division() { - let quotients = [["123456", "100", "1234"], ["7", "3", "2"], ["3", "6", "0"]]; - - for item in quotients.iter() { - assert_eq!( - FieldElement::from_dec_str(item[0]) - .unwrap() - .floor_div(FieldElement::from_dec_str(item[1]).unwrap()), - FieldElement::from_dec_str(item[2]).unwrap() - ); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_to_primitives() { - let fe_256: FieldElement = 256u16.into(); - - if u8::try_from(fe_256).is_ok() { - panic!("invalid conversion"); - } - - assert_eq!(u16::try_from(fe_256).unwrap(), 256u16); - assert_eq!(u32::try_from(fe_256).unwrap(), 256u32); - assert_eq!(u64::try_from(fe_256).unwrap(), 256u64); - } - - #[test] - #[cfg(feature = "bigdecimal")] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_to_big_decimal() { - use bigdecimal::{BigDecimal, Num}; - - let nums = [ - ( - "134500", - 5, - BigDecimal::from_str_radix("1.345", 10).unwrap(), - ), - ( - "134500", - 0, - BigDecimal::from_str_radix("134500", 10).unwrap(), - ), - ( - "134500", - 10, - BigDecimal::from_str_radix("0.00001345", 10).unwrap(), - ), - ]; - - for num in nums.into_iter() { - assert_eq!( - FieldElement::from_dec_str(num.0) - .unwrap() - .to_big_decimal(num.1), - num.2 - ); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_from_str() { - let nums = [ - ("134500", "0x20d64"), - ("9999999999999999", "0x2386f26fc0ffff"), - ]; - - for num in nums.into_iter() { - assert_eq!( - num.0.parse::().unwrap(), - num.1.parse::().unwrap(), - ); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_from_byte_slice_be() { - let nums = [("25800", [100u8, 200u8])]; - - for num in nums.into_iter() { - assert_eq!( - num.0.parse::().unwrap(), - FieldElement::from_byte_slice_be(&num.1).unwrap() - ); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_u8_conversion() { - let nums = [u8::MAX, u8::MAX / 3 * 2, u8::MAX / 3]; - - for num in nums.into_iter() { - let felt: FieldElement = num.into(); - assert_eq!(format!("{}", felt), format!("{}", num)); - - let back_to_num: u8 = felt.try_into().unwrap(); - assert_eq!(num, back_to_num); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_u16_conversion() { - let nums = [u16::MAX, u16::MAX / 3 * 2, u16::MAX / 3]; - - for num in nums.into_iter() { - let felt: FieldElement = num.into(); - assert_eq!(format!("{}", felt), format!("{}", num)); - - let back_to_num: u16 = felt.try_into().unwrap(); - assert_eq!(num, back_to_num); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_u32_conversion() { - let nums = [u32::MAX, u32::MAX / 3 * 2, u32::MAX / 3]; - - for num in nums.into_iter() { - let felt: FieldElement = num.into(); - assert_eq!(format!("{}", felt), format!("{}", num)); - - let back_to_num: u32 = felt.try_into().unwrap(); - assert_eq!(num, back_to_num); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_u64_conversion() { - let nums = [u64::MAX, u64::MAX / 3 * 2, u64::MAX / 3]; - - for num in nums.into_iter() { - let felt: FieldElement = num.into(); - assert_eq!(format!("{}", felt), format!("{}", num)); - - let back_to_num: u64 = felt.try_into().unwrap(); - assert_eq!(num, back_to_num); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn test_u128_conversion() { - let nums = [u128::MAX, u128::MAX / 3 * 2, u128::MAX / 3]; - - for num in nums.into_iter() { - let felt: FieldElement = num.into(); - assert_eq!(format!("{}", felt), format!("{}", num)); - - let back_to_num: u128 = felt.try_into().unwrap(); - assert_eq!(num, back_to_num); - } - } -} diff --git a/starknet-macros/src/lib.rs b/starknet-macros/src/lib.rs index 1d887834..ebeebe38 100644 --- a/starknet-macros/src/lib.rs +++ b/starknet-macros/src/lib.rs @@ -1,6 +1,6 @@ use proc_macro::TokenStream; use starknet_core::{ - types::FieldElement, + types::Felt, utils::{cairo_short_string_to_felt, get_selector_from_name}, }; use syn::{parse_macro_input, LitStr}; @@ -12,10 +12,10 @@ pub fn selector(input: TokenStream) -> TokenStream { let str_value = input.value(); let selector_value = get_selector_from_name(&str_value).expect("invalid selector name"); - let selector_raw = selector_value.into_mont(); + let selector_raw = selector_value.to_raw(); format!( - "{}::from_mont([{}, {}, {}, {}])", + "{}::from_raw([{}, {}, {}, {}])", field_element_path(), selector_raw[0], selector_raw[1], @@ -33,10 +33,10 @@ pub fn short_string(input: TokenStream) -> TokenStream { let str_value = input.value(); let felt_value = cairo_short_string_to_felt(&str_value).expect("invalid Cairo short string"); - let felt_raw = felt_value.into_mont(); + let felt_raw = felt_value.to_raw(); format!( - "{}::from_mont([{}, {}, {}, {}])", + "{}::from_raw([{}, {}, {}, {}])", field_element_path(), felt_raw[0], felt_raw[1], @@ -54,15 +54,15 @@ pub fn felt(input: TokenStream) -> TokenStream { let str_value = input.value(); let felt_value = if str_value.starts_with("0x") { - FieldElement::from_hex_be(&str_value).expect("invalid FieldElement value") + Felt::from_hex(&str_value).expect("invalid Felt value") } else { - FieldElement::from_dec_str(&str_value).expect("invalid FieldElement value") + Felt::from_dec_str(&str_value).expect("invalid Felt value") }; - let felt_raw = felt_value.into_mont(); + let felt_raw = felt_value.to_raw(); format!( - "{}::from_mont([{}, {}, {}, {}])", + "{}::from_raw([{}, {}, {}, {}])", field_element_path(), felt_raw[0], felt_raw[1], @@ -79,11 +79,11 @@ pub fn felt_dec(input: TokenStream) -> TokenStream { let str_value = input.value(); - let felt_value = FieldElement::from_dec_str(&str_value).expect("invalid FieldElement value"); - let felt_raw = felt_value.into_mont(); + let felt_value = Felt::from_dec_str(&str_value).expect("invalid Felt value"); + let felt_raw = felt_value.to_raw(); format!( - "{}::from_mont([{}, {}, {}, {}])", + "{}::from_raw([{}, {}, {}, {}])", field_element_path(), felt_raw[0], felt_raw[1], @@ -100,11 +100,11 @@ pub fn felt_hex(input: TokenStream) -> TokenStream { let str_value = input.value(); - let felt_value = FieldElement::from_hex_be(&str_value).expect("invalid FieldElement value"); - let felt_raw = felt_value.into_mont(); + let felt_value = Felt::from_hex(&str_value).expect("invalid Felt value"); + let felt_raw = felt_value.to_raw(); format!( - "{}::from_mont([{}, {}, {}, {}])", + "{}::from_raw([{}, {}, {}, {}])", field_element_path(), felt_raw[0], felt_raw[1], @@ -117,10 +117,10 @@ pub fn felt_hex(input: TokenStream) -> TokenStream { #[cfg(feature = "use_imported_type")] fn field_element_path() -> &'static str { - "FieldElement" + "Felt" } #[cfg(not(feature = "use_imported_type"))] fn field_element_path() -> &'static str { - "::starknet::core::types::FieldElement" + "::starknet::core::types::Felt" } diff --git a/starknet-providers/Cargo.toml b/starknet-providers/Cargo.toml index 08da4cd8..fd649247 100644 --- a/starknet-providers/Cargo.toml +++ b/starknet-providers/Cargo.toml @@ -27,6 +27,9 @@ serde = "1.0.160" serde_json = "1.0.96" serde_with = "2.3.2" +[target.'cfg(target_arch = "wasm32")'.dependencies] +getrandom = { version = "0.2.9", features = ["js"] } + [dev-dependencies] starknet-providers = { path = ".", features = ["no_unknown_fields"] } tokio = { version = "1.27.0", features = ["full"] } diff --git a/starknet-providers/src/any.rs b/starknet-providers/src/any.rs index cf6e5ce1..7bbd7f13 100644 --- a/starknet-providers/src/any.rs +++ b/starknet-providers/src/any.rs @@ -3,7 +3,7 @@ use starknet_core::types::{ BlockHashAndNumber, BlockId, BroadcastedDeclareTransaction, BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction, ContractClass, DeclareTransactionResult, DeployAccountTransactionResult, EventFilter, - EventsPage, FeeEstimate, FieldElement, FunctionCall, InvokeTransactionResult, + EventsPage, FeeEstimate, Felt, FunctionCall, InvokeTransactionResult, MaybePendingBlockWithReceipts, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate, MsgFromL1, SimulatedTransaction, SimulationFlag, SimulationFlagForEstimateFee, SyncStatusType, Transaction, TransactionReceiptWithBlockInfo, @@ -124,10 +124,10 @@ impl Provider for AnyProvider { contract_address: A, key: K, block_id: B, - ) -> Result + ) -> Result where - A: AsRef + Send + Sync, - K: AsRef + Send + Sync, + A: AsRef + Send + Sync, + K: AsRef + Send + Sync, B: AsRef + Send + Sync, { match self { @@ -157,7 +157,7 @@ impl Provider for AnyProvider { transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { match self { Self::JsonRpcHttp(inner) => { @@ -182,7 +182,7 @@ impl Provider for AnyProvider { transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { match self { Self::JsonRpcHttp(inner) => { @@ -231,7 +231,7 @@ impl Provider for AnyProvider { transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { match self { Self::JsonRpcHttp(inner) => { @@ -258,7 +258,7 @@ impl Provider for AnyProvider { ) -> Result where B: AsRef + Send + Sync, - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { match self { Self::JsonRpcHttp(inner) => { @@ -275,10 +275,10 @@ impl Provider for AnyProvider { &self, block_id: B, contract_address: A, - ) -> Result + ) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync, + A: AsRef + Send + Sync, { match self { Self::JsonRpcHttp(inner) => { @@ -307,7 +307,7 @@ impl Provider for AnyProvider { ) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync, + A: AsRef + Send + Sync, { match self { Self::JsonRpcHttp(inner) => { @@ -347,7 +347,7 @@ impl Provider for AnyProvider { } } - async fn call(&self, request: R, block_id: B) -> Result, ProviderError> + async fn call(&self, request: R, block_id: B) -> Result, ProviderError> where R: AsRef + Send + Sync, B: AsRef + Send + Sync, @@ -442,7 +442,7 @@ impl Provider for AnyProvider { } } - async fn chain_id(&self) -> Result { + async fn chain_id(&self) -> Result { match self { Self::JsonRpcHttp(inner) => { as Provider>::chain_id(inner).await @@ -492,14 +492,10 @@ impl Provider for AnyProvider { } } - async fn get_nonce( - &self, - block_id: B, - contract_address: A, - ) -> Result + async fn get_nonce(&self, block_id: B, contract_address: A) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync, + A: AsRef + Send + Sync, { match self { Self::JsonRpcHttp(inner) => { @@ -597,7 +593,7 @@ impl Provider for AnyProvider { transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { match self { Self::JsonRpcHttp(inner) => { diff --git a/starknet-providers/src/jsonrpc/mod.rs b/starknet-providers/src/jsonrpc/mod.rs index 91a46304..e57550cc 100644 --- a/starknet-providers/src/jsonrpc/mod.rs +++ b/starknet-providers/src/jsonrpc/mod.rs @@ -9,13 +9,13 @@ use starknet_core::{ requests::*, BlockHashAndNumber, BlockId, BroadcastedDeclareTransaction, BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction, ContractClass, ContractErrorData, DeclareTransactionResult, DeployAccountTransactionResult, - EventFilter, EventFilterWithPage, EventsPage, FeeEstimate, FieldElement, FunctionCall, - InvokeTransactionResult, MaybePendingBlockWithReceipts, MaybePendingBlockWithTxHashes, - MaybePendingBlockWithTxs, MaybePendingStateUpdate, MsgFromL1, NoTraceAvailableErrorData, - ResultPageRequest, SimulatedTransaction, SimulationFlag, SimulationFlagForEstimateFee, - StarknetError, SyncStatusType, Transaction, TransactionExecutionErrorData, - TransactionReceiptWithBlockInfo, TransactionStatus, TransactionTrace, - TransactionTraceWithHash, + EventFilter, EventFilterWithPage, EventsPage, FeeEstimate, Felt as FeltPrimitive, + FunctionCall, InvokeTransactionResult, MaybePendingBlockWithReceipts, + MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate, + MsgFromL1, NoTraceAvailableErrorData, ResultPageRequest, SimulatedTransaction, + SimulationFlag, SimulationFlagForEstimateFee, StarknetError, SyncStatusType, Transaction, + TransactionExecutionErrorData, TransactionReceiptWithBlockInfo, TransactionStatus, + TransactionTrace, TransactionTraceWithHash, }, }; @@ -168,11 +168,11 @@ pub enum JsonRpcErrorConversionError { #[serde_as] #[derive(Serialize, Deserialize)] -struct Felt(#[serde_as(as = "UfeHex")] pub FieldElement); +struct Felt(#[serde_as(as = "UfeHex")] pub FeltPrimitive); #[serde_as] #[derive(Serialize, Deserialize)] -struct FeltArray(#[serde_as(as = "Vec")] pub Vec); +struct FeltArray(#[serde_as(as = "Vec")] pub Vec); impl JsonRpcClient { pub fn new(transport: T) -> Self { @@ -292,10 +292,10 @@ where contract_address: A, key: K, block_id: B, - ) -> Result + ) -> Result where - A: AsRef + Send + Sync, - K: AsRef + Send + Sync, + A: AsRef + Send + Sync, + K: AsRef + Send + Sync, B: AsRef + Send + Sync, { Ok(self @@ -318,7 +318,7 @@ where transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { self.send_request( JsonRpcMethod::GetTransactionStatus, @@ -335,7 +335,7 @@ where transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { self.send_request( JsonRpcMethod::GetTransactionByHash, @@ -371,7 +371,7 @@ where transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { self.send_request( JsonRpcMethod::GetTransactionReceipt, @@ -390,7 +390,7 @@ where ) -> Result where B: AsRef + Send + Sync, - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { self.send_request( JsonRpcMethod::GetClass, @@ -407,10 +407,10 @@ where &self, block_id: B, contract_address: A, - ) -> Result + ) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync, + A: AsRef + Send + Sync, { Ok(self .send_request::<_, Felt>( @@ -432,7 +432,7 @@ where ) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync, + A: AsRef + Send + Sync, { self.send_request( JsonRpcMethod::GetClassAt, @@ -459,7 +459,7 @@ where } /// Call a starknet function without creating a Starknet transaction - async fn call(&self, request: R, block_id: B) -> Result, ProviderError> + async fn call(&self, request: R, block_id: B) -> Result, ProviderError> where R: AsRef + Send + Sync, B: AsRef + Send + Sync, @@ -532,7 +532,7 @@ where } /// Return the currently configured Starknet chain id - async fn chain_id(&self) -> Result { + async fn chain_id(&self) -> Result { Ok(self .send_request::<_, Felt>(JsonRpcMethod::ChainId, ChainIdRequest) .await? @@ -572,10 +572,10 @@ where &self, block_id: B, contract_address: A, - ) -> Result + ) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync, + A: AsRef + Send + Sync, { Ok(self .send_request::<_, Felt>( @@ -647,7 +647,7 @@ where transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { self.send_request( JsonRpcMethod::TraceTransaction, diff --git a/starknet-providers/src/provider.rs b/starknet-providers/src/provider.rs index 3db7363c..0ee4958a 100644 --- a/starknet-providers/src/provider.rs +++ b/starknet-providers/src/provider.rs @@ -4,7 +4,7 @@ use starknet_core::types::{ BlockHashAndNumber, BlockId, BroadcastedDeclareTransaction, BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction, ContractClass, DeclareTransactionResult, DeployAccountTransactionResult, EventFilter, - EventsPage, FeeEstimate, FieldElement, FunctionCall, InvokeTransactionResult, + EventsPage, FeeEstimate, Felt, FunctionCall, InvokeTransactionResult, MaybePendingBlockWithReceipts, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate, MsgFromL1, SimulatedTransaction, SimulationFlag, SimulationFlagForEstimateFee, StarknetError, SyncStatusType, Transaction, @@ -57,10 +57,10 @@ pub trait Provider { contract_address: A, key: K, block_id: B, - ) -> Result + ) -> Result where - A: AsRef + Send + Sync, - K: AsRef + Send + Sync, + A: AsRef + Send + Sync, + K: AsRef + Send + Sync, B: AsRef + Send + Sync; /// Gets the transaction status (possibly reflecting that the tx is still in @@ -70,7 +70,7 @@ pub trait Provider { transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync; + H: AsRef + Send + Sync; /// Get the details and status of a submitted transaction async fn get_transaction_by_hash( @@ -78,7 +78,7 @@ pub trait Provider { transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync; + H: AsRef + Send + Sync; /// Get the details of a transaction by a given block id and index async fn get_transaction_by_block_id_and_index( @@ -95,7 +95,7 @@ pub trait Provider { transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync; + H: AsRef + Send + Sync; /// Get the contract class definition in the given block associated with the given hash async fn get_class( @@ -105,17 +105,17 @@ pub trait Provider { ) -> Result where B: AsRef + Send + Sync, - H: AsRef + Send + Sync; + H: AsRef + Send + Sync; /// Get the contract class hash in the given block for the contract deployed at the given address async fn get_class_hash_at( &self, block_id: B, contract_address: A, - ) -> Result + ) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync; + A: AsRef + Send + Sync; /// Get the contract class definition in the given block at the given address async fn get_class_at( @@ -125,7 +125,7 @@ pub trait Provider { ) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync; + A: AsRef + Send + Sync; /// Get the number of transactions in a block given a block id async fn get_block_transaction_count(&self, block_id: B) -> Result @@ -133,7 +133,7 @@ pub trait Provider { B: AsRef + Send + Sync; /// Call a starknet function without creating a Starknet transaction - async fn call(&self, request: R, block_id: B) -> Result, ProviderError> + async fn call(&self, request: R, block_id: B) -> Result, ProviderError> where R: AsRef + Send + Sync, B: AsRef + Send + Sync; @@ -166,7 +166,7 @@ pub trait Provider { async fn block_hash_and_number(&self) -> Result; /// Return the currently configured Starknet chain id - async fn chain_id(&self) -> Result; + async fn chain_id(&self) -> Result; /// Returns an object about the sync status, or false if the node is not synching async fn syncing(&self) -> Result; @@ -184,10 +184,10 @@ pub trait Provider { &self, block_id: B, contract_address: A, - ) -> Result + ) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync; + A: AsRef + Send + Sync; /// Submit a new transaction to be added to the chain async fn add_invoke_transaction( @@ -220,7 +220,7 @@ pub trait Provider { transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync; + H: AsRef + Send + Sync; /// Simulate a given sequence of transactions on the requested state, and generate the execution /// traces. Note that some of the transactions may revert, in which case no error is thrown, but diff --git a/starknet-providers/src/sequencer/mod.rs b/starknet-providers/src/sequencer/mod.rs index 3b06f121..8e83a11e 100644 --- a/starknet-providers/src/sequencer/mod.rs +++ b/starknet-providers/src/sequencer/mod.rs @@ -8,7 +8,7 @@ use serde_with::serde_as; use starknet_core::{ chain_id, serde::unsigned_field_element::UfeHex, - types::{contract::CompiledClass, FieldElement, StarknetError}, + types::{contract::CompiledClass, Felt, StarknetError}, }; use url::Url; @@ -25,7 +25,7 @@ pub struct SequencerGatewayProvider { client: Client, gateway_url: Url, feeder_gateway_url: Url, - chain_id: FieldElement, + chain_id: Felt, headers: Vec<(String, String)>, } @@ -103,7 +103,7 @@ impl SequencerGatewayProvider { pub fn new( gateway_url: impl Into, feeder_gateway_url: impl Into, - chain_id: FieldElement, + chain_id: Felt, ) -> Self { Self::new_with_client(gateway_url, feeder_gateway_url, chain_id, Client::new()) } @@ -111,7 +111,7 @@ impl SequencerGatewayProvider { pub fn new_with_client( gateway_url: impl Into, feeder_gateway_url: impl Into, - chain_id: FieldElement, + chain_id: Felt, client: Client, ) -> Self { Self { @@ -165,12 +165,12 @@ enum GatewayResponse { SequencerError(SequencerError), } -// Work FieldElement deserialization +// Work Felt deserialization #[serde_as] #[derive(Deserialize)] #[serde(untagged)] enum RawFieldElementResponse { - Data(#[serde_as(as = "UfeHex")] FieldElement), + Data(#[serde_as(as = "UfeHex")] Felt), SequencerError(SequencerError), } @@ -321,7 +321,7 @@ impl SequencerGatewayProvider { )] pub async fn get_compiled_class_by_class_hash( &self, - class_hash: FieldElement, + class_hash: Felt, block_identifier: BlockId, ) -> Result { let mut request_url = self.extend_feeder_gateway_url("get_compiled_class_by_class_hash"); @@ -340,7 +340,7 @@ impl SequencerGatewayProvider { )] pub async fn get_class_by_hash( &self, - class_hash: FieldElement, + class_hash: Felt, block_identifier: BlockId, ) -> Result { let mut request_url = self.extend_feeder_gateway_url("get_class_by_hash"); @@ -359,7 +359,7 @@ impl SequencerGatewayProvider { )] pub async fn get_transaction_status( &self, - transaction_hash: FieldElement, + transaction_hash: Felt, ) -> Result { let mut request_url = self.extend_feeder_gateway_url("get_transaction_status"); request_url @@ -376,7 +376,7 @@ impl SequencerGatewayProvider { )] pub async fn get_transaction( &self, - transaction_hash: FieldElement, + transaction_hash: Felt, ) -> Result { let mut request_url = self.extend_feeder_gateway_url("get_transaction"); request_url @@ -393,7 +393,7 @@ impl SequencerGatewayProvider { )] pub async fn get_transaction_trace( &self, - transaction_hash: FieldElement, + transaction_hash: Felt, ) -> Result { let mut request_url = self.extend_feeder_gateway_url("get_transaction_trace"); request_url @@ -408,10 +408,7 @@ impl SequencerGatewayProvider { #[deprecated( note = "Sequencer-specific functions are deprecated. Use it via the Provider trait instead." )] - pub async fn get_block_hash_by_id( - &self, - block_number: u64, - ) -> Result { + pub async fn get_block_hash_by_id(&self, block_number: u64) -> Result { let mut request_url = self.extend_feeder_gateway_url("get_block_hash_by_id"); request_url .query_pairs_mut() @@ -425,10 +422,7 @@ impl SequencerGatewayProvider { #[deprecated( note = "Sequencer-specific functions are deprecated. Use it via the Provider trait instead." )] - pub async fn get_block_id_by_hash( - &self, - block_hash: FieldElement, - ) -> Result { + pub async fn get_block_id_by_hash(&self, block_hash: Felt) -> Result { let mut request_url = self.extend_feeder_gateway_url("get_block_id_by_hash"); request_url .query_pairs_mut() @@ -509,7 +503,7 @@ impl From> for Result { } } -impl From for Result { +impl From for Result { fn from(value: RawFieldElementResponse) -> Self { match value { RawFieldElementResponse::Data(data) => Ok(data), diff --git a/starknet-providers/src/sequencer/models/block.rs b/starknet-providers/src/sequencer/models/block.rs index 2a0bd3a9..75430a51 100644 --- a/starknet-providers/src/sequencer/models/block.rs +++ b/starknet-providers/src/sequencer/models/block.rs @@ -2,14 +2,14 @@ use serde::Deserialize; use serde_with::serde_as; use starknet_core::{ serde::unsigned_field_element::{UfeHex, UfeHexOption}, - types::{FieldElement, L1DataAvailabilityMode, ResourcePrice}, + types::{Felt, L1DataAvailabilityMode, ResourcePrice}, }; use super::{ConfirmedTransactionReceipt, TransactionType}; #[derive(Debug, Clone, Copy)] pub enum BlockId { - Hash(FieldElement), + Hash(Felt), Number(u64), Pending, Latest, @@ -37,24 +37,24 @@ pub enum BlockStatus { pub struct Block { #[serde(default)] #[serde_as(as = "UfeHexOption")] - pub block_hash: Option, + pub block_hash: Option, pub block_number: Option, #[serde_as(as = "UfeHex")] - pub parent_block_hash: FieldElement, + pub parent_block_hash: Felt, pub timestamp: u64, // Field marked optional as old blocks don't include it yet. Drop optional once resolved. #[serde(default)] #[serde_as(as = "UfeHexOption")] - pub sequencer_address: Option, + pub sequencer_address: Option, #[serde(default)] #[serde_as(as = "UfeHexOption")] - pub state_root: Option, + pub state_root: Option, #[serde(default)] #[serde_as(as = "UfeHexOption")] - pub transaction_commitment: Option, + pub transaction_commitment: Option, #[serde(default)] #[serde_as(as = "UfeHexOption")] - pub event_commitment: Option, + pub event_commitment: Option, pub status: BlockStatus, pub l1_da_mode: L1DataAvailabilityMode, pub l1_gas_price: ResourcePrice, @@ -82,24 +82,18 @@ mod tests { assert_eq!(block.status, BlockStatus::AcceptedOnL1); assert_eq!( block.state_root.unwrap(), - FieldElement::from_hex_be( - "051098918fd96edda4e251f695181c063e21fb0666352e3469db507c7fd62b89" - ) - .unwrap() + Felt::from_hex("051098918fd96edda4e251f695181c063e21fb0666352e3469db507c7fd62b89") + .unwrap() ); assert_eq!( block.transaction_commitment.unwrap(), - FieldElement::from_hex_be( - "0576db32d35cf011694a73c6ce400d5d77f768cbd77ee7cf87d12902e0f9b4ec" - ) - .unwrap() + Felt::from_hex("0576db32d35cf011694a73c6ce400d5d77f768cbd77ee7cf87d12902e0f9b4ec") + .unwrap() ); assert_eq!( block.event_commitment.unwrap(), - FieldElement::from_hex_be( - "01c972780140fd16dde94639226ca25818e4f24ecd5b5c3065cc1f5f5fc410f9" - ) - .unwrap() + Felt::from_hex("01c972780140fd16dde94639226ca25818e4f24ecd5b5c3065cc1f5f5fc410f9") + .unwrap() ); assert_eq!(block.transactions.len(), 4); assert_eq!(block.transaction_receipts.len(), 4); @@ -219,10 +213,8 @@ mod tests { assert_eq!( tx.sender_address, - FieldElement::from_hex_be( - "0x68922eb87daed71fc3099031e178b6534fc39a570022342e8c166024da893f5" - ) - .unwrap() + Felt::from_hex("0x68922eb87daed71fc3099031e178b6534fc39a570022342e8c166024da893f5") + .unwrap() ); } @@ -242,10 +234,8 @@ mod tests { assert_eq!( tx.contract_address, - FieldElement::from_hex_be( - "0x4c5772d1914fe6ce891b64eb35bf3522aeae1315647314aac58b01137607f3f" - ) - .unwrap() + Felt::from_hex("0x4c5772d1914fe6ce891b64eb35bf3522aeae1315647314aac58b01137607f3f") + .unwrap() ); } diff --git a/starknet-providers/src/sequencer/models/contract.rs b/starknet-providers/src/sequencer/models/contract.rs index bfeb7d31..04584d51 100644 --- a/starknet-providers/src/sequencer/models/contract.rs +++ b/starknet-providers/src/sequencer/models/contract.rs @@ -10,7 +10,7 @@ use starknet_core::{ legacy::{LegacyContractClass, RawLegacyAbiEntry, RawLegacyEntryPoints}, CompressProgramError, }, - EntryPointsByType, FieldElement, FlattenedSierraClass, + EntryPointsByType, Felt, FlattenedSierraClass, }, }; @@ -78,7 +78,7 @@ impl CompressedSierraClass { ) -> Result { #[serde_as] #[derive(Serialize)] - struct SierraProgram<'a>(#[serde_as(as = "Vec")] &'a Vec); + struct SierraProgram<'a>(#[serde_as(as = "Vec")] &'a Vec); let program_json = serde_json::to_string(&SierraProgram(&flattened_class.sierra_program)) .map_err(DecompressProgramError::Json)?; diff --git a/starknet-providers/src/sequencer/models/conversions.rs b/starknet-providers/src/sequencer/models/conversions.rs index e6358fd2..c1c0d618 100644 --- a/starknet-providers/src/sequencer/models/conversions.rs +++ b/starknet-providers/src/sequencer/models/conversions.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use starknet_core::types::{self as core, contract::legacy as contract_legacy, FieldElement}; +use starknet_core::types::{self as core, contract::legacy as contract_legacy, Felt}; use super::{ state_update::{DeclaredContract, DeployedContract, StateDiff, StorageDiff}, @@ -24,7 +24,7 @@ pub(crate) struct ConfirmedReceiptWithContext { pub(crate) struct OrderedL2ToL1MessageResponseWithFromAddress { pub message: OrderedL2ToL1MessageResponse, - pub from: FieldElement, + pub from: Felt, } impl From for BlockId { @@ -228,7 +228,7 @@ impl TryFrom for core::DeclareTransaction { type Error = ConversionError; fn try_from(value: DeclareTransaction) -> Result { - if value.version == FieldElement::ZERO { + if value.version == Felt::ZERO { Ok(Self::V0(core::DeclareTransactionV0 { transaction_hash: value.transaction_hash, max_fee: value.max_fee.ok_or(ConversionError)?, @@ -236,7 +236,7 @@ impl TryFrom for core::DeclareTransaction { class_hash: value.class_hash, sender_address: value.sender_address, })) - } else if value.version == FieldElement::ONE { + } else if value.version == Felt::ONE { Ok(Self::V1(core::DeclareTransactionV1 { transaction_hash: value.transaction_hash, max_fee: value.max_fee.ok_or(ConversionError)?, @@ -245,7 +245,7 @@ impl TryFrom for core::DeclareTransaction { class_hash: value.class_hash, sender_address: value.sender_address, })) - } else if value.version == FieldElement::TWO { + } else if value.version == Felt::TWO { Ok(Self::V2(core::DeclareTransactionV2 { transaction_hash: value.transaction_hash, max_fee: value.max_fee.ok_or(ConversionError)?, @@ -255,7 +255,7 @@ impl TryFrom for core::DeclareTransaction { compiled_class_hash: value.compiled_class_hash.ok_or(ConversionError)?, sender_address: value.sender_address, })) - } else if value.version == FieldElement::THREE { + } else if value.version == Felt::THREE { Ok(Self::V3(core::DeclareTransactionV3 { transaction_hash: value.transaction_hash, sender_address: value.sender_address, @@ -300,7 +300,7 @@ impl TryFrom for core::DeployAccountTransaction { type Error = ConversionError; fn try_from(value: DeployAccountTransaction) -> Result { - if value.version == FieldElement::ONE { + if value.version == Felt::ONE { Ok(Self::V1(core::DeployAccountTransactionV1 { transaction_hash: value.transaction_hash, max_fee: value.max_fee.ok_or(ConversionError)?, @@ -310,7 +310,7 @@ impl TryFrom for core::DeployAccountTransaction { constructor_calldata: value.constructor_calldata, class_hash: value.class_hash, })) - } else if value.version == FieldElement::THREE { + } else if value.version == Felt::THREE { Ok(Self::V3(core::DeployAccountTransactionV3 { transaction_hash: value.transaction_hash, signature: value.signature, @@ -340,7 +340,7 @@ impl TryFrom for core::InvokeTransaction { type Error = ConversionError; fn try_from(value: InvokeFunctionTransaction) -> Result { - if value.version == FieldElement::ZERO { + if value.version == Felt::ZERO { Ok(Self::V0(core::InvokeTransactionV0 { transaction_hash: value.transaction_hash, max_fee: value.max_fee.ok_or(ConversionError)?, @@ -349,7 +349,7 @@ impl TryFrom for core::InvokeTransaction { entry_point_selector: value.entry_point_selector.ok_or(ConversionError)?, calldata: value.calldata, })) - } else if value.version == FieldElement::ONE { + } else if value.version == Felt::ONE { Ok(Self::V1(core::InvokeTransactionV1 { transaction_hash: value.transaction_hash, max_fee: value.max_fee.ok_or(ConversionError)?, @@ -358,7 +358,7 @@ impl TryFrom for core::InvokeTransaction { sender_address: value.sender_address, calldata: value.calldata, })) - } else if value.version == FieldElement::THREE { + } else if value.version == Felt::THREE { Ok(Self::V3(core::InvokeTransactionV3 { transaction_hash: value.transaction_hash, sender_address: value.sender_address, @@ -391,11 +391,14 @@ impl TryFrom for core::L1HandlerTransaction { Ok(Self { transaction_hash: value.transaction_hash, version: value.version, - nonce: value - .nonce - .unwrap_or_default() - .try_into() - .map_err(|_| ConversionError)?, + nonce: { + // TODO: remove this when a proper u64 conversion is implemented for `Felt` + let nonce_bytes = value.nonce.unwrap_or_default().to_bytes_le(); + if nonce_bytes.iter().skip(8).any(|&x| x != 0) { + return Err(ConversionError); + } + u64::from_le_bytes(nonce_bytes[..8].try_into().unwrap()) + }, contract_address: value.contract_address, entry_point_selector: value.entry_point_selector, calldata: value.calldata, @@ -568,7 +571,7 @@ impl From for core::MsgToL1 { Self { from_address: value.from_address, // Unwrapping here is safe - to_address: FieldElement::from_byte_slice_be(&value.to_address.0).unwrap(), + to_address: Felt::from_bytes_be_slice(&value.to_address.0), payload: value.payload, } } @@ -871,10 +874,7 @@ impl From for core::OrderedMessage Self { from_address: value.from, // Unwrapping is safe here as H160 is only 20 bytes - to_address: FieldElement::from_byte_slice_be( - &value.message.to_address.to_fixed_bytes(), - ) - .unwrap(), + to_address: Felt::from_bytes_be_slice(&value.message.to_address.to_fixed_bytes()), payload: value.message.payload, order: value.message.order, } diff --git a/starknet-providers/src/sequencer/models/state_update.rs b/starknet-providers/src/sequencer/models/state_update.rs index 18cd5ee9..0447b96c 100644 --- a/starknet-providers/src/sequencer/models/state_update.rs +++ b/starknet-providers/src/sequencer/models/state_update.rs @@ -1,6 +1,6 @@ use serde::Deserialize; use serde_with::serde_as; -use starknet_core::{serde::unsigned_field_element::UfeHex, types::FieldElement}; +use starknet_core::{serde::unsigned_field_element::UfeHex, types::Felt}; use std::collections::HashMap; #[serde_as] @@ -8,11 +8,11 @@ use std::collections::HashMap; #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct StateUpdate { #[serde_as(as = "Option")] - pub block_hash: Option, + pub block_hash: Option, #[serde_as(as = "Option")] - pub new_root: Option, + pub new_root: Option, #[serde_as(as = "UfeHex")] - pub old_root: FieldElement, + pub old_root: Felt, pub state_diff: StateDiff, } @@ -21,14 +21,14 @@ pub struct StateUpdate { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct StateDiff { #[serde_as(as = "HashMap")] - pub storage_diffs: HashMap>, + pub storage_diffs: HashMap>, pub deployed_contracts: Vec, #[serde_as(as = "Vec")] - pub old_declared_contracts: Vec, + pub old_declared_contracts: Vec, pub declared_classes: Vec, #[serde(default)] #[serde_as(as = "HashMap")] - pub nonces: HashMap, + pub nonces: HashMap, pub replaced_classes: Vec, } @@ -37,9 +37,9 @@ pub struct StateDiff { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct StorageDiff { #[serde_as(as = "UfeHex")] - pub key: FieldElement, + pub key: Felt, #[serde_as(as = "UfeHex")] - pub value: FieldElement, + pub value: Felt, } #[serde_as] @@ -47,9 +47,9 @@ pub struct StorageDiff { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct DeployedContract { #[serde_as(as = "UfeHex")] - pub address: FieldElement, + pub address: Felt, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, } #[serde_as] @@ -57,9 +57,9 @@ pub struct DeployedContract { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct DeclaredContract { #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, #[serde_as(as = "UfeHex")] - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, } #[cfg(test)] @@ -78,7 +78,7 @@ mod tests { .state_diff .storage_diffs .get( - &FieldElement::from_hex_be( + &Felt::from_hex( "0x197b9913e67947b0605934ec72db497d341a0199282c1da6d4aae46b17e0e76", ) .unwrap(), @@ -87,17 +87,13 @@ mod tests { assert_eq!( storage_diff.key, - FieldElement::from_hex_be( - "0x34c0d833897dbc937dd35e9f49a5184aecd6ab47829de999f9587549f82d0e" - ) - .unwrap() + Felt::from_hex("0x34c0d833897dbc937dd35e9f49a5184aecd6ab47829de999f9587549f82d0e") + .unwrap() ); assert_eq!( storage_diff.value, - FieldElement::from_hex_be( - "0x74fd8ca6e84097ad9ae00febfb690ad032fc4477155ec2193382c1b30b5e12b" - ) - .unwrap() + Felt::from_hex("0x74fd8ca6e84097ad9ae00febfb690ad032fc4477155ec2193382c1b30b5e12b") + .unwrap() ); } diff --git a/starknet-providers/src/sequencer/models/trace.rs b/starknet-providers/src/sequencer/models/trace.rs index 680e6072..cce9ec2f 100644 --- a/starknet-providers/src/sequencer/models/trace.rs +++ b/starknet-providers/src/sequencer/models/trace.rs @@ -1,6 +1,6 @@ use serde::Deserialize; use serde_with::serde_as; -use starknet_core::{serde::unsigned_field_element::UfeHex, types::FieldElement}; +use starknet_core::{serde::unsigned_field_element::UfeHex, types::Felt}; use super::{EntryPointType, ExecutionResources, L1Address}; @@ -28,7 +28,7 @@ pub struct TransactionTrace { #[serde(default)] pub validate_invocation: Option, #[serde_as(as = "Vec")] - pub signature: Vec, + pub signature: Vec, } #[serde_as] @@ -38,7 +38,7 @@ pub struct TransactionTraceWithHash { #[serde(flatten)] pub trace: TransactionTrace, #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, } #[derive(Debug, Deserialize, PartialEq, Eq)] @@ -55,23 +55,23 @@ pub enum CallType { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct FunctionInvocation { #[serde_as(as = "UfeHex")] - pub caller_address: FieldElement, + pub caller_address: Felt, #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, #[serde_as(as = "Vec")] - pub calldata: Vec, + pub calldata: Vec, pub call_type: Option, // This field is marked optional because it's missing from old transactions. Drop `Option` once // it's resolved. #[serde_as(as = "Option")] - pub class_hash: Option, + pub class_hash: Option, // This field is marked optional because it's missing from old transactions. Drop `Option` once // it's resolved. #[serde_as(as = "Option")] - pub selector: Option, + pub selector: Option, pub entry_point_type: Option, #[serde_as(as = "Vec")] - pub result: Vec, + pub result: Vec, pub execution_resources: ExecutionResources, pub internal_calls: Vec, pub events: Vec, @@ -84,9 +84,9 @@ pub struct FunctionInvocation { pub struct OrderedEventResponse { pub order: u64, #[serde_as(as = "Vec")] - pub keys: Vec, + pub keys: Vec, #[serde_as(as = "Vec")] - pub data: Vec, + pub data: Vec, } #[serde_as] @@ -96,7 +96,7 @@ pub struct OrderedL2ToL1MessageResponse { pub order: u64, pub to_address: L1Address, #[serde_as(as = "Vec")] - pub payload: Vec, + pub payload: Vec, } #[cfg(test)] diff --git a/starknet-providers/src/sequencer/models/transaction.rs b/starknet-providers/src/sequencer/models/transaction.rs index e6bc531d..db625f16 100644 --- a/starknet-providers/src/sequencer/models/transaction.rs +++ b/starknet-providers/src/sequencer/models/transaction.rs @@ -2,7 +2,7 @@ use serde::{de::Visitor, Deserialize, Serialize}; use serde_with::serde_as; use starknet_core::{ serde::unsigned_field_element::{UfeHex, UfePendingBlockHash}, - types::FieldElement, + types::Felt, }; use super::{ @@ -28,7 +28,7 @@ pub enum TransactionType { pub struct TransactionStatusInfo { #[serde(default)] #[serde_as(as = "UfePendingBlockHash")] - pub block_hash: Option, + pub block_hash: Option, #[serde(alias = "tx_status")] pub status: TransactionStatus, // This field is actually always present since v0.12.1, but we're keeping it optional until @@ -56,7 +56,7 @@ pub struct TransactionFailureReason { pub struct TransactionInfo { #[serde(default)] #[serde_as(as = "UfePendingBlockHash")] - pub block_hash: Option, + pub block_hash: Option, pub block_number: Option, pub status: TransactionStatus, // This field is actually always present since v0.12.1, but we're keeping it optional until @@ -87,31 +87,31 @@ pub enum EntryPointType { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct DeclareTransaction { #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, #[serde_as(as = "Option")] - pub compiled_class_hash: Option, + pub compiled_class_hash: Option, #[serde_as(as = "UfeHex")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, #[serde(default)] #[serde_as(as = "Option")] - pub max_fee: Option, + pub max_fee: Option, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, #[serde_as(deserialize_as = "Vec")] - pub signature: Vec, + pub signature: Vec, pub nonce_data_availability_mode: Option, pub fee_data_availability_mode: Option, pub resource_bounds: Option, #[serde(default, with = "u64_hex_opt")] pub tip: Option, #[serde_as(as = "Option>")] - pub paymaster_data: Option>, + pub paymaster_data: Option>, #[serde_as(deserialize_as = "Option>")] - pub account_deployment_data: Option>, + pub account_deployment_data: Option>, } #[serde_as] @@ -119,17 +119,17 @@ pub struct DeclareTransaction { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct DeployTransaction { #[serde_as(deserialize_as = "Vec")] - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, #[serde_as(as = "UfeHex")] - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, } #[serde_as] @@ -137,35 +137,35 @@ pub struct DeployTransaction { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct DeployAccountTransaction { #[serde_as(deserialize_as = "Vec")] - pub constructor_calldata: Vec, + pub constructor_calldata: Vec, #[serde(default)] #[serde_as(as = "Option")] - pub contract_address: Option, + pub contract_address: Option, #[serde_as(as = "UfeHex")] - pub contract_address_salt: FieldElement, + pub contract_address_salt: Felt, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, #[serde_as(as = "UfeHex")] - pub nonce: FieldElement, + pub nonce: Felt, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, #[serde_as(deserialize_as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde(default)] #[serde_as(as = "Option")] - pub max_fee: Option, + pub max_fee: Option, pub nonce_data_availability_mode: Option, pub fee_data_availability_mode: Option, pub resource_bounds: Option, #[serde(default, with = "u64_hex_opt")] pub tip: Option, #[serde_as(as = "Option>")] - pub paymaster_data: Option>, + pub paymaster_data: Option>, #[serde(default)] #[serde_as(as = "Option")] - pub sender_address: Option, + pub sender_address: Option, } #[serde_as] @@ -175,31 +175,31 @@ pub struct InvokeFunctionTransaction { #[serde_as(as = "UfeHex")] // Need this alias because older blocks still use `contract_address` #[serde(alias = "contract_address")] - pub sender_address: FieldElement, + pub sender_address: Felt, #[serde_as(as = "Option")] - pub entry_point_selector: Option, + pub entry_point_selector: Option, #[serde_as(deserialize_as = "Vec")] - pub calldata: Vec, + pub calldata: Vec, #[serde_as(deserialize_as = "Vec")] - pub signature: Vec, + pub signature: Vec, #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, #[serde(default)] #[serde_as(as = "Option")] - pub max_fee: Option, + pub max_fee: Option, #[serde_as(as = "Option")] - pub nonce: Option, + pub nonce: Option, pub nonce_data_availability_mode: Option, pub fee_data_availability_mode: Option, pub resource_bounds: Option, #[serde(default, with = "u64_hex_opt")] pub tip: Option, #[serde_as(as = "Option>")] - pub paymaster_data: Option>, + pub paymaster_data: Option>, #[serde_as(deserialize_as = "Option>")] - pub account_deployment_data: Option>, + pub account_deployment_data: Option>, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, } #[serde_as] @@ -207,17 +207,17 @@ pub struct InvokeFunctionTransaction { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct L1HandlerTransaction { #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + pub contract_address: Felt, #[serde_as(as = "UfeHex")] - pub entry_point_selector: FieldElement, + pub entry_point_selector: Felt, #[serde_as(deserialize_as = "Vec")] - pub calldata: Vec, + pub calldata: Vec, #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, #[serde_as(as = "Option")] - pub nonce: Option, + pub nonce: Option, #[serde_as(as = "UfeHex")] - pub version: FieldElement, + pub version: Felt, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -246,7 +246,7 @@ pub enum DataAvailabilityMode { struct DataAvailabilityModeVisitor; impl TransactionType { - pub fn transaction_hash(&self) -> FieldElement { + pub fn transaction_hash(&self) -> Felt { match self { TransactionType::Declare(inner) => inner.transaction_hash, TransactionType::Deploy(inner) => inner.transaction_hash, @@ -412,7 +412,7 @@ mod tests { match tx.r#type.unwrap() { TransactionType::InvokeFunction(tx) => { - assert_eq!(tx.version, FieldElement::THREE); + assert_eq!(tx.version, Felt::THREE); } _ => panic!("Did not deserialize TransactionType::InvokeFunction properly"), } @@ -428,7 +428,7 @@ mod tests { match tx.r#type.unwrap() { TransactionType::Declare(tx) => { - assert_eq!(tx.version, FieldElement::THREE); + assert_eq!(tx.version, Felt::THREE); } _ => panic!("Did not deserialize TransactionType::Declare properly"), } @@ -444,7 +444,7 @@ mod tests { match tx.r#type.unwrap() { TransactionType::DeployAccount(tx) => { - assert_eq!(tx.version, FieldElement::THREE); + assert_eq!(tx.version, Felt::THREE); } _ => panic!("Did not deserialize TransactionType::DeployAccount properly"), } @@ -463,10 +463,8 @@ mod tests { assert_eq!( tx.block_hash, Some( - FieldElement::from_hex_be( - "0x13b390a0b2c48f907cda28c73a12aa31b96d51bc1be004ba5f71174d8d70e4f" - ) - .unwrap() + Felt::from_hex("0x13b390a0b2c48f907cda28c73a12aa31b96d51bc1be004ba5f71174d8d70e4f") + .unwrap() ) ); } diff --git a/starknet-providers/src/sequencer/models/transaction_receipt.rs b/starknet-providers/src/sequencer/models/transaction_receipt.rs index 356586a4..fdcaf221 100644 --- a/starknet-providers/src/sequencer/models/transaction_receipt.rs +++ b/starknet-providers/src/sequencer/models/transaction_receipt.rs @@ -1,8 +1,9 @@ use serde::Deserialize; use serde_with::serde_as; + use starknet_core::{ serde::unsigned_field_element::{UfeHex, UfePendingBlockHash}, - types::{DataAvailabilityResources, FieldElement}, + types::{DataAvailabilityResources, Felt}, }; use super::{L1Address, TransactionFailureReason}; @@ -12,7 +13,7 @@ use super::{L1Address, TransactionFailureReason}; #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct ConfirmedReceipt { #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub transaction_index: u64, // This field is actually always present since v0.12.1, but we're keeping it optional until // mainnet is upgraded. @@ -26,7 +27,7 @@ pub struct ConfirmedReceipt { pub l2_to_l1_messages: Vec, pub events: Vec, #[serde_as(as = "UfeHex")] - pub actual_fee: FieldElement, + pub actual_fee: Felt, } #[derive(Debug, Deserialize, PartialEq, Eq)] @@ -97,13 +98,13 @@ pub struct BuiltinInstanceCounter { pub struct L1ToL2Message { pub from_address: L1Address, #[serde_as(as = "UfeHex")] - pub to_address: FieldElement, + pub to_address: Felt, #[serde_as(deserialize_as = "UfeHex")] - pub selector: FieldElement, + pub selector: Felt, #[serde_as(deserialize_as = "Vec")] - pub payload: Vec, + pub payload: Vec, #[serde_as(deserialize_as = "Option")] - pub nonce: Option, + pub nonce: Option, } #[serde_as] @@ -111,10 +112,10 @@ pub struct L1ToL2Message { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct L2ToL1Message { #[serde_as(as = "UfeHex")] - pub from_address: FieldElement, + pub from_address: Felt, pub to_address: L1Address, #[serde_as(deserialize_as = "Vec")] - pub payload: Vec, + pub payload: Vec, } #[serde_as] @@ -122,9 +123,9 @@ pub struct L2ToL1Message { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct Event { #[serde_as(as = "UfeHex")] - pub from_address: FieldElement, + pub from_address: Felt, #[serde_as(deserialize_as = "Vec")] - pub keys: Vec, + pub keys: Vec, #[serde_as(deserialize_as = "Vec")] - pub data: Vec, + pub data: Vec, } diff --git a/starknet-providers/src/sequencer/models/transaction_request.rs b/starknet-providers/src/sequencer/models/transaction_request.rs index ff294141..35dd5bb6 100644 --- a/starknet-providers/src/sequencer/models/transaction_request.rs +++ b/starknet-providers/src/sequencer/models/transaction_request.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize, Serializer}; use serde_with::serde_as; use starknet_core::{ serde::unsigned_field_element::{UfeHex, UfeHexOption}, - types::FieldElement, + types::Felt, }; use std::sync::Arc; @@ -14,27 +14,27 @@ use super::{ }; /// 2 ^ 128 + 1 -const QUERY_VERSION_ONE: FieldElement = FieldElement::from_mont([ - 18446744073700081633, - 17407, - 18446744073709551584, +const QUERY_VERSION_ONE: Felt = Felt::from_raw([ 576460752142433776, + 18446744073709551584, + 17407, + 18446744073700081633, ]); /// 2 ^ 128 + 2 -const QUERY_VERSION_TWO: FieldElement = FieldElement::from_mont([ - 18446744073700081601, - 17407, - 18446744073709551584, +const QUERY_VERSION_TWO: Felt = Felt::from_raw([ 576460752142433232, + 18446744073709551584, + 17407, + 18446744073700081601, ]); /// 2 ^ 128 + 3 -const QUERY_VERSION_THREE: FieldElement = FieldElement::from_mont([ - 18446744073700081569, - 17407, - 18446744073709551584, +const QUERY_VERSION_THREE: Felt = Felt::from_raw([ 576460752142432688, + 18446744073709551584, + 17407, + 18446744073700081569, ]); #[serde_as] @@ -43,13 +43,13 @@ const QUERY_VERSION_THREE: FieldElement = FieldElement::from_mont([ pub struct AddTransactionResult { pub code: AddTransactionResultCode, #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, #[serde(default)] #[serde_as(as = "UfeHexOption")] - pub address: Option, + pub address: Option, #[serde(default)] #[serde_as(as = "UfeHexOption")] - pub class_hash: Option, + pub class_hash: Option, } #[derive(Debug, PartialEq, Eq, Deserialize)] @@ -79,13 +79,13 @@ pub enum DeclareTransaction { pub struct DeclareV1Transaction { pub contract_class: Arc, /// The address of the account contract sending the declaration transaction. - pub sender_address: FieldElement, + pub sender_address: Felt, /// The maximal fee to be paid in Wei for declaring a contract class. - pub max_fee: FieldElement, + pub max_fee: Felt, /// Additional information given by the caller that represents the signature of the transaction. - pub signature: Vec, + pub signature: Vec, /// A sequential integer used to distinguish between transactions and order them. - pub nonce: FieldElement, + pub nonce: Felt, pub is_query: bool, } @@ -96,15 +96,15 @@ pub struct DeclareV2Transaction { /// class. This is required because at the moment, Sierra compilation is not proven, allowing /// the sequencer to run arbitrary code if this is not signed. It's expected that in the future /// this will no longer be required. - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, /// The address of the account contract sending the declaration transaction. - pub sender_address: FieldElement, + pub sender_address: Felt, /// The maximal fee to be paid in Wei for declaring a contract class. - pub max_fee: FieldElement, + pub max_fee: Felt, /// Additional information given by the caller that represents the signature of the transaction. - pub signature: Vec, + pub signature: Vec, /// A sequential integer used to distinguish between transactions and order them. - pub nonce: FieldElement, + pub nonce: Felt, pub is_query: bool, } @@ -115,19 +115,19 @@ pub struct DeclareV3Transaction { /// class. This is required because at the moment, Sierra compilation is not proven, allowing /// the sequencer to run arbitrary code if this is not signed. It's expected that in the future /// this will no longer be required. - pub compiled_class_hash: FieldElement, + pub compiled_class_hash: Felt, /// The address of the account contract sending the declaration transaction. - pub sender_address: FieldElement, + pub sender_address: Felt, /// Additional information given by the caller that represents the signature of the transaction. - pub signature: Vec, + pub signature: Vec, /// A sequential integer used to distinguish between transactions and order them. - pub nonce: FieldElement, + pub nonce: Felt, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, pub resource_bounds: ResourceBoundsMapping, pub tip: u64, - pub paymaster_data: Vec, - pub account_deployment_data: Vec, + pub paymaster_data: Vec, + pub account_deployment_data: Vec, pub is_query: bool, } @@ -140,26 +140,26 @@ pub enum InvokeFunctionTransaction { #[derive(Debug)] pub struct InvokeFunctionV1Transaction { - pub sender_address: FieldElement, - pub calldata: Vec, - pub signature: Vec, - pub max_fee: FieldElement, - pub nonce: FieldElement, + pub sender_address: Felt, + pub calldata: Vec, + pub signature: Vec, + pub max_fee: Felt, + pub nonce: Felt, pub is_query: bool, } #[derive(Debug)] pub struct InvokeFunctionV3Transaction { - pub sender_address: FieldElement, - pub calldata: Vec, - pub signature: Vec, - pub nonce: FieldElement, + pub sender_address: Felt, + pub calldata: Vec, + pub signature: Vec, + pub nonce: Felt, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, pub resource_bounds: ResourceBoundsMapping, pub tip: u64, - pub paymaster_data: Vec, - pub account_deployment_data: Vec, + pub paymaster_data: Vec, + pub account_deployment_data: Vec, pub is_query: bool, } @@ -172,32 +172,32 @@ pub enum DeployAccountTransaction { #[derive(Debug)] pub struct DeployAccountV1Transaction { - pub class_hash: FieldElement, - pub contract_address_salt: FieldElement, - pub constructor_calldata: Vec, + pub class_hash: Felt, + pub contract_address_salt: Felt, + pub constructor_calldata: Vec, // The maximal fee to be paid in Wei for executing the transaction. - pub max_fee: FieldElement, + pub max_fee: Felt, // The signature of the transaction. - pub signature: Vec, + pub signature: Vec, // The nonce of the transaction. - pub nonce: FieldElement, + pub nonce: Felt, pub is_query: bool, } #[derive(Debug)] pub struct DeployAccountV3Transaction { - pub class_hash: FieldElement, - pub contract_address_salt: FieldElement, - pub constructor_calldata: Vec, + pub class_hash: Felt, + pub contract_address_salt: Felt, + pub constructor_calldata: Vec, // The signature of the transaction. - pub signature: Vec, + pub signature: Vec, // The nonce of the transaction. - pub nonce: FieldElement, + pub nonce: Felt, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, pub resource_bounds: ResourceBoundsMapping, pub tip: u64, - pub paymaster_data: Vec, + pub paymaster_data: Vec, pub is_query: bool, } @@ -210,22 +210,22 @@ impl Serialize for DeclareV1Transaction { #[derive(Serialize)] struct Versioned<'a> { #[serde_as(as = "UfeHex")] - version: FieldElement, + version: Felt, contract_class: &'a CompressedLegacyContractClass, #[serde_as(as = "UfeHex")] - sender_address: &'a FieldElement, + sender_address: &'a Felt, #[serde_as(as = "UfeHex")] - max_fee: &'a FieldElement, - signature: &'a Vec, + max_fee: &'a Felt, + signature: &'a Vec, #[serde_as(as = "UfeHex")] - nonce: &'a FieldElement, + nonce: &'a Felt, } let versioned = Versioned { version: if self.is_query { QUERY_VERSION_ONE } else { - FieldElement::ONE + Felt::ONE }, contract_class: &self.contract_class, sender_address: &self.sender_address, @@ -247,24 +247,24 @@ impl Serialize for DeclareV2Transaction { #[derive(Serialize)] struct Versioned<'a> { #[serde_as(as = "UfeHex")] - version: FieldElement, + version: Felt, contract_class: &'a CompressedSierraClass, #[serde_as(as = "UfeHex")] - compiled_class_hash: &'a FieldElement, + compiled_class_hash: &'a Felt, #[serde_as(as = "UfeHex")] - sender_address: &'a FieldElement, + sender_address: &'a Felt, #[serde_as(as = "UfeHex")] - max_fee: &'a FieldElement, - signature: &'a Vec, + max_fee: &'a Felt, + signature: &'a Vec, #[serde_as(as = "UfeHex")] - nonce: &'a FieldElement, + nonce: &'a Felt, } let versioned = Versioned { version: if self.is_query { QUERY_VERSION_TWO } else { - FieldElement::TWO + Felt::TWO }, contract_class: &self.contract_class, compiled_class_hash: &self.compiled_class_hash, @@ -287,32 +287,32 @@ impl Serialize for DeclareV3Transaction { #[derive(Serialize)] struct Versioned<'a> { #[serde_as(as = "UfeHex")] - version: FieldElement, + version: Felt, contract_class: &'a CompressedSierraClass, #[serde_as(as = "UfeHex")] - compiled_class_hash: &'a FieldElement, + compiled_class_hash: &'a Felt, #[serde_as(as = "UfeHex")] - sender_address: &'a FieldElement, + sender_address: &'a Felt, #[serde_as(as = "Vec")] - signature: &'a Vec, + signature: &'a Vec, #[serde_as(as = "UfeHex")] - nonce: &'a FieldElement, + nonce: &'a Felt, nonce_data_availability_mode: &'a DataAvailabilityMode, fee_data_availability_mode: &'a DataAvailabilityMode, resource_bounds: &'a ResourceBoundsMapping, #[serde(with = "u64_hex")] tip: &'a u64, #[serde_as(as = "Vec")] - paymaster_data: &'a Vec, + paymaster_data: &'a Vec, #[serde_as(as = "Vec")] - account_deployment_data: &'a Vec, + account_deployment_data: &'a Vec, } let versioned = Versioned { version: if self.is_query { QUERY_VERSION_THREE } else { - FieldElement::THREE + Felt::THREE }, contract_class: &self.contract_class, compiled_class_hash: &self.compiled_class_hash, @@ -340,22 +340,22 @@ impl Serialize for InvokeFunctionV1Transaction { #[derive(Serialize)] struct Versioned<'a> { #[serde_as(as = "UfeHex")] - version: FieldElement, + version: Felt, #[serde_as(as = "UfeHex")] - sender_address: &'a FieldElement, - calldata: &'a Vec, - signature: &'a Vec, + sender_address: &'a Felt, + calldata: &'a Vec, + signature: &'a Vec, #[serde_as(as = "UfeHex")] - max_fee: &'a FieldElement, + max_fee: &'a Felt, #[serde_as(as = "UfeHex")] - nonce: &'a FieldElement, + nonce: &'a Felt, } let versioned = Versioned { version: if self.is_query { QUERY_VERSION_ONE } else { - FieldElement::ONE + Felt::ONE }, sender_address: &self.sender_address, calldata: &self.calldata, @@ -377,30 +377,30 @@ impl Serialize for InvokeFunctionV3Transaction { #[derive(Serialize)] struct Versioned<'a> { #[serde_as(as = "UfeHex")] - version: FieldElement, + version: Felt, #[serde_as(as = "UfeHex")] - sender_address: &'a FieldElement, - calldata: &'a Vec, + sender_address: &'a Felt, + calldata: &'a Vec, #[serde_as(as = "Vec")] - signature: &'a Vec, + signature: &'a Vec, #[serde_as(as = "UfeHex")] - nonce: &'a FieldElement, + nonce: &'a Felt, nonce_data_availability_mode: &'a DataAvailabilityMode, fee_data_availability_mode: &'a DataAvailabilityMode, resource_bounds: &'a ResourceBoundsMapping, #[serde(with = "u64_hex")] tip: &'a u64, #[serde_as(as = "Vec")] - paymaster_data: &'a Vec, + paymaster_data: &'a Vec, #[serde_as(as = "Vec")] - account_deployment_data: &'a Vec, + account_deployment_data: &'a Vec, } let versioned = Versioned { version: if self.is_query { QUERY_VERSION_THREE } else { - FieldElement::THREE + Felt::THREE }, sender_address: &self.sender_address, calldata: &self.calldata, @@ -427,24 +427,24 @@ impl Serialize for DeployAccountV1Transaction { #[derive(Serialize)] struct Versioned<'a> { #[serde_as(as = "UfeHex")] - version: FieldElement, + version: Felt, #[serde_as(as = "UfeHex")] - class_hash: &'a FieldElement, + class_hash: &'a Felt, #[serde_as(as = "UfeHex")] - contract_address_salt: &'a FieldElement, - constructor_calldata: &'a Vec, + contract_address_salt: &'a Felt, + constructor_calldata: &'a Vec, #[serde_as(as = "UfeHex")] - max_fee: &'a FieldElement, - signature: &'a Vec, + max_fee: &'a Felt, + signature: &'a Vec, #[serde_as(as = "UfeHex")] - nonce: &'a FieldElement, + nonce: &'a Felt, } let versioned = Versioned { version: if self.is_query { QUERY_VERSION_ONE } else { - FieldElement::ONE + Felt::ONE }, class_hash: &self.class_hash, contract_address_salt: &self.contract_address_salt, @@ -467,31 +467,31 @@ impl Serialize for DeployAccountV3Transaction { #[derive(Serialize)] struct Versioned<'a> { #[serde_as(as = "UfeHex")] - version: FieldElement, + version: Felt, #[serde_as(as = "UfeHex")] - class_hash: &'a FieldElement, + class_hash: &'a Felt, #[serde_as(as = "UfeHex")] - contract_address_salt: &'a FieldElement, + contract_address_salt: &'a Felt, #[serde_as(as = "Vec")] - constructor_calldata: &'a Vec, + constructor_calldata: &'a Vec, #[serde_as(as = "Vec")] - signature: &'a Vec, + signature: &'a Vec, #[serde_as(as = "UfeHex")] - nonce: &'a FieldElement, + nonce: &'a Felt, nonce_data_availability_mode: &'a DataAvailabilityMode, fee_data_availability_mode: &'a DataAvailabilityMode, resource_bounds: &'a ResourceBoundsMapping, #[serde(with = "u64_hex")] tip: &'a u64, #[serde_as(as = "Vec")] - paymaster_data: &'a Vec, + paymaster_data: &'a Vec, } let versioned = Versioned { version: if self.is_query { QUERY_VERSION_THREE } else { - FieldElement::THREE + Felt::THREE }, class_hash: &self.class_hash, contract_address_salt: &self.contract_address_salt, @@ -517,7 +517,7 @@ where buffer[12..].copy_from_slice(&value.0); // Unwrapping is safe here as it's never out of range - let addr_in_felt = FieldElement::from_bytes_be(&buffer).unwrap(); + let addr_in_felt = Felt::from_bytes_be(&buffer); serializer.serialize_str(&addr_in_felt.to_string()) } diff --git a/starknet-providers/src/sequencer/provider.rs b/starknet-providers/src/sequencer/provider.rs index 86beab47..b6b44bcd 100644 --- a/starknet-providers/src/sequencer/provider.rs +++ b/starknet-providers/src/sequencer/provider.rs @@ -7,7 +7,7 @@ use starknet_core::types::{ BlockHashAndNumber, BlockId, BroadcastedDeclareTransaction, BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction, ContractClass, DeclareTransactionResult, DeployAccountTransactionResult, EventFilter, - EventsPage, FeeEstimate, FieldElement, FunctionCall, InvokeTransactionResult, + EventsPage, FeeEstimate, Felt, FunctionCall, InvokeTransactionResult, MaybePendingBlockWithReceipts, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate, MsgFromL1, SimulatedTransaction, SimulationFlag, SimulationFlagForEstimateFee, StarknetError, SyncStatusType, Transaction, @@ -87,10 +87,10 @@ impl Provider for SequencerGatewayProvider { contract_address: A, key: K, block_id: B, - ) -> Result + ) -> Result where - A: AsRef + Send + Sync, - K: AsRef + Send + Sync, + A: AsRef + Send + Sync, + K: AsRef + Send + Sync, B: AsRef + Send + Sync, { // Deprecated since Starknet v0.12.3 @@ -106,7 +106,7 @@ impl Provider for SequencerGatewayProvider { transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { let status = self .get_transaction_status(*transaction_hash.as_ref()) @@ -127,7 +127,7 @@ impl Provider for SequencerGatewayProvider { transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { Ok(self .get_transaction(*transaction_hash.as_ref()) @@ -160,7 +160,7 @@ impl Provider for SequencerGatewayProvider { transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { // Deprecated since Starknet v0.12.3 Err(ProviderError::Other(Box::new( @@ -175,7 +175,7 @@ impl Provider for SequencerGatewayProvider { ) -> Result where B: AsRef + Send + Sync, - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { Ok(self .get_class_by_hash(*class_hash.as_ref(), block_id.as_ref().to_owned().into()) @@ -187,10 +187,10 @@ impl Provider for SequencerGatewayProvider { &self, block_id: B, contract_address: A, - ) -> Result + ) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync, + A: AsRef + Send + Sync, { // Deprecated since Starknet v0.12.3 Err(ProviderError::Other(Box::new( @@ -205,7 +205,7 @@ impl Provider for SequencerGatewayProvider { ) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync, + A: AsRef + Send + Sync, { // Deprecated since Starknet v0.12.3 Err(ProviderError::Other(Box::new( @@ -221,7 +221,7 @@ impl Provider for SequencerGatewayProvider { Ok(block.transactions.len() as u64) } - async fn call(&self, request: R, block_id: B) -> Result, ProviderError> + async fn call(&self, request: R, block_id: B) -> Result, ProviderError> where R: AsRef + Send + Sync, B: AsRef + Send + Sync, @@ -277,7 +277,7 @@ impl Provider for SequencerGatewayProvider { }) } - async fn chain_id(&self) -> Result { + async fn chain_id(&self) -> Result { Ok(self.chain_id) } @@ -296,14 +296,10 @@ impl Provider for SequencerGatewayProvider { ))) } - async fn get_nonce( - &self, - block_id: B, - contract_address: A, - ) -> Result + async fn get_nonce(&self, block_id: B, contract_address: A) -> Result where B: AsRef + Send + Sync, - A: AsRef + Send + Sync, + A: AsRef + Send + Sync, { // Deprecated since Starknet v0.12.3 Err(ProviderError::Other(Box::new( @@ -372,7 +368,7 @@ impl Provider for SequencerGatewayProvider { _transaction_hash: H, ) -> Result where - H: AsRef + Send + Sync, + H: AsRef + Send + Sync, { // With JSON-RPC v0.5.0 it's no longer possible to convert feeder traces to JSON-RPC traces. So we simply pretend that it's not supported here. // diff --git a/starknet-providers/tests/jsonrpc.rs b/starknet-providers/tests/jsonrpc.rs index acc7fa3f..bddd2ab4 100644 --- a/starknet-providers/tests/jsonrpc.rs +++ b/starknet-providers/tests/jsonrpc.rs @@ -2,7 +2,7 @@ use starknet_core::{ types::{ BlockId, BlockTag, BroadcastedInvokeTransaction, BroadcastedInvokeTransactionV1, BroadcastedTransaction, ContractClass, DeclareTransaction, DeployAccountTransaction, - EthAddress, EventFilter, ExecuteInvocation, ExecutionResult, FieldElement, FunctionCall, + EthAddress, EventFilter, ExecuteInvocation, ExecutionResult, Felt, FunctionCall, InvokeTransaction, MaybePendingBlockWithReceipts, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate, MsgFromL1, StarknetError, SyncStatusType, Transaction, TransactionExecutionStatus, TransactionReceipt, @@ -96,7 +96,7 @@ async fn jsonrpc_get_state_update() { _ => panic!("unexpected data type"), }; - assert!(state_update.new_root > FieldElement::ZERO); + assert!(state_update.new_root > Felt::ZERO); } #[tokio::test] @@ -106,13 +106,11 @@ async fn jsonrpc_get_storage_at() { // Checks L2 ETH balance via storage taking advantage of implementation detail let eth_balance = rpc_client .get_storage_at( - FieldElement::from_hex_be( - "049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - ) - .unwrap(), + Felt::from_hex("049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7") + .unwrap(), get_storage_var_address( "ERC20_balances", - &[FieldElement::from_hex_be( + &[Felt::from_hex( "03f47d3911396b6d579fd7848cf576286ab6f96dda977915d6c7b10f3dd2315b", ) .unwrap()], @@ -123,7 +121,7 @@ async fn jsonrpc_get_storage_at() { .await .unwrap(); - assert!(eth_balance > FieldElement::ZERO); + assert!(eth_balance > Felt::ZERO); } // Test case `jsonrpc_get_transaction_status_rejected` was removed as there is no `REJECTED` @@ -135,10 +133,8 @@ async fn jsonrpc_get_transaction_status_succeeded() { let status = rpc_client .get_transaction_status( - FieldElement::from_hex_be( - "03f786ecc4955a2602c91a291328518ef866cb7f3d50e4b16fd42282952623aa", - ) - .unwrap(), + Felt::from_hex("03f786ecc4955a2602c91a291328518ef866cb7f3d50e4b16fd42282952623aa") + .unwrap(), ) .await .unwrap(); @@ -155,10 +151,8 @@ async fn jsonrpc_get_transaction_status_reverted() { let status = rpc_client .get_transaction_status( - FieldElement::from_hex_be( - "02f00c7f28df2197196440747f97baa63d0851e3b0cfc2efedb6a88a7ef78cb1", - ) - .unwrap(), + Felt::from_hex("02f00c7f28df2197196440747f97baa63d0851e3b0cfc2efedb6a88a7ef78cb1") + .unwrap(), ) .await .unwrap(); @@ -178,10 +172,8 @@ async fn jsonrpc_get_transaction_by_hash_invoke_v1() { let tx = rpc_client .get_transaction_by_hash( - FieldElement::from_hex_be( - "03f786ecc4955a2602c91a291328518ef866cb7f3d50e4b16fd42282952623aa", - ) - .unwrap(), + Felt::from_hex("03f786ecc4955a2602c91a291328518ef866cb7f3d50e4b16fd42282952623aa") + .unwrap(), ) .await .unwrap(); @@ -191,7 +183,7 @@ async fn jsonrpc_get_transaction_by_hash_invoke_v1() { _ => panic!("unexpected tx response type"), }; - assert!(tx.sender_address > FieldElement::ZERO); + assert!(tx.sender_address > Felt::ZERO); } #[tokio::test] @@ -200,10 +192,8 @@ async fn jsonrpc_get_transaction_by_hash_l1_handler() { let tx = rpc_client .get_transaction_by_hash( - FieldElement::from_hex_be( - "0785c2ada3f53fbc66078d47715c27718f92e6e48b96372b36e5197de69b82b5", - ) - .unwrap(), + Felt::from_hex("0785c2ada3f53fbc66078d47715c27718f92e6e48b96372b36e5197de69b82b5") + .unwrap(), ) .await .unwrap(); @@ -213,7 +203,7 @@ async fn jsonrpc_get_transaction_by_hash_l1_handler() { _ => panic!("unexpected tx response type"), }; - assert!(tx.entry_point_selector > FieldElement::ZERO); + assert!(tx.entry_point_selector > Felt::ZERO); } #[tokio::test] @@ -222,10 +212,8 @@ async fn jsonrpc_get_transaction_by_hash_declare_v0() { let tx = rpc_client .get_transaction_by_hash( - FieldElement::from_hex_be( - "030a541df2547ed9f94602c35daf61ce3a8e179ec75d26cbe34e0ec61f823695", - ) - .unwrap(), + Felt::from_hex("030a541df2547ed9f94602c35daf61ce3a8e179ec75d26cbe34e0ec61f823695") + .unwrap(), ) .await .unwrap(); @@ -235,7 +223,7 @@ async fn jsonrpc_get_transaction_by_hash_declare_v0() { _ => panic!("unexpected tx response type"), }; - assert!(tx.sender_address > FieldElement::ZERO); + assert!(tx.sender_address > Felt::ZERO); } #[tokio::test] @@ -244,10 +232,8 @@ async fn jsonrpc_get_transaction_by_hash_declare_v1() { let tx = rpc_client .get_transaction_by_hash( - FieldElement::from_hex_be( - "01936a09e5aaee208fc0f7cc826e126d421c3ac9aca2c789605e1e919e399185", - ) - .unwrap(), + Felt::from_hex("01936a09e5aaee208fc0f7cc826e126d421c3ac9aca2c789605e1e919e399185") + .unwrap(), ) .await .unwrap(); @@ -257,7 +243,7 @@ async fn jsonrpc_get_transaction_by_hash_declare_v1() { _ => panic!("unexpected tx response type"), }; - assert!(tx.sender_address > FieldElement::ZERO); + assert!(tx.sender_address > Felt::ZERO); } #[tokio::test] @@ -266,10 +252,8 @@ async fn jsonrpc_get_transaction_by_hash_declare_v2() { let tx = rpc_client .get_transaction_by_hash( - FieldElement::from_hex_be( - "004cacc2bbdd5ec77b20e908f311ab27d6495b69761e929bb24ba02632716944", - ) - .unwrap(), + Felt::from_hex("004cacc2bbdd5ec77b20e908f311ab27d6495b69761e929bb24ba02632716944") + .unwrap(), ) .await .unwrap(); @@ -279,7 +263,7 @@ async fn jsonrpc_get_transaction_by_hash_declare_v2() { _ => panic!("unexpected tx response type"), }; - assert!(tx.sender_address > FieldElement::ZERO); + assert!(tx.sender_address > Felt::ZERO); } #[tokio::test] @@ -288,10 +272,8 @@ async fn jsonrpc_get_transaction_by_hash_declare_v3() { let tx = rpc_client .get_transaction_by_hash( - FieldElement::from_hex_be( - "054270d103c875a613e013d1fd555edcff2085feca9d7b4532243a8257fd5cf3", - ) - .unwrap(), + Felt::from_hex("054270d103c875a613e013d1fd555edcff2085feca9d7b4532243a8257fd5cf3") + .unwrap(), ) .await .unwrap(); @@ -301,7 +283,7 @@ async fn jsonrpc_get_transaction_by_hash_declare_v3() { _ => panic!("unexpected tx response type"), }; - assert!(tx.sender_address > FieldElement::ZERO); + assert!(tx.sender_address > Felt::ZERO); } // Test case `jsonrpc_get_transaction_by_hash_deploy` was removed as there is no `DEPLOY` @@ -313,10 +295,8 @@ async fn jsonrpc_get_transaction_by_hash_deploy_account_v1() { let tx = rpc_client .get_transaction_by_hash( - FieldElement::from_hex_be( - "024ed6b82e2f6d3a811ec180a25c1ccd0bdc7bdba8ebd709de2ed697a1e82193", - ) - .unwrap(), + Felt::from_hex("024ed6b82e2f6d3a811ec180a25c1ccd0bdc7bdba8ebd709de2ed697a1e82193") + .unwrap(), ) .await .unwrap(); @@ -326,7 +306,7 @@ async fn jsonrpc_get_transaction_by_hash_deploy_account_v1() { _ => panic!("unexpected tx response type"), }; - assert!(tx.class_hash > FieldElement::ZERO); + assert!(tx.class_hash > Felt::ZERO); } #[tokio::test] @@ -335,10 +315,8 @@ async fn jsonrpc_get_transaction_by_hash_deploy_account_v3() { let tx = rpc_client .get_transaction_by_hash( - FieldElement::from_hex_be( - "011c67fb3a9a623b3190c9ac41ebf7f5dd421f2583344c498a30a7280c660f01", - ) - .unwrap(), + Felt::from_hex("011c67fb3a9a623b3190c9ac41ebf7f5dd421f2583344c498a30a7280c660f01") + .unwrap(), ) .await .unwrap(); @@ -348,7 +326,7 @@ async fn jsonrpc_get_transaction_by_hash_deploy_account_v3() { _ => panic!("unexpected tx response type"), }; - assert!(tx.class_hash > FieldElement::ZERO); + assert!(tx.class_hash > Felt::ZERO); } #[tokio::test] @@ -365,7 +343,7 @@ async fn jsonrpc_get_transaction_by_block_id_and_index() { _ => panic!("unexpected tx response type"), }; - assert!(tx.sender_address > FieldElement::ZERO); + assert!(tx.sender_address > Felt::ZERO); } #[tokio::test] @@ -373,7 +351,7 @@ async fn jsonrpc_get_transaction_by_hash_non_existent_tx() { let rpc_client = create_jsonrpc_client(); let err = rpc_client - .get_transaction_by_hash(FieldElement::from_hex_be("1234").unwrap()) + .get_transaction_by_hash(Felt::from_hex("1234").unwrap()) .await .unwrap_err(); @@ -391,10 +369,8 @@ async fn jsonrpc_get_transaction_receipt_invoke() { let receipt = rpc_client .get_transaction_receipt( - FieldElement::from_hex_be( - "03f786ecc4955a2602c91a291328518ef866cb7f3d50e4b16fd42282952623aa", - ) - .unwrap(), + Felt::from_hex("03f786ecc4955a2602c91a291328518ef866cb7f3d50e4b16fd42282952623aa") + .unwrap(), ) .await .unwrap(); @@ -418,10 +394,8 @@ async fn jsonrpc_get_transaction_receipt_invoke_reverted() { let receipt = rpc_client .get_transaction_receipt( - FieldElement::from_hex_be( - "02f00c7f28df2197196440747f97baa63d0851e3b0cfc2efedb6a88a7ef78cb1", - ) - .unwrap(), + Felt::from_hex("02f00c7f28df2197196440747f97baa63d0851e3b0cfc2efedb6a88a7ef78cb1") + .unwrap(), ) .await .unwrap(); @@ -443,10 +417,8 @@ async fn jsonrpc_get_transaction_receipt_invoke_reverted() { async fn jsonrpc_get_transaction_receipt_l1_handler() { let rpc_client = create_jsonrpc_client(); - let tx_hash = FieldElement::from_hex_be( - "0785c2ada3f53fbc66078d47715c27718f92e6e48b96372b36e5197de69b82b5", - ) - .unwrap(); + let tx_hash = + Felt::from_hex("0785c2ada3f53fbc66078d47715c27718f92e6e48b96372b36e5197de69b82b5").unwrap(); let tx = rpc_client.get_transaction_by_hash(tx_hash).await.unwrap(); let receipt = rpc_client.get_transaction_receipt(tx_hash).await.unwrap(); @@ -477,10 +449,8 @@ async fn jsonrpc_get_transaction_receipt_declare() { let receipt = rpc_client .get_transaction_receipt( - FieldElement::from_hex_be( - "01936a09e5aaee208fc0f7cc826e126d421c3ac9aca2c789605e1e919e399185", - ) - .unwrap(), + Felt::from_hex("01936a09e5aaee208fc0f7cc826e126d421c3ac9aca2c789605e1e919e399185") + .unwrap(), ) .await .unwrap(); @@ -507,10 +477,8 @@ async fn jsonrpc_get_transaction_receipt_deploy_account() { let receipt = rpc_client .get_transaction_receipt( - FieldElement::from_hex_be( - "024ed6b82e2f6d3a811ec180a25c1ccd0bdc7bdba8ebd709de2ed697a1e82193", - ) - .unwrap(), + Felt::from_hex("024ed6b82e2f6d3a811ec180a25c1ccd0bdc7bdba8ebd709de2ed697a1e82193") + .unwrap(), ) .await .unwrap(); @@ -535,10 +503,8 @@ async fn jsonrpc_get_class_cairo_0() { let class = rpc_client .get_class( BlockId::Tag(BlockTag::Latest), - FieldElement::from_hex_be( - "07b3e05f48f0c69e4a65ce5e076a66271a527aff2c34ce1083ec6e1526997a69", - ) - .unwrap(), + Felt::from_hex("07b3e05f48f0c69e4a65ce5e076a66271a527aff2c34ce1083ec6e1526997a69") + .unwrap(), ) .await .unwrap(); @@ -558,10 +524,8 @@ async fn jsonrpc_get_class_cairo_1() { let class = rpc_client .get_class( BlockId::Tag(BlockTag::Latest), - FieldElement::from_hex_be( - "01a736d6ed154502257f02b1ccdf4d9d1089f80811cd6acad48e6b6a9d1f2003", - ) - .unwrap(), + Felt::from_hex("01a736d6ed154502257f02b1ccdf4d9d1089f80811cd6acad48e6b6a9d1f2003") + .unwrap(), ) .await .unwrap(); @@ -581,20 +545,15 @@ async fn jsonrpc_get_class_hash_at() { let class_hash = rpc_client .get_class_hash_at( BlockId::Tag(BlockTag::Latest), - FieldElement::from_hex_be( - "041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf", - ) - .unwrap(), + Felt::from_hex("041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf") + .unwrap(), ) .await .unwrap(); assert_eq!( class_hash, - FieldElement::from_hex_be( - "07b3e05f48f0c69e4a65ce5e076a66271a527aff2c34ce1083ec6e1526997a69" - ) - .unwrap() + Felt::from_hex("07b3e05f48f0c69e4a65ce5e076a66271a527aff2c34ce1083ec6e1526997a69").unwrap() ); } @@ -605,10 +564,8 @@ async fn jsonrpc_get_class_at() { let class = rpc_client .get_class_at( BlockId::Tag(BlockTag::Latest), - FieldElement::from_hex_be( - "041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf", - ) - .unwrap(), + Felt::from_hex("041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf") + .unwrap(), ) .await .unwrap(); @@ -641,12 +598,12 @@ async fn jsonrpc_call() { let eth_balance = rpc_client .call( &FunctionCall { - contract_address: FieldElement::from_hex_be( + contract_address: Felt::from_hex( "049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", ) .unwrap(), entry_point_selector: get_selector_from_name("balanceOf").unwrap(), - calldata: vec![FieldElement::from_hex_be( + calldata: vec![Felt::from_hex( "03f47d3911396b6d579fd7848cf576286ab6f96dda977915d6c7b10f3dd2315b", ) .unwrap()], @@ -656,7 +613,7 @@ async fn jsonrpc_call() { .await .unwrap(); - assert!(eth_balance[0] > FieldElement::ZERO); + assert!(eth_balance[0] > Felt::ZERO); } #[tokio::test] @@ -667,36 +624,36 @@ async fn jsonrpc_estimate_fee() { .estimate_fee_single( BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction::V1( BroadcastedInvokeTransactionV1 { - max_fee: FieldElement::ZERO, + max_fee: Felt::ZERO, signature: vec![ - FieldElement::from_hex_be( + Felt::from_hex( "0024bd9efc809227bbcdfbd5a38b9255562184f944336c662037865dddda7a98", ) .unwrap(), - FieldElement::from_hex_be( + Felt::from_hex( "0647f552129f367c1053caeb722c3e1d5719032e229c08dbfde988bd87c9cc3e", ) .unwrap(), ], - nonce: FieldElement::ONE, - sender_address: FieldElement::from_hex_be( + nonce: Felt::ONE, + sender_address: Felt::from_hex( "047e5089068f45ed6f7e1396157cd2346dfecbf1c77f396c03d45db3b164f5a0", ) .unwrap(), calldata: vec![ - FieldElement::from_hex_be("1").unwrap(), - FieldElement::from_hex_be( + Felt::from_hex("1").unwrap(), + Felt::from_hex( "049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", ) .unwrap(), - FieldElement::from_hex_be( + Felt::from_hex( "0083afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", ) .unwrap(), - FieldElement::from_hex_be("3").unwrap(), - FieldElement::from_hex_be("1234").unwrap(), - FieldElement::from_hex_be("64").unwrap(), - FieldElement::from_hex_be("0").unwrap(), + Felt::from_hex("3").unwrap(), + Felt::from_hex("1234").unwrap(), + Felt::from_hex("64").unwrap(), + Felt::from_hex("0").unwrap(), ], is_query: true, }, @@ -707,9 +664,9 @@ async fn jsonrpc_estimate_fee() { .await .unwrap(); - assert!(estimate.gas_consumed > FieldElement::ZERO); - assert!(estimate.gas_price > FieldElement::ZERO); - assert!(estimate.overall_fee > FieldElement::ZERO); + assert!(estimate.gas_consumed > Felt::ZERO); + assert!(estimate.gas_price > Felt::ZERO); + assert!(estimate.overall_fee > Felt::ZERO); } #[tokio::test] @@ -721,24 +678,24 @@ async fn jsonrpc_estimate_message_fee() { MsgFromL1 { from_address: EthAddress::from_hex("0x8453FC6Cd1bCfE8D4dFC069C400B433054d47bDc") .unwrap(), - to_address: FieldElement::from_hex_be( + to_address: Felt::from_hex( "04c5772d1914fe6ce891b64eb35bf3522aeae1315647314aac58b01137607f3f", ) .unwrap(), - entry_point_selector: FieldElement::from_hex_be( + entry_point_selector: Felt::from_hex( "02d757788a8d8d6f21d1cd40bce38a8222d70654214e96ff95d8086e684fbee5", ) .unwrap(), - payload: vec![FieldElement::ONE, FieldElement::ONE, FieldElement::ONE], + payload: vec![Felt::ONE, Felt::ONE, Felt::ONE], }, BlockId::Tag(BlockTag::Latest), ) .await .unwrap(); - assert!(estimate.gas_consumed > FieldElement::ZERO); - assert!(estimate.gas_price > FieldElement::ZERO); - assert!(estimate.overall_fee > FieldElement::ZERO); + assert!(estimate.gas_consumed > Felt::ZERO); + assert!(estimate.gas_price > Felt::ZERO); + assert!(estimate.overall_fee > Felt::ZERO); } #[tokio::test] @@ -755,7 +712,7 @@ async fn jsonrpc_block_hash_and_number() { let id = rpc_client.block_hash_and_number().await.unwrap(); - assert!(id.block_hash > FieldElement::ZERO); + assert!(id.block_hash > Felt::ZERO); assert!(id.block_number > 0); } @@ -764,7 +721,7 @@ async fn jsonrpc_chain_id() { let rpc_client = create_jsonrpc_client(); let chain_id = rpc_client.chain_id().await.unwrap(); - assert!(chain_id > FieldElement::ZERO); + assert!(chain_id > Felt::ZERO); } #[tokio::test] @@ -805,15 +762,13 @@ async fn jsonrpc_get_nonce() { let nonce = rpc_client .get_nonce( BlockId::Tag(BlockTag::Latest), - FieldElement::from_hex_be( - "047e5089068f45ed6f7e1396157cd2346dfecbf1c77f396c03d45db3b164f5a0", - ) - .unwrap(), + Felt::from_hex("047e5089068f45ed6f7e1396157cd2346dfecbf1c77f396c03d45db3b164f5a0") + .unwrap(), ) .await .unwrap(); - assert_eq!(nonce, FieldElement::ONE); + assert_eq!(nonce, Felt::ONE); } #[tokio::test] @@ -822,10 +777,8 @@ async fn jsonrpc_trace_invoke() { let trace = rpc_client .trace_transaction( - FieldElement::from_hex_be( - "03f786ecc4955a2602c91a291328518ef866cb7f3d50e4b16fd42282952623aa", - ) - .unwrap(), + Felt::from_hex("03f786ecc4955a2602c91a291328518ef866cb7f3d50e4b16fd42282952623aa") + .unwrap(), ) .await .unwrap(); @@ -847,10 +800,8 @@ async fn jsonrpc_trace_invoke_reverted() { let trace = rpc_client .trace_transaction( - FieldElement::from_hex_be( - "02f00c7f28df2197196440747f97baa63d0851e3b0cfc2efedb6a88a7ef78cb1", - ) - .unwrap(), + Felt::from_hex("02f00c7f28df2197196440747f97baa63d0851e3b0cfc2efedb6a88a7ef78cb1") + .unwrap(), ) .await .unwrap(); @@ -872,10 +823,8 @@ async fn jsonrpc_trace_l1_handler() { let trace = rpc_client .trace_transaction( - FieldElement::from_hex_be( - "0785c2ada3f53fbc66078d47715c27718f92e6e48b96372b36e5197de69b82b5", - ) - .unwrap(), + Felt::from_hex("0785c2ada3f53fbc66078d47715c27718f92e6e48b96372b36e5197de69b82b5") + .unwrap(), ) .await .unwrap(); @@ -892,10 +841,8 @@ async fn jsonrpc_trace_declare() { let trace = rpc_client .trace_transaction( - FieldElement::from_hex_be( - "01936a09e5aaee208fc0f7cc826e126d421c3ac9aca2c789605e1e919e399185", - ) - .unwrap(), + Felt::from_hex("01936a09e5aaee208fc0f7cc826e126d421c3ac9aca2c789605e1e919e399185") + .unwrap(), ) .await .unwrap(); @@ -914,10 +861,8 @@ async fn jsonrpc_trace_deploy_account() { let trace = rpc_client .trace_transaction( - FieldElement::from_hex_be( - "024ed6b82e2f6d3a811ec180a25c1ccd0bdc7bdba8ebd709de2ed697a1e82193", - ) - .unwrap(), + Felt::from_hex("024ed6b82e2f6d3a811ec180a25c1ccd0bdc7bdba8ebd709de2ed697a1e82193") + .unwrap(), ) .await .unwrap(); diff --git a/starknet-signers/Cargo.toml b/starknet-signers/Cargo.toml index dc64c7c0..aefea7a2 100644 --- a/starknet-signers/Cargo.toml +++ b/starknet-signers/Cargo.toml @@ -24,5 +24,8 @@ rand = { version = "0.8.5", features = ["std_rng"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] eth-keystore = { version = "0.5.0", default-features = false } +[target.'cfg(target_arch = "wasm32")'.dependencies] +getrandom = { version = "0.2.9", features = ["js"] } + [target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen-test = "0.3.34" diff --git a/starknet-signers/src/key_pair.rs b/starknet-signers/src/key_pair.rs index 23ad1276..31a7cefe 100644 --- a/starknet-signers/src/key_pair.rs +++ b/starknet-signers/src/key_pair.rs @@ -2,18 +2,18 @@ use crypto_bigint::{Encoding, NonZero, U256}; use rand::{rngs::StdRng, Rng, SeedableRng}; use starknet_core::{ crypto::{ecdsa_sign, ecdsa_verify, EcdsaSignError, EcdsaVerifyError, Signature}, - types::FieldElement, + types::Felt, }; use starknet_crypto::get_public_key; #[derive(Debug, Clone)] pub struct SigningKey { - secret_scalar: FieldElement, + secret_scalar: Felt, } #[derive(Debug, Clone)] pub struct VerifyingKey { - scalar: FieldElement, + scalar: Felt, } #[cfg(not(target_arch = "wasm32"))] @@ -42,12 +42,12 @@ impl SigningKey { let secret_scalar = random_u256.rem(&PRIME); // It's safe to unwrap here as we're 100% sure it's not out of range - let secret_scalar = FieldElement::from_byte_slice_be(&secret_scalar.to_be_bytes()).unwrap(); + let secret_scalar = Felt::from_bytes_be_slice(&secret_scalar.to_be_bytes()); Self { secret_scalar } } - pub fn from_secret_scalar(secret_scalar: FieldElement) -> Self { + pub fn from_secret_scalar(secret_scalar: Felt) -> Self { Self { secret_scalar } } @@ -58,8 +58,7 @@ impl SigningKey { P: AsRef, { let key = eth_keystore::decrypt_key(path, password).map_err(KeystoreError::Inner)?; - let secret_scalar = - FieldElement::from_byte_slice_be(&key).map_err(|_| KeystoreError::InvalidScalar)?; + let secret_scalar = Felt::from_bytes_be_slice(&key); Ok(Self::from_secret_scalar(secret_scalar)) } @@ -93,7 +92,7 @@ impl SigningKey { Ok(()) } - pub fn secret_scalar(&self) -> FieldElement { + pub fn secret_scalar(&self) -> Felt { self.secret_scalar } @@ -101,25 +100,21 @@ impl SigningKey { VerifyingKey::from_scalar(get_public_key(&self.secret_scalar)) } - pub fn sign(&self, hash: &FieldElement) -> Result { + pub fn sign(&self, hash: &Felt) -> Result { ecdsa_sign(&self.secret_scalar, hash).map(|sig| sig.into()) } } impl VerifyingKey { - pub fn from_scalar(scalar: FieldElement) -> Self { + pub fn from_scalar(scalar: Felt) -> Self { Self { scalar } } - pub fn scalar(&self) -> FieldElement { + pub fn scalar(&self) -> Felt { self.scalar } - pub fn verify( - &self, - hash: &FieldElement, - signature: &Signature, - ) -> Result { + pub fn verify(&self, hash: &Felt, signature: &Signature) -> Result { ecdsa_verify(&self.scalar, hash, signature) } } @@ -132,10 +127,9 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_get_secret_scalar() { // Generated with `cairo-lang` - let private_key = FieldElement::from_hex_be( - "0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79", - ) - .unwrap(); + let private_key = + Felt::from_hex("0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79") + .unwrap(); let signing_key = SigningKey::from_secret_scalar(private_key); @@ -146,14 +140,12 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_get_verifying_key() { // Generated with `cairo-lang` - let private_key = FieldElement::from_hex_be( - "0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79", - ) - .unwrap(); - let expected_public_key = FieldElement::from_hex_be( - "02c5dbad71c92a45cc4b40573ae661f8147869a91d57b8d9b8f48c8af7f83159", - ) - .unwrap(); + let private_key = + Felt::from_hex("0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79") + .unwrap(); + let expected_public_key = + Felt::from_hex("02c5dbad71c92a45cc4b40573ae661f8147869a91d57b8d9b8f48c8af7f83159") + .unwrap(); let signing_key = SigningKey::from_secret_scalar(private_key); let verifying_key = signing_key.verifying_key(); @@ -165,22 +157,18 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_sign() { // Generated with `cairo-lang` - let private_key = FieldElement::from_hex_be( - "0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79", - ) - .unwrap(); - let hash = FieldElement::from_hex_be( - "06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76", - ) - .unwrap(); - let expected_r = FieldElement::from_hex_be( - "061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f", - ) - .unwrap(); - let expected_s = FieldElement::from_hex_be( - "04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a", - ) - .unwrap(); + let private_key = + Felt::from_hex("0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79") + .unwrap(); + let hash = + Felt::from_hex("06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76") + .unwrap(); + let expected_r = + Felt::from_hex("061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f") + .unwrap(); + let expected_s = + Felt::from_hex("04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a") + .unwrap(); let signing_key = SigningKey::from_secret_scalar(private_key); let signature = signing_key.sign(&hash).unwrap(); @@ -192,14 +180,12 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_hash_out_of_range() { - let private_key = FieldElement::from_hex_be( - "0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79", - ) - .unwrap(); - let hash = FieldElement::from_hex_be( - "0800000000000000000000000000000000000000000000000000000000000000", - ) - .unwrap(); + let private_key = + Felt::from_hex("0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79") + .unwrap(); + let hash = + Felt::from_hex("0800000000000000000000000000000000000000000000000000000000000000") + .unwrap(); let signing_key = SigningKey::from_secret_scalar(private_key); @@ -213,22 +199,16 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_verify_valid_signature() { // Generated with `cairo-lang` - let public_key = FieldElement::from_hex_be( - "02c5dbad71c92a45cc4b40573ae661f8147869a91d57b8d9b8f48c8af7f83159", - ) - .unwrap(); - let hash = FieldElement::from_hex_be( - "06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76", - ) - .unwrap(); - let r = FieldElement::from_hex_be( - "061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f", - ) - .unwrap(); - let s = FieldElement::from_hex_be( - "04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a", - ) - .unwrap(); + let public_key = + Felt::from_hex("02c5dbad71c92a45cc4b40573ae661f8147869a91d57b8d9b8f48c8af7f83159") + .unwrap(); + let hash = + Felt::from_hex("06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76") + .unwrap(); + let r = Felt::from_hex("061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f") + .unwrap(); + let s = Felt::from_hex("04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a") + .unwrap(); let verifying_key = VerifyingKey::from_scalar(public_key); @@ -239,22 +219,16 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_verify_invalid_signature() { // Generated with `cairo-lang` - let public_key = FieldElement::from_hex_be( - "02c5dbad71c92a45cc4b40573ae661f8147869a91d57b8d9b8f48c8af7f83159", - ) - .unwrap(); - let hash = FieldElement::from_hex_be( - "06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76", - ) - .unwrap(); - let r = FieldElement::from_hex_be( - "061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f", - ) - .unwrap(); - let s = FieldElement::from_hex_be( - "04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9b", - ) - .unwrap(); + let public_key = + Felt::from_hex("02c5dbad71c92a45cc4b40573ae661f8147869a91d57b8d9b8f48c8af7f83159") + .unwrap(); + let hash = + Felt::from_hex("06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76") + .unwrap(); + let r = Felt::from_hex("061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f") + .unwrap(); + let s = Felt::from_hex("04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9b") + .unwrap(); let verifying_key = VerifyingKey::from_scalar(public_key); diff --git a/starknet-signers/src/local_wallet.rs b/starknet-signers/src/local_wallet.rs index c4ce3778..23c00b28 100644 --- a/starknet-signers/src/local_wallet.rs +++ b/starknet-signers/src/local_wallet.rs @@ -3,7 +3,7 @@ use crate::{Infallible, Signer, SigningKey, VerifyingKey}; use async_trait::async_trait; use starknet_core::{ crypto::{EcdsaSignError, Signature}, - types::FieldElement, + types::Felt, }; #[derive(Debug, Clone)] @@ -33,7 +33,7 @@ impl Signer for LocalWallet { Ok(self.private_key.verifying_key()) } - async fn sign_hash(&self, hash: &FieldElement) -> Result { + async fn sign_hash(&self, hash: &Felt) -> Result { Ok(self.private_key.sign(hash)?) } } diff --git a/starknet-signers/src/signer.rs b/starknet-signers/src/signer.rs index 777d3a3a..0f586f82 100644 --- a/starknet-signers/src/signer.rs +++ b/starknet-signers/src/signer.rs @@ -2,7 +2,7 @@ use crate::VerifyingKey; use async_trait::async_trait; use auto_impl::auto_impl; -use starknet_core::{crypto::Signature, types::FieldElement}; +use starknet_core::{crypto::Signature, types::Felt}; use std::error::Error; #[cfg_attr(not(target_arch = "wasm32"), async_trait)] @@ -14,5 +14,5 @@ pub trait Signer { async fn get_public_key(&self) -> Result; - async fn sign_hash(&self, hash: &FieldElement) -> Result; + async fn sign_hash(&self, hash: &Felt) -> Result; } diff --git a/tests/macros.rs b/tests/macros.rs index b9fafae4..9bc25193 100644 --- a/tests/macros.rs +++ b/tests/macros.rs @@ -1,6 +1,6 @@ use starknet::{ core::{ - types::FieldElement, + types::Felt, utils::{cairo_short_string_to_felt, get_selector_from_name}, }, macros::{felt, felt_dec, felt_hex, selector, short_string}, @@ -28,7 +28,7 @@ fn short_string_can_generate_correct_short_string() { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn felt_with_dec_string() { let macro_value = felt!("1234567"); - let function_call_value = FieldElement::from_dec_str("1234567").unwrap(); + let function_call_value = Felt::from_dec_str("1234567").unwrap(); assert_eq!(macro_value, function_call_value); } @@ -37,7 +37,7 @@ fn felt_with_dec_string() { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn felt_with_hex_string() { let macro_value = felt!("0x123456789abcdef"); - let function_call_value = FieldElement::from_hex_be("0x123456789abcdef").unwrap(); + let function_call_value = Felt::from_hex("0x123456789abcdef").unwrap(); assert_eq!(macro_value, function_call_value); } @@ -46,7 +46,7 @@ fn felt_with_hex_string() { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn felt_dec() { let macro_value = felt_dec!("1234567"); - let function_call_value = FieldElement::from_dec_str("1234567").unwrap(); + let function_call_value = Felt::from_dec_str("1234567").unwrap(); assert_eq!(macro_value, function_call_value); } @@ -55,7 +55,7 @@ fn felt_dec() { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn felt_hex() { let macro_value = felt_hex!("0x123456789abcdef"); - let function_call_value = FieldElement::from_hex_be("0x123456789abcdef").unwrap(); + let function_call_value = Felt::from_hex("0x123456789abcdef").unwrap(); assert_eq!(macro_value, function_call_value); } From 33581e3e2c85adfb2136b4747e14390b00d49d8b Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Sun, 16 Jun 2024 17:38:17 -0600 Subject: [PATCH 03/28] release: bump starknet to 0.11.0 (and deps) (#576) (#602) --- Cargo.lock | 20 ++++++++++---------- Cargo.toml | 16 ++++++++-------- README.md | 2 +- examples/starknet-wasm/Cargo.toml | 2 +- starknet-accounts/Cargo.toml | 10 +++++----- starknet-contract/Cargo.toml | 10 +++++----- starknet-core/Cargo.toml | 4 ++-- starknet-crypto-codegen/Cargo.toml | 4 ++-- starknet-crypto/Cargo.toml | 6 +++--- starknet-curve/Cargo.toml | 2 +- starknet-macros/Cargo.toml | 4 ++-- starknet-providers/Cargo.toml | 4 ++-- starknet-signers/Cargo.toml | 6 +++--- 13 files changed, 45 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0fc89dd6..2eff5706 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1534,7 +1534,7 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "starknet" -version = "0.10.0" +version = "0.11.0" dependencies = [ "serde_json", "starknet-accounts", @@ -1550,7 +1550,7 @@ dependencies = [ [[package]] name = "starknet-accounts" -version = "0.9.0" +version = "0.10.0" dependencies = [ "async-trait", "auto_impl", @@ -1567,7 +1567,7 @@ dependencies = [ [[package]] name = "starknet-contract" -version = "0.9.0" +version = "0.10.0" dependencies = [ "rand", "serde", @@ -1584,7 +1584,7 @@ dependencies = [ [[package]] name = "starknet-core" -version = "0.10.0" +version = "0.11.0" dependencies = [ "base64 0.21.0", "criterion", @@ -1605,7 +1605,7 @@ dependencies = [ [[package]] name = "starknet-crypto" -version = "0.6.2" +version = "0.7.0" dependencies = [ "criterion", "crypto-bigint", @@ -1628,7 +1628,7 @@ dependencies = [ [[package]] name = "starknet-crypto-codegen" -version = "0.3.3" +version = "0.4.0" dependencies = [ "starknet-curve", "starknet-types-core", @@ -1637,7 +1637,7 @@ dependencies = [ [[package]] name = "starknet-curve" -version = "0.4.2" +version = "0.5.0" dependencies = [ "starknet-types-core", ] @@ -1654,7 +1654,7 @@ dependencies = [ [[package]] name = "starknet-macros" -version = "0.1.7" +version = "0.2.0" dependencies = [ "starknet-core", "syn 2.0.63", @@ -1662,7 +1662,7 @@ dependencies = [ [[package]] name = "starknet-providers" -version = "0.10.0" +version = "0.11.0" dependencies = [ "async-trait", "auto_impl", @@ -1683,7 +1683,7 @@ dependencies = [ [[package]] name = "starknet-signers" -version = "0.8.0" +version = "0.9.0" dependencies = [ "async-trait", "auto_impl", diff --git a/Cargo.toml b/Cargo.toml index 00ada836..39dafc51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet" -version = "0.10.0" +version = "0.11.0" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" @@ -33,13 +33,13 @@ members = [ all-features = true [dependencies] -starknet-crypto = { version = "0.6.2", path = "./starknet-crypto" } -starknet-core = { version = "0.10.0", path = "./starknet-core", default-features = false } -starknet-providers = { version = "0.10.0", path = "./starknet-providers" } -starknet-contract = { version = "0.9.0", path = "./starknet-contract" } -starknet-signers = { version = "0.8.0", path = "./starknet-signers" } -starknet-accounts = { version = "0.9.0", path = "./starknet-accounts" } -starknet-macros = { version = "0.1.7", path = "./starknet-macros" } +starknet-crypto = { version = "0.7.0", path = "./starknet-crypto" } +starknet-core = { version = "0.11.0", path = "./starknet-core", default-features = false } +starknet-providers = { version = "0.11.0", path = "./starknet-providers" } +starknet-contract = { version = "0.10.0", path = "./starknet-contract" } +starknet-signers = { version = "0.9.0", path = "./starknet-signers" } +starknet-accounts = { version = "0.10.0", path = "./starknet-accounts" } +starknet-macros = { version = "0.2.0", path = "./starknet-macros" } [dev-dependencies] serde_json = "1.0.74" diff --git a/README.md b/README.md index ff782c89..dfa97ae4 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ To use the crate from [crates.io](https://crates.io/crates/starknet), add the fo ```toml [dependencies] -starknet = "0.9.0" +starknet = "0.11.0" ``` Note that the [crates.io version](https://crates.io/crates/starknet) might be outdated. You may want to use the library directly from GitHub for all the latest features and fixes: diff --git a/examples/starknet-wasm/Cargo.toml b/examples/starknet-wasm/Cargo.toml index d214878f..cf4f900c 100644 --- a/examples/starknet-wasm/Cargo.toml +++ b/examples/starknet-wasm/Cargo.toml @@ -19,6 +19,6 @@ crate-type = ["cdylib", "rlib"] default = ["console_error_panic_hook"] [dependencies] -starknet-crypto = { version = "0.6.2", path = "../../starknet-crypto" } +starknet-crypto = { version = "0.7.0", path = "../../starknet-crypto" } console_error_panic_hook = { version = "0.1.7", optional = true } wasm-bindgen = "0.2.84" diff --git a/starknet-accounts/Cargo.toml b/starknet-accounts/Cargo.toml index b7feb539..fdb256c6 100644 --- a/starknet-accounts/Cargo.toml +++ b/starknet-accounts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-accounts" -version = "0.9.0" +version = "0.10.0" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" @@ -14,10 +14,10 @@ keywords = ["ethereum", "starknet", "web3"] exclude = ["test-data/**"] [dependencies] -starknet-core = { version = "0.10.0", path = "../starknet-core" } -starknet-crypto = { version = "0.6.2", path = "../starknet-crypto" } -starknet-providers = { version = "0.10.0", path = "../starknet-providers" } -starknet-signers = { version = "0.8.0", path = "../starknet-signers" } +starknet-core = { version = "0.11.0", path = "../starknet-core" } +starknet-crypto = { version = "0.7.0", path = "../starknet-crypto" } +starknet-providers = { version = "0.11.0", path = "../starknet-providers" } +starknet-signers = { version = "0.9.0", path = "../starknet-signers" } async-trait = "0.1.68" auto_impl = "1.0.1" thiserror = "1.0.40" diff --git a/starknet-contract/Cargo.toml b/starknet-contract/Cargo.toml index 209bb59e..992069df 100644 --- a/starknet-contract/Cargo.toml +++ b/starknet-contract/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-contract" -version = "0.9.0" +version = "0.10.0" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" @@ -14,9 +14,9 @@ keywords = ["ethereum", "starknet", "web3"] exclude = ["test-data/**"] [dependencies] -starknet-core = { version = "0.10.0", path = "../starknet-core" } -starknet-providers = { version = "0.10.0", path = "../starknet-providers" } -starknet-accounts = { version = "0.9.0", path = "../starknet-accounts" } +starknet-core = { version = "0.11.0", path = "../starknet-core" } +starknet-providers = { version = "0.11.0", path = "../starknet-providers" } +starknet-accounts = { version = "0.10.0", path = "../starknet-accounts" } serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0.96" serde_with = "2.3.2" @@ -24,6 +24,6 @@ thiserror = "1.0.40" [dev-dependencies] rand = { version = "0.8.5", features=["std_rng"] } -starknet-signers = { version = "0.8.0", path = "../starknet-signers" } +starknet-signers = { version = "0.9.0", path = "../starknet-signers" } tokio = { version = "1.27.0", features = ["full"] } url = "2.3.1" diff --git a/starknet-core/Cargo.toml b/starknet-core/Cargo.toml index 74164b66..f3f7862d 100644 --- a/starknet-core/Cargo.toml +++ b/starknet-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-core" -version = "0.10.0" +version = "0.11.0" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" @@ -17,7 +17,7 @@ exclude = ["test-data/**"] all-features = true [dependencies] -starknet-crypto = { version = "0.6.2", path = "../starknet-crypto", default-features = false, features = ["alloc"] } +starknet-crypto = { version = "0.7.0", path = "../starknet-crypto", default-features = false, features = ["alloc"] } base64 = { version = "0.21.0", default-features = false, features = ["alloc"] } crypto-bigint = { version = "0.5.1", default-features = false } flate2 = { version = "1.0.25", optional = true } diff --git a/starknet-crypto-codegen/Cargo.toml b/starknet-crypto-codegen/Cargo.toml index a0065269..e8959610 100644 --- a/starknet-crypto-codegen/Cargo.toml +++ b/starknet-crypto-codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-crypto-codegen" -version = "0.3.3" +version = "0.4.0" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" @@ -16,6 +16,6 @@ keywords = ["ethereum", "starknet", "web3", "no_std"] proc-macro = true [dependencies] -starknet-curve = { version = "0.4.2", path = "../starknet-curve" } +starknet-curve = { version = "0.5.0", path = "../starknet-curve" } syn = "2.0.55" starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve"] } diff --git a/starknet-crypto/Cargo.toml b/starknet-crypto/Cargo.toml index 2a9e285d..c81cd10b 100644 --- a/starknet-crypto/Cargo.toml +++ b/starknet-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-crypto" -version = "0.6.2" +version = "0.7.0" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" @@ -14,8 +14,8 @@ keywords = ["ethereum", "starknet", "web3", "no_std"] exclude = ["test-data/**"] [dependencies] -starknet-crypto-codegen = { version = "0.3.3", path = "../starknet-crypto-codegen" } -starknet-curve = { version = "0.4.2", path = "../starknet-curve" } +starknet-crypto-codegen = { version = "0.4.0", path = "../starknet-crypto-codegen" } +starknet-curve = { version = "0.5.0", path = "../starknet-curve" } crypto-bigint = { version = "0.5.1", default-features = false, features = ["generic-array", "zeroize"] } hmac = { version = "0.12.1", default-features = false } num-bigint = { version = "0.4.3", default-features = false } diff --git a/starknet-curve/Cargo.toml b/starknet-curve/Cargo.toml index ddefc7d4..83c291ba 100644 --- a/starknet-curve/Cargo.toml +++ b/starknet-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-curve" -version = "0.4.2" +version = "0.5.0" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" diff --git a/starknet-macros/Cargo.toml b/starknet-macros/Cargo.toml index 774f70ac..78b1a782 100644 --- a/starknet-macros/Cargo.toml +++ b/starknet-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-macros" -version = "0.1.7" +version = "0.2.0" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" @@ -16,7 +16,7 @@ keywords = ["ethereum", "starknet", "web3"] proc-macro = true [dependencies] -starknet-core = { version = "0.10.0", path = "../starknet-core" } +starknet-core = { version = "0.11.0", path = "../starknet-core" } syn = "2.0.15" [features] diff --git a/starknet-providers/Cargo.toml b/starknet-providers/Cargo.toml index fd649247..bfcf2275 100644 --- a/starknet-providers/Cargo.toml +++ b/starknet-providers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-providers" -version = "0.10.0" +version = "0.11.0" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" @@ -14,7 +14,7 @@ keywords = ["ethereum", "starknet", "web3"] exclude = ["test-data/**"] [dependencies] -starknet-core = { version = "0.10.0", path = "../starknet-core" } +starknet-core = { version = "0.11.0", path = "../starknet-core" } async-trait = "0.1.68" auto_impl = "1.0.1" ethereum-types = "0.14.1" diff --git a/starknet-signers/Cargo.toml b/starknet-signers/Cargo.toml index aefea7a2..98e27026 100644 --- a/starknet-signers/Cargo.toml +++ b/starknet-signers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-signers" -version = "0.8.0" +version = "0.9.0" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" @@ -13,8 +13,8 @@ Starknet signer implementations keywords = ["ethereum", "starknet", "web3"] [dependencies] -starknet-core = { version = "0.10.0", path = "../starknet-core" } -starknet-crypto = { version = "0.6.2", path = "../starknet-crypto" } +starknet-core = { version = "0.11.0", path = "../starknet-core" } +starknet-crypto = { version = "0.7.0", path = "../starknet-crypto" } async-trait = "0.1.68" auto_impl = "1.0.1" thiserror = "1.0.40" From bdb2663489bff43c8f6b9747deaecb2b4d0532eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Delabrouille?= <34384633+tdelabro@users.noreply.github.com> Date: Mon, 17 Jun 2024 17:44:26 +0200 Subject: [PATCH 04/28] feat: make hasher accept iterators rather than arrays (#594) * feat: poseidon_hash_may takes an iterator * feat: compute_hash_on_elements takes ExactSizeIterator * fix bug --- starknet-core/src/crypto.rs | 13 +++++++++---- starknet-crypto/src/poseidon_hash.rs | 29 ++++++++++++++++++---------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/starknet-core/src/crypto.rs b/starknet-core/src/crypto.rs index 634faab9..1977f4da 100644 --- a/starknet-core/src/crypto.rs +++ b/starknet-core/src/crypto.rs @@ -46,14 +46,19 @@ mod errors { } pub use errors::{EcdsaSignError, EcdsaVerifyError}; -pub fn compute_hash_on_elements(data: &[Felt]) -> Felt { +pub fn compute_hash_on_elements<'a, ESI, II>(data: II) -> Felt +where + ESI: ExactSizeIterator, + II: IntoIterator, +{ let mut current_hash = Felt::ZERO; + let data_iter = data.into_iter(); + let data_len = Felt::from(data_iter.len()); - for item in data.iter() { - current_hash = pedersen_hash(¤t_hash, item); + for elem in data_iter { + current_hash = pedersen_hash(¤t_hash, elem); } - let data_len = Felt::from(data.len()); pedersen_hash(¤t_hash, &data_len) } diff --git a/starknet-crypto/src/poseidon_hash.rs b/starknet-crypto/src/poseidon_hash.rs index c8b15bd9..4f3db345 100644 --- a/starknet-crypto/src/poseidon_hash.rs +++ b/starknet-crypto/src/poseidon_hash.rs @@ -72,20 +72,29 @@ pub fn poseidon_hash_single(x: Felt) -> Felt { /// Computes the Starknet Poseidon hash of an arbitrary number of [Felt]s. /// /// Using this function is the same as using [PoseidonHasher]. -pub fn poseidon_hash_many(msgs: &[Felt]) -> Felt { +pub fn poseidon_hash_many<'a, I: IntoIterator>(msgs: I) -> Felt { let mut state = [Felt::ZERO, Felt::ZERO, Felt::ZERO]; - let mut iter = msgs.chunks_exact(2); + let mut iter = msgs.into_iter(); + + loop { + match iter.next() { + Some(v) => state[0] += *v, + None => { + state[0] += Felt::ONE; + break; + } + } + + match iter.next() { + Some(v) => state[1] += *v, + None => { + state[1] += Felt::ONE; + break; + } + } - for msg in iter.by_ref() { - state[0] += msg[0]; - state[1] += msg[1]; poseidon_permute_comp(&mut state); } - let r = iter.remainder(); - if r.len() == 1 { - state[0] += r[0]; - } - state[r.len()] += Felt::ONE; poseidon_permute_comp(&mut state); state[0] From 4dbc1692d4f295de803484181e07803201528922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Delabrouille?= <34384633+tdelabro@users.noreply.github.com> Date: Mon, 17 Jun 2024 17:45:01 +0200 Subject: [PATCH 05/28] feat: compress LegacyProgram.debug_info as None (#599) chore: remove pathfinder bug induced workaround --- starknet-core/src/types/contract/legacy.rs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/starknet-core/src/types/contract/legacy.rs b/starknet-core/src/types/contract/legacy.rs index 56cab605..83294a82 100644 --- a/starknet-core/src/types/contract/legacy.rs +++ b/starknet-core/src/types/contract/legacy.rs @@ -502,9 +502,7 @@ impl LegacyProgram { compiler_version: &'a Option, #[serde_as(as = "Vec")] data: &'a Vec, - // Needed due to pathfinder bug: - // https://github.com/eqlabs/pathfinder/issues/1371 - debug_info: EmptyDebugInfo, + debug_info: Option<()>, hints: &'a BTreeMap>, identifiers: &'a BTreeMap, main_scope: &'a String, @@ -512,24 +510,12 @@ impl LegacyProgram { reference_manager: &'a LegacyReferenceManager, } - #[derive(Serialize)] - pub struct EmptyDebugInfo { - file_contents: Unit, - instruction_locations: Unit, - } - - #[derive(Serialize)] - pub struct Unit {} - let program_json = serde_json::to_string(&ProgramWithoutDebugInfo { attributes: &self.attributes, builtins: &self.builtins, compiler_version: &self.compiler_version, data: &self.data, - debug_info: EmptyDebugInfo { - file_contents: Unit {}, - instruction_locations: Unit {}, - }, + debug_info: None, hints: &self.hints, identifiers: &self.identifiers, main_scope: &self.main_scope, From 36ec1d681fc2917ca4857d14ce262ed7c2b60a7a Mon Sep 17 00:00:00 2001 From: Charpa <102919164+jbcaron@users.noreply.github.com> Date: Tue, 18 Jun 2024 18:14:25 +0400 Subject: [PATCH 06/28] fix: serialization ReceiptBlock (#604) --- starknet-core/src/types/receipt_block.rs | 37 +++++++++--------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/starknet-core/src/types/receipt_block.rs b/starknet-core/src/types/receipt_block.rs index 4287e2e6..5c73d03d 100644 --- a/starknet-core/src/types/receipt_block.rs +++ b/starknet-core/src/types/receipt_block.rs @@ -1,6 +1,7 @@ use serde::{Deserialize, Serialize}; use serde_with::serde_as; +use crate::serde::unsigned_field_element::UfeHex; use starknet_types_core::felt::Felt; /// A more idiomatic way to access `execution_status` and `revert_reason`. @@ -48,21 +49,22 @@ impl ReceiptBlock { } } +#[serde_as] +#[derive(Serialize, Deserialize)] +#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] +struct Raw { + #[serde(skip_serializing_if = "Option::is_none")] + #[serde_as(as = "Option")] + block_hash: Option, + #[serde(skip_serializing_if = "Option::is_none")] + block_number: Option, +} + impl Serialize for ReceiptBlock { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { - #[derive(Serialize)] - #[serde_as] - struct Raw<'a> { - #[serde_as(as = "Option")] - #[serde(skip_serializing_if = "Option::is_none")] - block_hash: Option<&'a Felt>, - #[serde(skip_serializing_if = "Option::is_none")] - block_number: Option<&'a u64>, - } - let raw = match self { Self::Pending => Raw { block_hash: None, @@ -72,8 +74,8 @@ impl Serialize for ReceiptBlock { block_hash, block_number, } => Raw { - block_hash: Some(block_hash), - block_number: Some(block_number), + block_hash: Some(*block_hash), + block_number: Some(*block_number), }, }; @@ -86,17 +88,6 @@ impl<'de> Deserialize<'de> for ReceiptBlock { where D: serde::Deserializer<'de>, { - #[derive(Deserialize)] - #[serde_as] - #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] - struct Raw { - #[serde_as(as = "Option")] - #[serde(skip_serializing_if = "Option::is_none")] - block_hash: Option, - #[serde(skip_serializing_if = "Option::is_none")] - block_number: Option, - } - let raw = Raw::deserialize(deserializer)?; match (raw.block_hash, raw.block_number) { From 1a28e955a28712c44a5ecca7d191df6e028cf2f2 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Wed, 19 Jun 2024 17:53:05 -0600 Subject: [PATCH 07/28] feat: ledger signer support (#605) --- Cargo.lock | 641 ++++++++++++++++++++++--- Cargo.toml | 3 + README.md | 9 +- examples/deploy_account_with_ledger.rs | 59 +++ examples/deploy_argent_account.rs | 2 +- examples/ledger_public_key.rs | 18 + starknet-signers/Cargo.toml | 9 + starknet-signers/src/ledger.rs | 244 ++++++++++ starknet-signers/src/lib.rs | 5 + 9 files changed, 924 insertions(+), 66 deletions(-) create mode 100644 examples/deploy_account_with_ledger.rs create mode 100644 examples/ledger_public_key.rs create mode 100644 starknet-signers/src/ledger.rs diff --git a/Cargo.lock b/Cargo.lock index 2eff5706..630c100c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -42,9 +51,9 @@ checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", @@ -80,6 +89,27 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide 0.7.4", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" @@ -92,12 +122,30 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + [[package]] name = "bitvec" version = "1.0.1" @@ -119,6 +167,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "sha2", + "tinyvec", +] + [[package]] name = "bumpalo" version = "3.12.1" @@ -133,9 +191,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -151,9 +209,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "cfg-if" @@ -217,7 +275,7 @@ version = "3.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ - "bitflags", + "bitflags 1.3.2", "clap_lex", "indexmap", "textwrap", @@ -242,6 +300,63 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "coins-bip32" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66c43ff7fd9ff522219058808a259e61423335767b1071d5b346de60d9219657" +dependencies = [ + "bs58", + "coins-core", + "digest", + "hmac", + "k256", + "serde", + "sha2", + "thiserror", +] + +[[package]] +name = "coins-core" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3aeeec621f4daec552e9d28befd58020a78cfc364827d06a753e8bc13c6c4b" +dependencies = [ + "base64 0.21.0", + "bech32", + "bs58", + "const-hex", + "digest", + "generic-array", + "ripemd", + "serde", + "sha2", + "sha3", + "thiserror", +] + +[[package]] +name = "coins-ledger" +version = "0.11.1" +source = "git+https://github.com/xJonathanLEI/coins?rev=0e3be5db0b18b683433de6b666556b99c726e785#0e3be5db0b18b683433de6b666556b99c726e785" +dependencies = [ + "async-trait", + "byteorder", + "cfg-if", + "const-hex", + "getrandom", + "hidapi-rusb", + "js-sys", + "log", + "nix", + "once_cell", + "thiserror", + "tokio", + "tracing", + "wasm-bindgen", + "wasm-bindgen-futures", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -252,6 +367,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-hex" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -323,6 +457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7" dependencies = [ "generic-array", + "rand_core", "subtle", "zeroize", ] @@ -425,23 +560,67 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + [[package]] name = "either" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "encoding_rs" version = "0.8.32" @@ -500,6 +679,16 @@ dependencies = [ "uint", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "fixed-hash" version = "0.8.0" @@ -519,7 +708,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.6.2", ] [[package]] @@ -590,6 +779,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -605,6 +795,23 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + [[package]] name = "h2" version = "0.3.18" @@ -666,6 +873,18 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +[[package]] +name = "hidapi-rusb" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efdc2ec354929a6e8f3c6b6923a4d97427ec2f764cfee8cd4bfe890946cdf08b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "rusb", +] + [[package]] name = "hmac" version = "0.12.1" @@ -726,7 +945,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -867,18 +1086,32 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -897,9 +1130,27 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.142" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libm" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libusb1-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da050ade7ac4ff1ba5379af847a10a10a8e284181e060105bf8d86960ce9ce0f" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] [[package]] name = "link-cplusplus" @@ -932,6 +1183,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.17" @@ -947,16 +1207,37 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + [[package]] name = "mio" -version = "0.8.6" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", - "log", "wasi", - "windows-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", + "pin-utils", ] [[package]] @@ -987,6 +1268,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -999,11 +1281,20 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" -version = "1.17.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" @@ -1063,7 +1354,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1083,9 +1374,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1093,6 +1384,22 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1155,6 +1462,22 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +dependencies = [ + "bitflags 2.5.0", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax 0.8.4", + "unarray", +] + [[package]] name = "quote" version = "1.0.36" @@ -1200,13 +1523,22 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + [[package]] name = "redox_syscall" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1215,7 +1547,7 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ - "regex-syntax", + "regex-syntax 0.7.1", ] [[package]] @@ -1224,6 +1556,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + [[package]] name = "reqwest" version = "0.11.16" @@ -1288,6 +1626,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest", +] + [[package]] name = "rlp" version = "0.5.2" @@ -1298,6 +1645,22 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "rusb" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9f9ff05b63a786553a4c02943b74b34a988448671001e9a27e2f0565cc05a4" +dependencies = [ + "libc", + "libusb1-sys", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -1389,20 +1752,34 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "serde" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -1473,9 +1850,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -1484,9 +1861,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest", "keccak", @@ -1501,6 +1878,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "slab" version = "0.4.8" @@ -1526,12 +1913,32 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "starknet" version = "0.11.0" @@ -1687,6 +2094,8 @@ version = "0.9.0" dependencies = [ "async-trait", "auto_impl", + "coins-bip32", + "coins-ledger", "crypto-bigint", "eth-keystore", "getrandom", @@ -1782,18 +2191,18 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", @@ -1863,11 +2272,11 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.27.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", "mio", @@ -1875,16 +2284,16 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.7", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.0.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", @@ -1947,9 +2356,21 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.63", +] + [[package]] name = "tracing-core" version = "0.1.30" @@ -1983,6 +2404,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -2037,6 +2464,12 @@ dependencies = [ "serde", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -2071,9 +2504,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2081,24 +2514,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.63", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -2108,9 +2541,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2118,22 +2551,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.63", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-bindgen-test" @@ -2237,6 +2670,24 @@ dependencies = [ "windows-targets 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -2267,6 +2718,22 @@ dependencies = [ "windows_x86_64_msvc 0.48.0", ] +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -2279,6 +2746,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -2291,6 +2764,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -2303,6 +2782,18 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -2315,6 +2806,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -2327,6 +2824,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -2339,6 +2842,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -2351,6 +2860,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + [[package]] name = "winnow" version = "0.4.1" @@ -2380,6 +2895,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/Cargo.toml b/Cargo.toml index 39dafc51..c6307866 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,10 +43,13 @@ starknet-macros = { version = "0.2.0", path = "./starknet-macros" } [dev-dependencies] serde_json = "1.0.74" +starknet-signers = { version = "0.9.0", path = "./starknet-signers", features = ["ledger"] } tokio = { version = "1.15.0", features = ["full"] } url = "2.2.2" [features] +default = [] +ledger = ["starknet-signers/ledger"] no_unknown_fields = [ "starknet-core/no_unknown_fields", "starknet-providers/no_unknown_fields", diff --git a/README.md b/README.md index dfa97ae4..d5639993 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ starknet = { git = "https://github.com/xJonathanLEI/starknet-rs" } - [x] Smart contract deployment - [x] Signer for using [IAccount](https://github.com/OpenZeppelin/cairo-contracts/blob/main/src/openzeppelin/account/IAccount.cairo) account contracts - [ ] Strongly-typed smart contract binding code generation from ABI +- [x] Ledger hardware wallet support ## Crates @@ -95,9 +96,13 @@ Examples can be found in the [examples folder](./examples): 8. [Deploy an Argent X account to a pre-funded address](./examples/deploy_argent_account.rs) -9. [Parsing a JSON-RPC request on the server side](./examples/parse_jsonrpc_request.rs) +9. [Inspect public key with Ledger](./examples/ledger_public_key.rs) -10. [Inspecting a erased provider-specific error type](./examples/downcast_provider_error.rs) +10. [Deploy an OpenZeppelin account with Ledger](./examples/deploy_account_with_ledger.rs) + +11. [Parsing a JSON-RPC request on the server side](./examples/parse_jsonrpc_request.rs) + +12. [Inspecting a erased provider-specific error type](./examples/downcast_provider_error.rs) ## License diff --git a/examples/deploy_account_with_ledger.rs b/examples/deploy_account_with_ledger.rs new file mode 100644 index 00000000..0f25ad2b --- /dev/null +++ b/examples/deploy_account_with_ledger.rs @@ -0,0 +1,59 @@ +use starknet::{ + accounts::AccountFactory, + core::chain_id, + macros::felt, + providers::{ + jsonrpc::{HttpTransport, JsonRpcClient}, + Url, + }, + signers::LedgerSigner, +}; +use starknet_accounts::OpenZeppelinAccountFactory; + +#[tokio::main] +async fn main() { + // OpenZeppelin account contract v0.13.0 compiled with cairo v2.6.3 + let class_hash = felt!("0x00e2eb8f5672af4e6a4e8a8f1b44989685e668489b0a25437733756c5a34a1d6"); + + // Anything you like here as salt + let salt = felt!("12345678"); + + let provider = JsonRpcClient::new(HttpTransport::new( + Url::parse("https://starknet-sepolia.public.blastapi.io/rpc/v0_7").unwrap(), + )); + + let signer = LedgerSigner::new( + "m/2645'/1195502025'/1470455285'/0'/0'/0" + .try_into() + .expect("unable to parse path"), + ) + .await + .expect("failed to initialize Starknet Ledger app"); + + let factory = OpenZeppelinAccountFactory::new(class_hash, chain_id::SEPOLIA, signer, provider) + .await + .unwrap(); + + let deployment = factory.deploy_v1(salt); + + let est_fee = deployment.estimate_fee().await.unwrap(); + + // In an actual application you might want to add a buffer to the amount + println!( + "Fund at least {} wei to {:#064x}", + est_fee.overall_fee, + deployment.address() + ); + println!("Press ENTER after account is funded to continue deployment..."); + std::io::stdin().read_line(&mut String::new()).unwrap(); + + let result = deployment.send().await; + match result { + Ok(tx) => { + println!("Transaction hash: {:#064x}", tx.transaction_hash); + } + Err(err) => { + eprintln!("Error: {err}"); + } + } +} diff --git a/examples/deploy_argent_account.rs b/examples/deploy_argent_account.rs index bf4ffae4..8eff33cc 100644 --- a/examples/deploy_argent_account.rs +++ b/examples/deploy_argent_account.rs @@ -46,7 +46,7 @@ async fn main() { let result = deployment.send().await; match result { Ok(tx) => { - dbg!(tx); + println!("Transaction hash: {:#064x}", tx.transaction_hash); } Err(err) => { eprintln!("Error: {err}"); diff --git a/examples/ledger_public_key.rs b/examples/ledger_public_key.rs new file mode 100644 index 00000000..36c5636a --- /dev/null +++ b/examples/ledger_public_key.rs @@ -0,0 +1,18 @@ +use starknet::signers::{LedgerSigner, Signer}; + +#[tokio::main] +async fn main() { + let path = "m/2645'/1195502025'/1470455285'/0'/0'/0"; + + let ledger = LedgerSigner::new(path.try_into().expect("unable to parse path")) + .await + .expect("failed to initialize Starknet Ledger app"); + + let public_key = ledger + .get_public_key() + .await + .expect("failed to get public key"); + + println!("Path: {}", path); + println!("Public key: {:#064x}", public_key.scalar()); +} diff --git a/starknet-signers/Cargo.toml b/starknet-signers/Cargo.toml index 98e27026..fd331ae2 100644 --- a/starknet-signers/Cargo.toml +++ b/starknet-signers/Cargo.toml @@ -20,6 +20,10 @@ auto_impl = "1.0.1" thiserror = "1.0.40" crypto-bigint = { version = "0.5.1", default-features = false } rand = { version = "0.8.5", features = ["std_rng"] } +coins-bip32 = { version = "0.11.1", optional = true } + +# Using a fork until https://github.com/summa-tx/coins/issues/137 is fixed +coins-ledger = { git = "https://github.com/xJonathanLEI/coins", rev = "0e3be5db0b18b683433de6b666556b99c726e785", default-features = false, optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] eth-keystore = { version = "0.5.0", default-features = false } @@ -29,3 +33,8 @@ getrandom = { version = "0.2.9", features = ["js"] } [target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen-test = "0.3.34" + +[features] +default = [] + +ledger = ["coins-bip32", "coins-ledger"] diff --git a/starknet-signers/src/ledger.rs b/starknet-signers/src/ledger.rs new file mode 100644 index 00000000..140d787c --- /dev/null +++ b/starknet-signers/src/ledger.rs @@ -0,0 +1,244 @@ +use async_trait::async_trait; +use coins_ledger::{ + common::{APDUData, APDUResponseCodes}, + transports::LedgerAsync, + APDUAnswer, APDUCommand, Ledger, +}; +use crypto_bigint::{ArrayEncoding, U256}; +use starknet_core::{crypto::Signature, types::Felt}; + +use crate::{Signer, VerifyingKey}; + +pub use coins_bip32::path::DerivationPath; + +/// The Ledger application identifier for app-starknet. +const CLA_STARKNET: u8 = 0x5a; + +/// BIP-32 encoding of `2645'` +const EIP_2645_PURPOSE: u32 = 0x80000a55; + +const EIP_2645_PATH_LENGTH: usize = 6; + +const PUBLIC_KEY_SIZE: usize = 65; +const SIGNATURE_SIZE: usize = 65; + +#[derive(Debug)] +pub struct LedgerSigner { + transport: Ledger, + derivation_path: DerivationPath, +} + +#[derive(Debug, thiserror::Error)] +pub enum LedgerError { + #[error("derivation path is empty, not prefixed with m/2645', or is not 6-level long")] + InvalidDerivationPath, + #[error(transparent)] + TransportError(coins_ledger::LedgerError), + #[error("unknown response code from Ledger: {0}")] + UnknownResponseCode(u16), + #[error("failed Ledger request: {0}")] + UnsuccessfulRequest(APDUResponseCodes), + #[error("unexpected response length - expected: {expected}; actual: {actual}")] + UnexpectedResponseLength { expected: usize, actual: usize }, +} + +/// The `GetPubKey` Ledger command. +struct GetPubKeyCommand { + display: bool, + path: DerivationPath, +} + +/// Part 1 of the `SignHash` command for setting path. +struct SignHashCommand1 { + path: DerivationPath, +} + +/// Part 2 of the `SignHash` command for setting hash. +struct SignHashCommand2 { + hash: [u8; 32], +} + +impl LedgerSigner { + /// Initializes the Starknet Ledger app. Attempts to find and connect to a Ledger device. The + /// device must be unlocked and have the Starknet app open. + /// + /// The `derivation_path` passed in _must_ follow EIP-2645, i.e. having `2645'` as its "purpose" + /// level as per BIP-44, as the Ledger app does not allow other paths to be used. + /// + /// The path _must_ also be 6-level in length. An example path for Starknet would be: + /// + /// `m/2645'/1195502025'/1470455285'/0'/0'/0` + /// + /// where: + /// + /// - `2645'` is the EIP-2645 prefix + /// - `1195502025'`, decimal for `0x4741e9c9`, is the 31 lowest bits for `sha256(starknet)` + /// - `1470455285'`, decimal for `0x57a55df5`, is the 31 lowest bits for `sha256(starkli)` + /// + /// Currently, the Ledger app only enforces the length and the first level of the path. + pub async fn new(derivation_path: DerivationPath) -> Result { + let transport = Ledger::init().await?; + + if !matches!(derivation_path.iter().next(), Some(&EIP_2645_PURPOSE)) + || derivation_path.len() != EIP_2645_PATH_LENGTH + { + return Err(LedgerError::InvalidDerivationPath); + } + + Ok(Self { + transport, + derivation_path, + }) + } +} + +#[async_trait] +impl Signer for LedgerSigner { + type GetPublicKeyError = LedgerError; + type SignError = LedgerError; + + async fn get_public_key(&self) -> Result { + let response = self + .transport + .exchange( + &GetPubKeyCommand { + display: false, + path: self.derivation_path.clone(), + } + .into(), + ) + .await?; + + let data = get_apdu_data(&response)?; + if data.len() != PUBLIC_KEY_SIZE { + return Err(LedgerError::UnexpectedResponseLength { + expected: PUBLIC_KEY_SIZE, + actual: data.len(), + }); + } + + // Unwrapping here is safe as length is fixed + let pubkey_x = Felt::from_bytes_be(&data[1..33].try_into().unwrap()); + + Ok(VerifyingKey::from_scalar(pubkey_x)) + } + + async fn sign_hash(&self, hash: &Felt) -> Result { + get_apdu_data( + &self + .transport + .exchange( + &SignHashCommand1 { + path: self.derivation_path.clone(), + } + .into(), + ) + .await?, + )?; + + let response = self + .transport + .exchange( + &SignHashCommand2 { + hash: hash.to_bytes_be(), + } + .into(), + ) + .await?; + + let data = get_apdu_data(&response)?; + + if data.len() != SIGNATURE_SIZE + 1 || data[0] != SIGNATURE_SIZE as u8 { + return Err(LedgerError::UnexpectedResponseLength { + expected: SIGNATURE_SIZE, + actual: data.len(), + }); + } + + // Unwrapping here is safe as length is fixed + let r = Felt::from_bytes_be(&data[1..33].try_into().unwrap()); + let s = Felt::from_bytes_be(&data[33..65].try_into().unwrap()); + + let signature = Signature { r, s }; + + Ok(signature) + } +} + +impl From for LedgerError { + fn from(value: coins_ledger::LedgerError) -> Self { + Self::TransportError(value) + } +} + +impl From for APDUCommand { + fn from(value: GetPubKeyCommand) -> Self { + let path = value + .path + .iter() + .flat_map(|level| level.to_be_bytes()) + .collect::>(); + + Self { + cla: CLA_STARKNET, + ins: 0x01, + p1: if value.display { 0x01 } else { 0x00 }, + p2: 0x00, + data: APDUData::new(&path), + response_len: None, + } + } +} + +impl From for APDUCommand { + fn from(value: SignHashCommand1) -> Self { + let path = value + .path + .iter() + .flat_map(|level| level.to_be_bytes()) + .collect::>(); + + Self { + cla: CLA_STARKNET, + ins: 0x02, + p1: 0x00, + p2: 0x00, + data: APDUData::new(&path), + response_len: None, + } + } +} + +impl From for APDUCommand { + fn from(value: SignHashCommand2) -> Self { + // For some reasons, the Ledger app expects the input to be left shifted by 4 bits... + let shifted_bytes: [u8; 32] = (U256::from_be_slice(&value.hash) << 4) + .to_be_byte_array() + .into(); + + Self { + cla: CLA_STARKNET, + ins: 0x02, + p1: 0x01, + p2: 0x00, + data: APDUData::new(&shifted_bytes), + response_len: None, + } + } +} + +fn get_apdu_data(answer: &APDUAnswer) -> Result<&[u8], LedgerError> { + let ret_code = answer.retcode(); + + match TryInto::::try_into(ret_code) { + Ok(status) => { + if status.is_success() { + // Unwrapping here as we've already checked success + Ok(answer.data().unwrap()) + } else { + Err(LedgerError::UnsuccessfulRequest(status)) + } + } + Err(_) => Err(LedgerError::UnknownResponseCode(ret_code)), + } +} diff --git a/starknet-signers/src/lib.rs b/starknet-signers/src/lib.rs index 241dab3d..50903fab 100644 --- a/starknet-signers/src/lib.rs +++ b/starknet-signers/src/lib.rs @@ -10,5 +10,10 @@ pub use signer::Signer; pub mod local_wallet; pub use local_wallet::LocalWallet; +#[cfg(feature = "ledger")] +pub mod ledger; +#[cfg(feature = "ledger")] +pub use ledger::{DerivationPath, LedgerError, LedgerSigner}; + #[derive(Debug, thiserror::Error)] pub enum Infallible {} From c6c2714a452b73f0fba69d5a4cd8b5d2ce54c8cf Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Thu, 20 Jun 2024 01:55:11 +0200 Subject: [PATCH 08/28] feat: add `is_` utils to `TransactionStatus` enums (#606) --- starknet-core/src/types/mod.rs | 27 ++++++++++++++ .../src/sequencer/models/conversions.rs | 2 +- .../src/sequencer/models/transaction.rs | 8 ++-- .../sequencer/models/transaction_receipt.rs | 37 +++++++++++++++++++ 4 files changed, 69 insertions(+), 5 deletions(-) diff --git a/starknet-core/src/types/mod.rs b/starknet-core/src/types/mod.rs index d46535bc..e5494a82 100644 --- a/starknet-core/src/types/mod.rs +++ b/starknet-core/src/types/mod.rs @@ -174,14 +174,41 @@ pub enum ContractClass { Legacy(CompressedLegacyContractClass), } +/// Represents the status of a transaction. #[derive(Debug, Clone, PartialEq, Eq)] pub enum TransactionStatus { + /// Transaction received and awaiting processing. Received, + /// Transaction rejected due to validation or other reasons. Rejected, + /// Transaction accepted on Layer 2 with a specific execution status. AcceptedOnL2(TransactionExecutionStatus), + /// Transaction accepted on Layer 1 with a specific execution status. AcceptedOnL1(TransactionExecutionStatus), } +impl TransactionStatus { + /// Returns `true` if the transaction status is `Received`. + pub const fn is_received(&self) -> bool { + matches!(self, Self::Received) + } + + /// Returns `true` if the transaction status is `Rejected`. + pub const fn is_rejected(&self) -> bool { + matches!(self, Self::Rejected) + } + + /// Returns `true` if the transaction status is `AcceptedOnL2`. + pub const fn is_accepted_on_l2(&self) -> bool { + matches!(self, Self::AcceptedOnL2(_)) + } + + /// Returns `true` if the transaction status is `AcceptedOnL1`. + pub const fn is_accepted_on_l1(&self) -> bool { + matches!(self, Self::AcceptedOnL1(_)) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Deserialize)] #[serde(tag = "type")] pub enum Transaction { diff --git a/starknet-providers/src/sequencer/models/conversions.rs b/starknet-providers/src/sequencer/models/conversions.rs index c1c0d618..8e2c6efe 100644 --- a/starknet-providers/src/sequencer/models/conversions.rs +++ b/starknet-providers/src/sequencer/models/conversions.rs @@ -902,7 +902,7 @@ impl TryFrom for core::TransactionStatus { type Error = ConversionError; fn try_from(value: TransactionStatusInfo) -> Result { - if let TransactionStatus::Rejected = value.status { + if value.status.is_rejected() { return Ok(Self::Rejected); } diff --git a/starknet-providers/src/sequencer/models/transaction.rs b/starknet-providers/src/sequencer/models/transaction.rs index db625f16..388ace7d 100644 --- a/starknet-providers/src/sequencer/models/transaction.rs +++ b/starknet-providers/src/sequencer/models/transaction.rs @@ -344,7 +344,7 @@ mod tests { let tx: TransactionInfo = serde_json::from_str(raw).unwrap(); assert_eq!(tx.block_number, None); - assert_eq!(tx.status, TransactionStatus::NotReceived); + assert!(tx.status.is_not_received()); } #[test] @@ -459,7 +459,7 @@ mod tests { let tx: TransactionStatusInfo = serde_json::from_str(raw).unwrap(); - assert_eq!(tx.status, TransactionStatus::AcceptedOnL1); + assert!(tx.status.is_accepted_on_l1()); assert_eq!( tx.block_hash, Some( @@ -478,7 +478,7 @@ mod tests { let tx: TransactionStatusInfo = serde_json::from_str(raw).unwrap(); - assert_eq!(tx.status, TransactionStatus::NotReceived); + assert!(tx.status.is_not_received()); assert!(tx.block_hash.is_none()); } @@ -492,7 +492,7 @@ mod tests { let tx: TransactionStatusInfo = serde_json::from_str(raw).unwrap(); - assert_eq!(tx.status, TransactionStatus::Rejected); + assert!(tx.status.is_rejected()); assert!(tx.block_hash.is_none()); assert!(tx.transaction_failure_reason.is_some()); } diff --git a/starknet-providers/src/sequencer/models/transaction_receipt.rs b/starknet-providers/src/sequencer/models/transaction_receipt.rs index fdcaf221..97f6e864 100644 --- a/starknet-providers/src/sequencer/models/transaction_receipt.rs +++ b/starknet-providers/src/sequencer/models/transaction_receipt.rs @@ -50,6 +50,43 @@ pub enum TransactionStatus { AcceptedOnL1, } +impl TransactionStatus { + /// Returns `true` if the transaction status is `NotReceived`. + pub const fn is_not_received(&self) -> bool { + matches!(self, Self::NotReceived) + } + + /// Returns `true` if the transaction status is `Received`. + pub const fn is_received(&self) -> bool { + matches!(self, Self::Received) + } + + /// Returns `true` if the transaction status is `Pending`. + pub const fn is_pending(&self) -> bool { + matches!(self, Self::Pending) + } + + /// Returns `true` if the transaction status is `Rejected`. + pub const fn is_rejected(&self) -> bool { + matches!(self, Self::Rejected) + } + + /// Returns `true` if the transaction status is `Reverted`. + pub const fn is_reverted(&self) -> bool { + matches!(self, Self::Reverted) + } + + /// Returns `true` if the transaction status is `AcceptedOnL2`. + pub const fn is_accepted_on_l2(&self) -> bool { + matches!(self, Self::AcceptedOnL2) + } + + /// Returns `true` if the transaction status is `AcceptedOnL1`. + pub const fn is_accepted_on_l1(&self) -> bool { + matches!(self, Self::AcceptedOnL1) + } +} + #[derive(Debug, Deserialize, PartialEq, Eq)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] From 34c7f5b98bf7e558b1124347258d53a11be58610 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Wed, 19 Jun 2024 22:57:42 -0600 Subject: [PATCH 09/28] feat: use query txs for account deployment simulation (#611) --- starknet-accounts/src/factory/argent.rs | 10 +-- starknet-accounts/src/factory/mod.rs | 64 ++++++++++++++----- .../src/factory/open_zeppelin.rs | 10 +-- 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/starknet-accounts/src/factory/argent.rs b/starknet-accounts/src/factory/argent.rs index 4677ef74..bed65a97 100644 --- a/starknet-accounts/src/factory/argent.rs +++ b/starknet-accounts/src/factory/argent.rs @@ -80,9 +80,10 @@ where async fn sign_deployment_v1( &self, deployment: &RawAccountDeploymentV1, + query_only: bool, ) -> Result, Self::SignError> { - let tx_hash = - PreparedAccountDeploymentV1::from_raw(deployment.clone(), self).transaction_hash(); + let tx_hash = PreparedAccountDeploymentV1::from_raw(deployment.clone(), self) + .transaction_hash(query_only); let signature = self.signer.sign_hash(&tx_hash).await?; Ok(vec![signature.r, signature.s]) @@ -91,9 +92,10 @@ where async fn sign_deployment_v3( &self, deployment: &RawAccountDeploymentV3, + query_only: bool, ) -> Result, Self::SignError> { - let tx_hash = - PreparedAccountDeploymentV3::from_raw(deployment.clone(), self).transaction_hash(); + let tx_hash = PreparedAccountDeploymentV3::from_raw(deployment.clone(), self) + .transaction_hash(query_only); let signature = self.signer.sign_hash(&tx_hash).await?; Ok(vec![signature.r, signature.s]) diff --git a/starknet-accounts/src/factory/mod.rs b/starknet-accounts/src/factory/mod.rs index 8f292db4..aef251a4 100644 --- a/starknet-accounts/src/factory/mod.rs +++ b/starknet-accounts/src/factory/mod.rs @@ -26,6 +26,22 @@ const PREFIX_DEPLOY_ACCOUNT: Felt = Felt::from_raw([ 3350261884043292318, ]); +/// 2 ^ 128 + 1 +const QUERY_VERSION_ONE: Felt = Felt::from_raw([ + 576460752142433776, + 18446744073709551584, + 17407, + 18446744073700081633, +]); + +/// 2 ^ 128 + 3 +const QUERY_VERSION_THREE: Felt = Felt::from_raw([ + 576460752142432688, + 18446744073709551584, + 17407, + 18446744073700081569, +]); + /// Cairo string for "STARKNET_CONTRACT_ADDRESS" const PREFIX_CONTRACT_ADDRESS: Felt = Felt::from_raw([ 533439743893157637, @@ -65,11 +81,13 @@ pub trait AccountFactory: Sized { async fn sign_deployment_v1( &self, deployment: &RawAccountDeploymentV1, + query_only: bool, ) -> Result, Self::SignError>; async fn sign_deployment_v3( &self, deployment: &RawAccountDeploymentV3, + query_only: bool, ) -> Result, Self::SignError>; fn deploy_v1(&self, salt: Felt) -> AccountDeploymentV1 { @@ -404,7 +422,7 @@ where }, }; let deploy = prepared - .get_deploy_request() + .get_deploy_request(true) .await .map_err(AccountFactoryError::Signing)?; @@ -436,7 +454,7 @@ where }, }; let deploy = prepared - .get_deploy_request() + .get_deploy_request(true) .await .map_err(AccountFactoryError::Signing)?; @@ -637,7 +655,7 @@ where }, }; let deploy = prepared - .get_deploy_request() + .get_deploy_request(true) .await .map_err(AccountFactoryError::Signing)?; @@ -670,7 +688,7 @@ where }, }; let deploy = prepared - .get_deploy_request() + .get_deploy_request(true) .await .map_err(AccountFactoryError::Signing)?; @@ -760,13 +778,17 @@ where ) } - pub fn transaction_hash(&self) -> Felt { + pub fn transaction_hash(&self, query_only: bool) -> Felt { let mut calldata_to_hash = vec![self.factory.class_hash(), self.inner.salt]; calldata_to_hash.append(&mut self.factory.calldata()); compute_hash_on_elements(&[ PREFIX_DEPLOY_ACCOUNT, - Felt::ONE, // version + if query_only { + QUERY_VERSION_ONE + } else { + Felt::ONE + }, // version self.address(), Felt::ZERO, // entry_point_selector compute_hash_on_elements(&calldata_to_hash), @@ -780,7 +802,7 @@ where &self, ) -> Result> { let tx_request = self - .get_deploy_request() + .get_deploy_request(false) .await .map_err(AccountFactoryError::Signing)?; self.factory @@ -792,8 +814,12 @@ where async fn get_deploy_request( &self, + query_only: bool, ) -> Result { - let signature = self.factory.sign_deployment_v1(&self.inner).await?; + let signature = self + .factory + .sign_deployment_v1(&self.inner, query_only) + .await?; Ok(BroadcastedDeployAccountTransactionV1 { max_fee: self.inner.max_fee, @@ -802,8 +828,7 @@ where contract_address_salt: self.inner.salt, constructor_calldata: self.factory.calldata(), class_hash: self.factory.class_hash(), - // TODO: make use of query version tx for estimating fees - is_query: false, + is_query: query_only, }) } } @@ -821,11 +846,15 @@ where ) } - pub fn transaction_hash(&self) -> Felt { + pub fn transaction_hash(&self, query_only: bool) -> Felt { let mut hasher = PoseidonHasher::new(); hasher.update(PREFIX_DEPLOY_ACCOUNT); - hasher.update(Felt::THREE); + hasher.update(if query_only { + QUERY_VERSION_THREE + } else { + Felt::THREE + }); hasher.update(self.address()); hasher.update({ @@ -882,7 +911,7 @@ where &self, ) -> Result> { let tx_request = self - .get_deploy_request() + .get_deploy_request(false) .await .map_err(AccountFactoryError::Signing)?; self.factory @@ -894,8 +923,12 @@ where async fn get_deploy_request( &self, + query_only: bool, ) -> Result { - let signature = self.factory.sign_deployment_v3(&self.inner).await?; + let signature = self + .factory + .sign_deployment_v3(&self.inner, query_only) + .await?; Ok(BroadcastedDeployAccountTransactionV3 { signature, @@ -921,8 +954,7 @@ where // Hard-coded L1 DA mode for nonce and fee nonce_data_availability_mode: DataAvailabilityMode::L1, fee_data_availability_mode: DataAvailabilityMode::L1, - // TODO: make use of query version tx for estimating fees - is_query: false, + is_query: query_only, }) } } diff --git a/starknet-accounts/src/factory/open_zeppelin.rs b/starknet-accounts/src/factory/open_zeppelin.rs index 0b1c78ad..72882e45 100644 --- a/starknet-accounts/src/factory/open_zeppelin.rs +++ b/starknet-accounts/src/factory/open_zeppelin.rs @@ -77,9 +77,10 @@ where async fn sign_deployment_v1( &self, deployment: &RawAccountDeploymentV1, + query_only: bool, ) -> Result, Self::SignError> { - let tx_hash = - PreparedAccountDeploymentV1::from_raw(deployment.clone(), self).transaction_hash(); + let tx_hash = PreparedAccountDeploymentV1::from_raw(deployment.clone(), self) + .transaction_hash(query_only); let signature = self.signer.sign_hash(&tx_hash).await?; Ok(vec![signature.r, signature.s]) @@ -88,9 +89,10 @@ where async fn sign_deployment_v3( &self, deployment: &RawAccountDeploymentV3, + query_only: bool, ) -> Result, Self::SignError> { - let tx_hash = - PreparedAccountDeploymentV3::from_raw(deployment.clone(), self).transaction_hash(); + let tx_hash = PreparedAccountDeploymentV3::from_raw(deployment.clone(), self) + .transaction_hash(query_only); let signature = self.signer.sign_hash(&tx_hash).await?; Ok(vec![signature.r, signature.s]) From 71b19119cbb482e35108db4c2e5f3338eacacaa5 Mon Sep 17 00:00:00 2001 From: Ammar Arif Date: Fri, 21 Jun 2024 02:44:47 +0800 Subject: [PATCH 10/28] feat: enable num-traits feature for `Felt` (#612) --- starknet-core/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starknet-core/Cargo.toml b/starknet-core/Cargo.toml index f3f7862d..e5ebd2a0 100644 --- a/starknet-core/Cargo.toml +++ b/starknet-core/Cargo.toml @@ -27,7 +27,7 @@ serde_json = { version = "1.0.96", default-features = false, features = ["alloc" serde_json_pythonic = { version = "0.1.2", default-features = false, features = ["alloc", "raw_value"] } serde_with = { version = "2.3.2", default-features = false, features = ["alloc", "macros"] } sha3 = { version = "0.10.7", default-features = false } -starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve", "serde"] } +starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve", "serde", "num-traits"] } [dev-dependencies] criterion = { version = "0.4.0", default-features = false } From 016f3ee3293c8355f8a7cb64777adea6119493b9 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Thu, 20 Jun 2024 16:58:45 -0600 Subject: [PATCH 11/28] release: bump starknet-core to 0.11.1 (#613) --- Cargo.lock | 2 +- Cargo.toml | 2 +- starknet-accounts/Cargo.toml | 2 +- starknet-contract/Cargo.toml | 2 +- starknet-core/Cargo.toml | 2 +- starknet-macros/Cargo.toml | 2 +- starknet-providers/Cargo.toml | 2 +- starknet-signers/Cargo.toml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 630c100c..2ab904b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1991,7 +1991,7 @@ dependencies = [ [[package]] name = "starknet-core" -version = "0.11.0" +version = "0.11.1" dependencies = [ "base64 0.21.0", "criterion", diff --git a/Cargo.toml b/Cargo.toml index c6307866..1d9542a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ all-features = true [dependencies] starknet-crypto = { version = "0.7.0", path = "./starknet-crypto" } -starknet-core = { version = "0.11.0", path = "./starknet-core", default-features = false } +starknet-core = { version = "0.11.1", path = "./starknet-core", default-features = false } starknet-providers = { version = "0.11.0", path = "./starknet-providers" } starknet-contract = { version = "0.10.0", path = "./starknet-contract" } starknet-signers = { version = "0.9.0", path = "./starknet-signers" } diff --git a/starknet-accounts/Cargo.toml b/starknet-accounts/Cargo.toml index fdb256c6..55827140 100644 --- a/starknet-accounts/Cargo.toml +++ b/starknet-accounts/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["ethereum", "starknet", "web3"] exclude = ["test-data/**"] [dependencies] -starknet-core = { version = "0.11.0", path = "../starknet-core" } +starknet-core = { version = "0.11.1", path = "../starknet-core" } starknet-crypto = { version = "0.7.0", path = "../starknet-crypto" } starknet-providers = { version = "0.11.0", path = "../starknet-providers" } starknet-signers = { version = "0.9.0", path = "../starknet-signers" } diff --git a/starknet-contract/Cargo.toml b/starknet-contract/Cargo.toml index 992069df..290e3e55 100644 --- a/starknet-contract/Cargo.toml +++ b/starknet-contract/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["ethereum", "starknet", "web3"] exclude = ["test-data/**"] [dependencies] -starknet-core = { version = "0.11.0", path = "../starknet-core" } +starknet-core = { version = "0.11.1", path = "../starknet-core" } starknet-providers = { version = "0.11.0", path = "../starknet-providers" } starknet-accounts = { version = "0.10.0", path = "../starknet-accounts" } serde = { version = "1.0.160", features = ["derive"] } diff --git a/starknet-core/Cargo.toml b/starknet-core/Cargo.toml index e5ebd2a0..5be48640 100644 --- a/starknet-core/Cargo.toml +++ b/starknet-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-core" -version = "0.11.0" +version = "0.11.1" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" diff --git a/starknet-macros/Cargo.toml b/starknet-macros/Cargo.toml index 78b1a782..82d6471c 100644 --- a/starknet-macros/Cargo.toml +++ b/starknet-macros/Cargo.toml @@ -16,7 +16,7 @@ keywords = ["ethereum", "starknet", "web3"] proc-macro = true [dependencies] -starknet-core = { version = "0.11.0", path = "../starknet-core" } +starknet-core = { version = "0.11.1", path = "../starknet-core" } syn = "2.0.15" [features] diff --git a/starknet-providers/Cargo.toml b/starknet-providers/Cargo.toml index bfcf2275..3760028c 100644 --- a/starknet-providers/Cargo.toml +++ b/starknet-providers/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["ethereum", "starknet", "web3"] exclude = ["test-data/**"] [dependencies] -starknet-core = { version = "0.11.0", path = "../starknet-core" } +starknet-core = { version = "0.11.1", path = "../starknet-core" } async-trait = "0.1.68" auto_impl = "1.0.1" ethereum-types = "0.14.1" diff --git a/starknet-signers/Cargo.toml b/starknet-signers/Cargo.toml index fd331ae2..75467e7c 100644 --- a/starknet-signers/Cargo.toml +++ b/starknet-signers/Cargo.toml @@ -13,7 +13,7 @@ Starknet signer implementations keywords = ["ethereum", "starknet", "web3"] [dependencies] -starknet-core = { version = "0.11.0", path = "../starknet-core" } +starknet-core = { version = "0.11.1", path = "../starknet-core" } starknet-crypto = { version = "0.7.0", path = "../starknet-crypto" } async-trait = "0.1.68" auto_impl = "1.0.1" From a78cc041843dbb198f15482263ff5f4b96ad7da4 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Fri, 28 Jun 2024 17:12:15 -0600 Subject: [PATCH 12/28] ci: replace macos-11 with macos-12 (#618) --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4f93f2c2..2ba9b375 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-11] + os: [ubuntu-latest, macos-12] toolchain: [stable, nightly] steps: From 36bcc5dbe9095e5e75c59db51d75f5776c39f8fc Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Fri, 28 Jun 2024 17:28:57 -0600 Subject: [PATCH 13/28] feat: signer interactivity (#617) Makes signer implementations specify whether a signing operation is "interactive" (or just expensive). Utilizing this new information, `Account` and `AccountFactory` now make more informed decisions on whether to request real signatures for different types of operations. The most significant benefit of this change is allowing using hardware wallet without excessive unnecessary signing requests. --- README.md | 6 +- examples/declare_cairo0_contract.rs | 3 +- examples/declare_cairo1_contract.rs | 3 +- examples/deploy_account_with_ledger.rs | 1 + examples/deploy_argent_account.rs | 1 + examples/mint_tokens.rs | 2 +- examples/transfer_with_ledger.rs | 57 ++++++++ starknet-accounts/src/account/declaration.rs | 133 +++++++++++++----- starknet-accounts/src/account/execution.rs | 86 ++++++++--- starknet-accounts/src/account/mod.rs | 20 +++ starknet-accounts/src/factory/argent.rs | 4 + starknet-accounts/src/factory/mod.rs | 90 +++++++++--- .../src/factory/open_zeppelin.rs | 4 + starknet-accounts/src/single_owner.rs | 4 + starknet-signers/src/ledger.rs | 4 + starknet-signers/src/local_wallet.rs | 4 + starknet-signers/src/signer.rs | 10 ++ 17 files changed, 347 insertions(+), 85 deletions(-) create mode 100644 examples/transfer_with_ledger.rs diff --git a/README.md b/README.md index d5639993..99b88ea6 100644 --- a/README.md +++ b/README.md @@ -100,9 +100,11 @@ Examples can be found in the [examples folder](./examples): 10. [Deploy an OpenZeppelin account with Ledger](./examples/deploy_account_with_ledger.rs) -11. [Parsing a JSON-RPC request on the server side](./examples/parse_jsonrpc_request.rs) +11. [Transfer ERC20 tokens with Ledger](./examples/transfer_with_ledger.rs) -12. [Inspecting a erased provider-specific error type](./examples/downcast_provider_error.rs) +12. [Parsing a JSON-RPC request on the server side](./examples/parse_jsonrpc_request.rs) + +13. [Inspecting a erased provider-specific error type](./examples/downcast_provider_error.rs) ## License diff --git a/examples/declare_cairo0_contract.rs b/examples/declare_cairo0_contract.rs index bb7dadfc..1bf94b0d 100644 --- a/examples/declare_cairo0_contract.rs +++ b/examples/declare_cairo0_contract.rs @@ -45,5 +45,6 @@ async fn main() { .await .unwrap(); - dbg!(result); + println!("Transaction hash: {:#064x}", result.transaction_hash); + println!("Class hash: {:#064x}", result.class_hash); } diff --git a/examples/declare_cairo1_contract.rs b/examples/declare_cairo1_contract.rs index f6f2fb3d..86ab0fdd 100644 --- a/examples/declare_cairo1_contract.rs +++ b/examples/declare_cairo1_contract.rs @@ -53,5 +53,6 @@ async fn main() { .await .unwrap(); - dbg!(result); + println!("Transaction hash: {:#064x}", result.transaction_hash); + println!("Class hash: {:#064x}", result.class_hash); } diff --git a/examples/deploy_account_with_ledger.rs b/examples/deploy_account_with_ledger.rs index 0f25ad2b..ef4ba9ae 100644 --- a/examples/deploy_account_with_ledger.rs +++ b/examples/deploy_account_with_ledger.rs @@ -51,6 +51,7 @@ async fn main() { match result { Ok(tx) => { println!("Transaction hash: {:#064x}", tx.transaction_hash); + println!("Account: {:#064x}", tx.contract_address); } Err(err) => { eprintln!("Error: {err}"); diff --git a/examples/deploy_argent_account.rs b/examples/deploy_argent_account.rs index 8eff33cc..acd559c7 100644 --- a/examples/deploy_argent_account.rs +++ b/examples/deploy_argent_account.rs @@ -47,6 +47,7 @@ async fn main() { match result { Ok(tx) => { println!("Transaction hash: {:#064x}", tx.transaction_hash); + println!("Account: {:#064x}", tx.contract_address); } Err(err) => { eprintln!("Error: {err}"); diff --git a/examples/mint_tokens.rs b/examples/mint_tokens.rs index 33e86ea2..64fc7ada 100644 --- a/examples/mint_tokens.rs +++ b/examples/mint_tokens.rs @@ -51,5 +51,5 @@ async fn main() { .await .unwrap(); - dbg!(result); + println!("Transaction hash: {:#064x}", result.transaction_hash); } diff --git a/examples/transfer_with_ledger.rs b/examples/transfer_with_ledger.rs new file mode 100644 index 00000000..223da492 --- /dev/null +++ b/examples/transfer_with_ledger.rs @@ -0,0 +1,57 @@ +use starknet::{ + accounts::{Account, Call, ExecutionEncoding, SingleOwnerAccount}, + core::{ + chain_id, + types::{BlockId, BlockTag, Felt}, + utils::get_selector_from_name, + }, + macros::felt, + providers::{ + jsonrpc::{HttpTransport, JsonRpcClient}, + Url, + }, + signers::LedgerSigner, +}; + +#[tokio::main] +async fn main() { + let provider = JsonRpcClient::new(HttpTransport::new( + Url::parse("https://starknet-sepolia.public.blastapi.io/rpc/v0_7").unwrap(), + )); + + let signer = LedgerSigner::new( + "m/2645'/1195502025'/1470455285'/0'/0'/0" + .try_into() + .expect("unable to parse path"), + ) + .await + .expect("failed to initialize Starknet Ledger app"); + let address = Felt::from_hex("YOUR_ACCOUNT_CONTRACT_ADDRESS_IN_HEX_HERE").unwrap(); + let eth_token_address = + Felt::from_hex("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7") + .unwrap(); + + let mut account = SingleOwnerAccount::new( + provider, + signer, + address, + chain_id::SEPOLIA, + ExecutionEncoding::New, + ); + + // `SingleOwnerAccount` defaults to checking nonce and estimating fees against the latest + // block. Optionally change the target block to pending with the following line: + account.set_block_id(BlockId::Tag(BlockTag::Pending)); + + let result = account + .execute_v1(vec![Call { + to: eth_token_address, + selector: get_selector_from_name("transfer").unwrap(), + calldata: vec![felt!("0x1234"), felt!("100"), Felt::ZERO], + }]) + .send() + .await + .unwrap(); + + println!("Transaction hash: {:#064x}", result.transaction_hash); +} diff --git a/starknet-accounts/src/account/declaration.rs b/starknet-accounts/src/account/declaration.rs index 5162320f..360dc924 100644 --- a/starknet-accounts/src/account/declaration.rs +++ b/starknet-accounts/src/account/declaration.rs @@ -12,6 +12,7 @@ use starknet_core::{ BroadcastedDeclareTransactionV2, BroadcastedDeclareTransactionV3, BroadcastedTransaction, DataAvailabilityMode, DeclareTransactionResult, FeeEstimate, Felt, FlattenedSierraClass, ResourceBounds, ResourceBoundsMapping, SimulatedTransaction, SimulationFlag, + SimulationFlagForEstimateFee, }, }; use starknet_crypto::PoseidonHasher; @@ -195,6 +196,8 @@ where &self, nonce: Felt, ) -> Result> { + let skip_signature = self.account.is_signer_interactive(); + let prepared = PreparedDeclarationV2 { account: self.account, inner: RawDeclarationV2 { @@ -204,13 +207,19 @@ where max_fee: Felt::ZERO, }, }; - let declare = prepared.get_declare_request(true).await?; + let declare = prepared.get_declare_request(true, skip_signature).await?; self.account .provider() .estimate_fee_single( BroadcastedTransaction::Declare(BroadcastedDeclareTransaction::V2(declare)), - [], + if skip_signature { + // Validation would fail since real signature was not requested + vec![SimulationFlagForEstimateFee::SkipValidate] + } else { + // With the correct signature in place, run validation for accurate results + vec![] + }, self.account.block_id(), ) .await @@ -223,6 +232,16 @@ where skip_validate: bool, skip_fee_charge: bool, ) -> Result> { + let skip_signature = if self.account.is_signer_interactive() { + // If signer is interactive, we would try to minimize signing requests. However, if the + // caller has decided to not skip validation, it's best we still request a real + // signature, as otherwise the simulation would most likely fail. + skip_validate + } else { + // Signing with non-interactive signers is cheap so always request signatures. + false + }; + let prepared = PreparedDeclarationV2 { account: self.account, inner: RawDeclarationV2 { @@ -232,7 +251,7 @@ where max_fee: self.max_fee.unwrap_or_default(), }, }; - let declare = prepared.get_declare_request(true).await?; + let declare = prepared.get_declare_request(true, skip_signature).await?; let mut flags = vec![]; @@ -470,6 +489,8 @@ where &self, nonce: Felt, ) -> Result> { + let skip_signature = self.account.is_signer_interactive(); + let prepared = PreparedDeclarationV3 { account: self.account, inner: RawDeclarationV3 { @@ -480,13 +501,19 @@ where gas_price: 0, }, }; - let declare = prepared.get_declare_request(true).await?; + let declare = prepared.get_declare_request(true, skip_signature).await?; self.account .provider() .estimate_fee_single( BroadcastedTransaction::Declare(BroadcastedDeclareTransaction::V3(declare)), - [], + if skip_signature { + // Validation would fail since real signature was not requested + vec![SimulationFlagForEstimateFee::SkipValidate] + } else { + // With the correct signature in place, run validation for accurate results + vec![] + }, self.account.block_id(), ) .await @@ -499,6 +526,16 @@ where skip_validate: bool, skip_fee_charge: bool, ) -> Result> { + let skip_signature = if self.account.is_signer_interactive() { + // If signer is interactive, we would try to minimize signing requests. However, if the + // caller has decided to not skip validation, it's best we still request a real + // signature, as otherwise the simulation would most likely fail. + skip_validate + } else { + // Signing with non-interactive signers is cheap so always request signatures. + false + }; + let prepared = PreparedDeclarationV3 { account: self.account, inner: RawDeclarationV3 { @@ -509,7 +546,7 @@ where gas_price: self.gas_price.unwrap_or_default(), }, }; - let declare = prepared.get_declare_request(true).await?; + let declare = prepared.get_declare_request(true, skip_signature).await?; let mut flags = vec![]; @@ -673,6 +710,8 @@ where &self, nonce: Felt, ) -> Result> { + let skip_signature = self.account.is_signer_interactive(); + let prepared = PreparedLegacyDeclaration { account: self.account, inner: RawLegacyDeclaration { @@ -681,13 +720,19 @@ where max_fee: Felt::ZERO, }, }; - let declare = prepared.get_declare_request(true).await?; + let declare = prepared.get_declare_request(true, skip_signature).await?; self.account .provider() .estimate_fee_single( BroadcastedTransaction::Declare(BroadcastedDeclareTransaction::V1(declare)), - [], + if skip_signature { + // Validation would fail since real signature was not requested + vec![SimulationFlagForEstimateFee::SkipValidate] + } else { + // With the correct signature in place, run validation for accurate results + vec![] + }, self.account.block_id(), ) .await @@ -700,6 +745,16 @@ where skip_validate: bool, skip_fee_charge: bool, ) -> Result> { + let skip_signature = if self.account.is_signer_interactive() { + // If signer is interactive, we would try to minimize signing requests. However, if the + // caller has decided to not skip validation, it's best we still request a real + // signature, as otherwise the simulation would most likely fail. + skip_validate + } else { + // Signing with non-interactive signers is cheap so always request signatures. + false + }; + let prepared = PreparedLegacyDeclaration { account: self.account, inner: RawLegacyDeclaration { @@ -708,7 +763,7 @@ where max_fee: self.max_fee.unwrap_or_default(), }, }; - let declare = prepared.get_declare_request(true).await?; + let declare = prepared.get_declare_request(true, skip_signature).await?; let mut flags = vec![]; @@ -895,7 +950,7 @@ where A: ConnectedAccount, { pub async fn send(&self) -> Result> { - let tx_request = self.get_declare_request(false).await?; + let tx_request = self.get_declare_request(false, false).await?; self.account .provider() .add_declare_transaction(BroadcastedDeclareTransaction::V2(tx_request)) @@ -903,19 +958,21 @@ where .map_err(AccountError::Provider) } - pub async fn get_declare_request( + async fn get_declare_request( &self, query_only: bool, + skip_signature: bool, ) -> Result> { - let signature = self - .account - .sign_declaration_v2(&self.inner, query_only) - .await - .map_err(AccountError::Signing)?; - Ok(BroadcastedDeclareTransactionV2 { max_fee: self.inner.max_fee, - signature, + signature: if skip_signature { + vec![] + } else { + self.account + .sign_declaration_v2(&self.inner, query_only) + .await + .map_err(AccountError::Signing)? + }, nonce: self.inner.nonce, contract_class: self.inner.contract_class.clone(), compiled_class_hash: self.inner.compiled_class_hash, @@ -942,7 +999,7 @@ where A: ConnectedAccount, { pub async fn send(&self) -> Result> { - let tx_request = self.get_declare_request(false).await?; + let tx_request = self.get_declare_request(false, false).await?; self.account .provider() .add_declare_transaction(BroadcastedDeclareTransaction::V3(tx_request)) @@ -950,20 +1007,22 @@ where .map_err(AccountError::Provider) } - pub async fn get_declare_request( + async fn get_declare_request( &self, query_only: bool, + skip_signature: bool, ) -> Result> { - let signature = self - .account - .sign_declaration_v3(&self.inner, query_only) - .await - .map_err(AccountError::Signing)?; - Ok(BroadcastedDeclareTransactionV3 { sender_address: self.account.address(), compiled_class_hash: self.inner.compiled_class_hash, - signature, + signature: if skip_signature { + vec![] + } else { + self.account + .sign_declaration_v3(&self.inner, query_only) + .await + .map_err(AccountError::Signing)? + }, nonce: self.inner.nonce, contract_class: self.inner.contract_class.clone(), resource_bounds: ResourceBoundsMapping { @@ -1008,7 +1067,7 @@ where A: ConnectedAccount, { pub async fn send(&self) -> Result> { - let tx_request = self.get_declare_request(false).await?; + let tx_request = self.get_declare_request(false, false).await?; self.account .provider() .add_declare_transaction(BroadcastedDeclareTransaction::V1(tx_request)) @@ -1016,21 +1075,23 @@ where .map_err(AccountError::Provider) } - pub async fn get_declare_request( + async fn get_declare_request( &self, query_only: bool, + skip_signature: bool, ) -> Result> { - let signature = self - .account - .sign_legacy_declaration(&self.inner, query_only) - .await - .map_err(AccountError::Signing)?; - let compressed_class = self.inner.contract_class.compress().unwrap(); Ok(BroadcastedDeclareTransactionV1 { max_fee: self.inner.max_fee, - signature, + signature: if skip_signature { + vec![] + } else { + self.account + .sign_legacy_declaration(&self.inner, query_only) + .await + .map_err(AccountError::Signing)? + }, nonce: self.inner.nonce, contract_class: Arc::new(compressed_class), sender_address: self.account.address(), diff --git a/starknet-accounts/src/account/execution.rs b/starknet-accounts/src/account/execution.rs index cef482fc..99757da0 100644 --- a/starknet-accounts/src/account/execution.rs +++ b/starknet-accounts/src/account/execution.rs @@ -10,7 +10,7 @@ use starknet_core::{ BroadcastedInvokeTransaction, BroadcastedInvokeTransactionV1, BroadcastedInvokeTransactionV3, BroadcastedTransaction, DataAvailabilityMode, FeeEstimate, Felt, InvokeTransactionResult, ResourceBounds, ResourceBoundsMapping, SimulatedTransaction, - SimulationFlag, + SimulationFlag, SimulationFlagForEstimateFee, }, }; use starknet_crypto::PoseidonHasher; @@ -245,6 +245,8 @@ where &self, nonce: Felt, ) -> Result> { + let skip_signature = self.account.is_signer_interactive(); + let prepared = PreparedExecutionV1 { account: self.account, inner: RawExecutionV1 { @@ -254,7 +256,7 @@ where }, }; let invoke = prepared - .get_invoke_request(true) + .get_invoke_request(true, skip_signature) .await .map_err(AccountError::Signing)?; @@ -262,7 +264,13 @@ where .provider() .estimate_fee_single( BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction::V1(invoke)), - [], + if skip_signature { + // Validation would fail since real signature was not requested + vec![SimulationFlagForEstimateFee::SkipValidate] + } else { + // With the correct signature in place, run validation for accurate results + vec![] + }, self.account.block_id(), ) .await @@ -275,6 +283,16 @@ where skip_validate: bool, skip_fee_charge: bool, ) -> Result> { + let skip_signature = if self.account.is_signer_interactive() { + // If signer is interactive, we would try to minimize signing requests. However, if the + // caller has decided to not skip validation, it's best we still request a real + // signature, as otherwise the simulation would most likely fail. + skip_validate + } else { + // Signing with non-interactive signers is cheap so always request signatures. + false + }; + let prepared = PreparedExecutionV1 { account: self.account, inner: RawExecutionV1 { @@ -284,7 +302,7 @@ where }, }; let invoke = prepared - .get_invoke_request(true) + .get_invoke_request(true, skip_signature) .await .map_err(AccountError::Signing)?; @@ -450,6 +468,8 @@ where &self, nonce: Felt, ) -> Result> { + let skip_signature = self.account.is_signer_interactive(); + let prepared = PreparedExecutionV3 { account: self.account, inner: RawExecutionV3 { @@ -460,7 +480,7 @@ where }, }; let invoke = prepared - .get_invoke_request(true) + .get_invoke_request(true, skip_signature) .await .map_err(AccountError::Signing)?; @@ -468,7 +488,13 @@ where .provider() .estimate_fee_single( BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction::V3(invoke)), - [], + if skip_signature { + // Validation would fail since real signature was not requested + vec![SimulationFlagForEstimateFee::SkipValidate] + } else { + // With the correct signature in place, run validation for accurate results + vec![] + }, self.account.block_id(), ) .await @@ -481,6 +507,16 @@ where skip_validate: bool, skip_fee_charge: bool, ) -> Result> { + let skip_signature = if self.account.is_signer_interactive() { + // If signer is interactive, we would try to minimize signing requests. However, if the + // caller has decided to not skip validation, it's best we still request a real + // signature, as otherwise the simulation would most likely fail. + skip_validate + } else { + // Signing with non-interactive signers is cheap so always request signatures. + false + }; + let prepared = PreparedExecutionV3 { account: self.account, inner: RawExecutionV3 { @@ -491,7 +527,7 @@ where }, }; let invoke = prepared - .get_invoke_request(true) + .get_invoke_request(true, skip_signature) .await .map_err(AccountError::Signing)?; @@ -682,7 +718,7 @@ where { pub async fn send(&self) -> Result> { let tx_request = self - .get_invoke_request(false) + .get_invoke_request(false, false) .await .map_err(AccountError::Signing)?; self.account @@ -695,18 +731,20 @@ where // The `simulate` function is temporarily removed until it's supported in [Provider] // TODO: add `simulate` back once transaction simulation in supported - pub async fn get_invoke_request( + async fn get_invoke_request( &self, query_only: bool, + skip_signature: bool, ) -> Result { - let signature = self - .account - .sign_execution_v1(&self.inner, query_only) - .await?; - Ok(BroadcastedInvokeTransactionV1 { max_fee: self.inner.max_fee, - signature, + signature: if skip_signature { + vec![] + } else { + self.account + .sign_execution_v1(&self.inner, query_only) + .await? + }, nonce: self.inner.nonce, sender_address: self.account.address(), calldata: self.account.encode_calls(&self.inner.calls), @@ -721,7 +759,7 @@ where { pub async fn send(&self) -> Result> { let tx_request = self - .get_invoke_request(false) + .get_invoke_request(false, false) .await .map_err(AccountError::Signing)?; self.account @@ -734,19 +772,21 @@ where // The `simulate` function is temporarily removed until it's supported in [Provider] // TODO: add `simulate` back once transaction simulation in supported - pub async fn get_invoke_request( + async fn get_invoke_request( &self, query_only: bool, + skip_signature: bool, ) -> Result { - let signature = self - .account - .sign_execution_v3(&self.inner, query_only) - .await?; - Ok(BroadcastedInvokeTransactionV3 { sender_address: self.account.address(), calldata: self.account.encode_calls(&self.inner.calls), - signature, + signature: if skip_signature { + vec![] + } else { + self.account + .sign_execution_v3(&self.inner, query_only) + .await? + }, nonce: self.inner.nonce, resource_bounds: ResourceBoundsMapping { l1_gas: ResourceBounds { diff --git a/starknet-accounts/src/account/mod.rs b/starknet-accounts/src/account/mod.rs index 30e39730..f2e6d62e 100644 --- a/starknet-accounts/src/account/mod.rs +++ b/starknet-accounts/src/account/mod.rs @@ -55,6 +55,14 @@ pub trait Account: ExecutionEncoder + Sized { query_only: bool, ) -> Result, Self::SignError>; + /// Whether the underlying signer implementation is interactive, such as a hardware wallet. + /// Implementations should return `true` if the signing operation is very expensive, even if not + /// strictly "interactive" as in requiring human input. + /// + /// This affects how an account makes decision on whether to request a real signature for + /// estimation/simulation purposes. + fn is_signer_interactive(&self) -> bool; + fn execute_v1(&self, calls: Vec) -> ExecutionV1 { ExecutionV1::new(calls, self) } @@ -354,6 +362,10 @@ where .sign_legacy_declaration(legacy_declaration, query_only) .await } + + fn is_signer_interactive(&self) -> bool { + (*self).is_signer_interactive() + } } #[cfg_attr(not(target_arch = "wasm32"), async_trait)] @@ -417,6 +429,10 @@ where .sign_legacy_declaration(legacy_declaration, query_only) .await } + + fn is_signer_interactive(&self) -> bool { + self.as_ref().is_signer_interactive() + } } #[cfg_attr(not(target_arch = "wasm32"), async_trait)] @@ -480,6 +496,10 @@ where .sign_legacy_declaration(legacy_declaration, query_only) .await } + + fn is_signer_interactive(&self) -> bool { + self.as_ref().is_signer_interactive() + } } #[cfg_attr(not(target_arch = "wasm32"), async_trait)] diff --git a/starknet-accounts/src/factory/argent.rs b/starknet-accounts/src/factory/argent.rs index bed65a97..5bfa0476 100644 --- a/starknet-accounts/src/factory/argent.rs +++ b/starknet-accounts/src/factory/argent.rs @@ -73,6 +73,10 @@ where &self.provider } + fn is_signer_interactive(&self) -> bool { + self.signer.is_interactive() + } + fn block_id(&self) -> BlockId { self.block_id } diff --git a/starknet-accounts/src/factory/mod.rs b/starknet-accounts/src/factory/mod.rs index aef251a4..1dc3b773 100644 --- a/starknet-accounts/src/factory/mod.rs +++ b/starknet-accounts/src/factory/mod.rs @@ -8,7 +8,7 @@ use starknet_core::{ BroadcastedDeployAccountTransactionV1, BroadcastedDeployAccountTransactionV3, BroadcastedTransaction, DataAvailabilityMode, DeployAccountTransactionResult, FeeEstimate, Felt, NonZeroFelt, ResourceBounds, ResourceBoundsMapping, SimulatedTransaction, - SimulationFlag, StarknetError, + SimulationFlag, SimulationFlagForEstimateFee, StarknetError, }, }; use starknet_crypto::PoseidonHasher; @@ -73,6 +73,14 @@ pub trait AccountFactory: Sized { fn provider(&self) -> &Self::Provider; + /// Whether the underlying signer implementation is interactive, such as a hardware wallet. + /// Implementations should return `true` if the signing operation is very expensive, even if not + /// strictly "interactive" as in requiring human input. + /// + /// This affects how an account factory makes decision on whether to request a real signature + /// for estimation/simulation purposes. + fn is_signer_interactive(&self) -> bool; + /// Block ID to use when estimating fees. fn block_id(&self) -> BlockId { BlockId::Tag(BlockTag::Latest) @@ -413,6 +421,8 @@ where &self, nonce: Felt, ) -> Result> { + let skip_signature = self.factory.is_signer_interactive(); + let prepared = PreparedAccountDeploymentV1 { factory: self.factory, inner: RawAccountDeploymentV1 { @@ -422,7 +432,7 @@ where }, }; let deploy = prepared - .get_deploy_request(true) + .get_deploy_request(true, skip_signature) .await .map_err(AccountFactoryError::Signing)?; @@ -432,7 +442,13 @@ where BroadcastedTransaction::DeployAccount(BroadcastedDeployAccountTransaction::V1( deploy, )), - [], + if skip_signature { + // Validation would fail since real signature was not requested + vec![SimulationFlagForEstimateFee::SkipValidate] + } else { + // With the correct signature in place, run validation for accurate results + vec![] + }, self.factory.block_id(), ) .await @@ -445,6 +461,16 @@ where skip_validate: bool, skip_fee_charge: bool, ) -> Result> { + let skip_signature = if self.factory.is_signer_interactive() { + // If signer is interactive, we would try to minimize signing requests. However, if the + // caller has decided to not skip validation, it's best we still request a real + // signature, as otherwise the simulation would most likely fail. + skip_validate + } else { + // Signing with non-interactive signers is cheap so always request signatures. + false + }; + let prepared = PreparedAccountDeploymentV1 { factory: self.factory, inner: RawAccountDeploymentV1 { @@ -454,7 +480,7 @@ where }, }; let deploy = prepared - .get_deploy_request(true) + .get_deploy_request(true, skip_signature) .await .map_err(AccountFactoryError::Signing)?; @@ -645,6 +671,8 @@ where &self, nonce: Felt, ) -> Result> { + let skip_signature = self.factory.is_signer_interactive(); + let prepared = PreparedAccountDeploymentV3 { factory: self.factory, inner: RawAccountDeploymentV3 { @@ -655,7 +683,7 @@ where }, }; let deploy = prepared - .get_deploy_request(true) + .get_deploy_request(true, skip_signature) .await .map_err(AccountFactoryError::Signing)?; @@ -665,7 +693,13 @@ where BroadcastedTransaction::DeployAccount(BroadcastedDeployAccountTransaction::V3( deploy, )), - [], + if skip_signature { + // Validation would fail since real signature was not requested + vec![SimulationFlagForEstimateFee::SkipValidate] + } else { + // With the correct signature in place, run validation for accurate results + vec![] + }, self.factory.block_id(), ) .await @@ -678,6 +712,16 @@ where skip_validate: bool, skip_fee_charge: bool, ) -> Result> { + let skip_signature = if self.factory.is_signer_interactive() { + // If signer is interactive, we would try to minimize signing requests. However, if the + // caller has decided to not skip validation, it's best we still request a real + // signature, as otherwise the simulation would most likely fail. + skip_validate + } else { + // Signing with non-interactive signers is cheap so always request signatures. + false + }; + let prepared = PreparedAccountDeploymentV3 { factory: self.factory, inner: RawAccountDeploymentV3 { @@ -688,7 +732,7 @@ where }, }; let deploy = prepared - .get_deploy_request(true) + .get_deploy_request(true, skip_signature) .await .map_err(AccountFactoryError::Signing)?; @@ -802,7 +846,7 @@ where &self, ) -> Result> { let tx_request = self - .get_deploy_request(false) + .get_deploy_request(false, false) .await .map_err(AccountFactoryError::Signing)?; self.factory @@ -815,15 +859,17 @@ where async fn get_deploy_request( &self, query_only: bool, + skip_signature: bool, ) -> Result { - let signature = self - .factory - .sign_deployment_v1(&self.inner, query_only) - .await?; - Ok(BroadcastedDeployAccountTransactionV1 { max_fee: self.inner.max_fee, - signature, + signature: if skip_signature { + vec![] + } else { + self.factory + .sign_deployment_v1(&self.inner, query_only) + .await? + }, nonce: self.inner.nonce, contract_address_salt: self.inner.salt, constructor_calldata: self.factory.calldata(), @@ -911,7 +957,7 @@ where &self, ) -> Result> { let tx_request = self - .get_deploy_request(false) + .get_deploy_request(false, false) .await .map_err(AccountFactoryError::Signing)?; self.factory @@ -924,14 +970,16 @@ where async fn get_deploy_request( &self, query_only: bool, + skip_signature: bool, ) -> Result { - let signature = self - .factory - .sign_deployment_v3(&self.inner, query_only) - .await?; - Ok(BroadcastedDeployAccountTransactionV3 { - signature, + signature: if skip_signature { + vec![] + } else { + self.factory + .sign_deployment_v3(&self.inner, query_only) + .await? + }, nonce: self.inner.nonce, contract_address_salt: self.inner.salt, constructor_calldata: self.factory.calldata(), diff --git a/starknet-accounts/src/factory/open_zeppelin.rs b/starknet-accounts/src/factory/open_zeppelin.rs index 72882e45..3b23b16e 100644 --- a/starknet-accounts/src/factory/open_zeppelin.rs +++ b/starknet-accounts/src/factory/open_zeppelin.rs @@ -70,6 +70,10 @@ where &self.provider } + fn is_signer_interactive(&self) -> bool { + self.signer.is_interactive() + } + fn block_id(&self) -> BlockId { self.block_id } diff --git a/starknet-accounts/src/single_owner.rs b/starknet-accounts/src/single_owner.rs index 9aa7a5b7..0677a8d8 100644 --- a/starknet-accounts/src/single_owner.rs +++ b/starknet-accounts/src/single_owner.rs @@ -170,6 +170,10 @@ where Ok(vec![signature.r, signature.s]) } + + fn is_signer_interactive(&self) -> bool { + self.signer.is_interactive() + } } impl ExecutionEncoder for SingleOwnerAccount diff --git a/starknet-signers/src/ledger.rs b/starknet-signers/src/ledger.rs index 140d787c..8071a78f 100644 --- a/starknet-signers/src/ledger.rs +++ b/starknet-signers/src/ledger.rs @@ -163,6 +163,10 @@ impl Signer for LedgerSigner { Ok(signature) } + + fn is_interactive(&self) -> bool { + true + } } impl From for LedgerError { diff --git a/starknet-signers/src/local_wallet.rs b/starknet-signers/src/local_wallet.rs index 23c00b28..2c898da0 100644 --- a/starknet-signers/src/local_wallet.rs +++ b/starknet-signers/src/local_wallet.rs @@ -36,6 +36,10 @@ impl Signer for LocalWallet { async fn sign_hash(&self, hash: &Felt) -> Result { Ok(self.private_key.sign(hash)?) } + + fn is_interactive(&self) -> bool { + false + } } impl From for LocalWallet { diff --git a/starknet-signers/src/signer.rs b/starknet-signers/src/signer.rs index 0f586f82..429efede 100644 --- a/starknet-signers/src/signer.rs +++ b/starknet-signers/src/signer.rs @@ -15,4 +15,14 @@ pub trait Signer { async fn get_public_key(&self) -> Result; async fn sign_hash(&self, hash: &Felt) -> Result; + + /// Whether the underlying signer implementation is interactive, such as a hardware wallet. + /// Implementations should return `true` if the signing operation is very expensive, even if not + /// strictly "interactive" as in requiring human input. + /// + /// This mainly affects the transaction simulation strategy used by higher-level types. With + /// non-interactive signers, it's fine to sign multiple times for getting the most accurate + /// estimation/simulation possible; but with interactive signers, they would accept less + /// accurate results to minimize signing requests. + fn is_interactive(&self) -> bool; } From 1ea9e7207d31b36f4e77d23868f2ea12b5393ea6 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Fri, 28 Jun 2024 20:50:29 -0600 Subject: [PATCH 14/28] fix: `std` not enabled for `starknet-types-core` (#619) --- Cargo.lock | 17 +++++++++++++++++ starknet-crypto/Cargo.toml | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 2ab904b9..1e814960 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1116,11 +1116,27 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "lambdaworks-crypto" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb5d4f22241504f7c7b8d2c3a7d7835d7c07117f10bff2a7d96a9ef6ef217c3" +dependencies = [ + "lambdaworks-math", + "serde", + "sha2", + "sha3", +] + [[package]] name = "lambdaworks-math" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "358e172628e713b80a530a59654154bfc45783a6ed70ea284839800cebdf8f97" +dependencies = [ + "serde", + "serde_json", +] [[package]] name = "lazy_static" @@ -2112,6 +2128,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe29a53d28ff630e4c7827788f14b28f9386d27cb9d05186a5f2e73218c34677" dependencies = [ + "lambdaworks-crypto", "lambdaworks-math", "num-bigint", "num-integer", diff --git a/starknet-crypto/Cargo.toml b/starknet-crypto/Cargo.toml index c81cd10b..75b185d2 100644 --- a/starknet-crypto/Cargo.toml +++ b/starknet-crypto/Cargo.toml @@ -29,7 +29,7 @@ starknet-types-core = { version = "0.1.3", default-features = false, features = [features] default = ["std", "signature-display"] -std = [] +std = ["starknet-types-core/std"] alloc = ["hex?/alloc", "starknet-types-core/alloc"] signature-display = ["dep:hex", "alloc"] From 838c612e445ae22af07beceaba862c708da2ab2d Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Fri, 28 Jun 2024 21:29:00 -0600 Subject: [PATCH 15/28] release: bump starknet-crypto to 0.7.1 (#620) --- Cargo.lock | 2 +- Cargo.toml | 2 +- examples/starknet-wasm/Cargo.toml | 2 +- starknet-accounts/Cargo.toml | 2 +- starknet-core/Cargo.toml | 2 +- starknet-crypto/Cargo.toml | 2 +- starknet-signers/Cargo.toml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1e814960..a46c8dd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2028,7 +2028,7 @@ dependencies = [ [[package]] name = "starknet-crypto" -version = "0.7.0" +version = "0.7.1" dependencies = [ "criterion", "crypto-bigint", diff --git a/Cargo.toml b/Cargo.toml index 1d9542a6..b3c0f9cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ members = [ all-features = true [dependencies] -starknet-crypto = { version = "0.7.0", path = "./starknet-crypto" } +starknet-crypto = { version = "0.7.1", path = "./starknet-crypto" } starknet-core = { version = "0.11.1", path = "./starknet-core", default-features = false } starknet-providers = { version = "0.11.0", path = "./starknet-providers" } starknet-contract = { version = "0.10.0", path = "./starknet-contract" } diff --git a/examples/starknet-wasm/Cargo.toml b/examples/starknet-wasm/Cargo.toml index cf4f900c..2ec65513 100644 --- a/examples/starknet-wasm/Cargo.toml +++ b/examples/starknet-wasm/Cargo.toml @@ -19,6 +19,6 @@ crate-type = ["cdylib", "rlib"] default = ["console_error_panic_hook"] [dependencies] -starknet-crypto = { version = "0.7.0", path = "../../starknet-crypto" } +starknet-crypto = { version = "0.7.1", path = "../../starknet-crypto" } console_error_panic_hook = { version = "0.1.7", optional = true } wasm-bindgen = "0.2.84" diff --git a/starknet-accounts/Cargo.toml b/starknet-accounts/Cargo.toml index 55827140..6ad3ad82 100644 --- a/starknet-accounts/Cargo.toml +++ b/starknet-accounts/Cargo.toml @@ -15,7 +15,7 @@ exclude = ["test-data/**"] [dependencies] starknet-core = { version = "0.11.1", path = "../starknet-core" } -starknet-crypto = { version = "0.7.0", path = "../starknet-crypto" } +starknet-crypto = { version = "0.7.1", path = "../starknet-crypto" } starknet-providers = { version = "0.11.0", path = "../starknet-providers" } starknet-signers = { version = "0.9.0", path = "../starknet-signers" } async-trait = "0.1.68" diff --git a/starknet-core/Cargo.toml b/starknet-core/Cargo.toml index 5be48640..cc501344 100644 --- a/starknet-core/Cargo.toml +++ b/starknet-core/Cargo.toml @@ -17,7 +17,7 @@ exclude = ["test-data/**"] all-features = true [dependencies] -starknet-crypto = { version = "0.7.0", path = "../starknet-crypto", default-features = false, features = ["alloc"] } +starknet-crypto = { version = "0.7.1", path = "../starknet-crypto", default-features = false, features = ["alloc"] } base64 = { version = "0.21.0", default-features = false, features = ["alloc"] } crypto-bigint = { version = "0.5.1", default-features = false } flate2 = { version = "1.0.25", optional = true } diff --git a/starknet-crypto/Cargo.toml b/starknet-crypto/Cargo.toml index 75b185d2..2c73c00f 100644 --- a/starknet-crypto/Cargo.toml +++ b/starknet-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-crypto" -version = "0.7.0" +version = "0.7.1" authors = ["Jonathan LEI "] license = "MIT OR Apache-2.0" edition = "2021" diff --git a/starknet-signers/Cargo.toml b/starknet-signers/Cargo.toml index 75467e7c..9a378f45 100644 --- a/starknet-signers/Cargo.toml +++ b/starknet-signers/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["ethereum", "starknet", "web3"] [dependencies] starknet-core = { version = "0.11.1", path = "../starknet-core" } -starknet-crypto = { version = "0.7.0", path = "../starknet-crypto" } +starknet-crypto = { version = "0.7.1", path = "../starknet-crypto" } async-trait = "0.1.68" auto_impl = "1.0.1" thiserror = "1.0.40" From 702008d296907765162e6cadecb5b9f8acf83995 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Sat, 29 Jun 2024 02:21:14 -0600 Subject: [PATCH 16/28] feat: add `LedgerStarknetApp` type for Ledger specific operations (#621) --- starknet-signers/src/ledger.rs | 91 +++++++++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 12 deletions(-) diff --git a/starknet-signers/src/ledger.rs b/starknet-signers/src/ledger.rs index 8071a78f..5bffac18 100644 --- a/starknet-signers/src/ledger.rs +++ b/starknet-signers/src/ledger.rs @@ -22,12 +22,19 @@ const EIP_2645_PATH_LENGTH: usize = 6; const PUBLIC_KEY_SIZE: usize = 65; const SIGNATURE_SIZE: usize = 65; +/// Ledger app wrapper that implements the [`Signer`] trait. #[derive(Debug)] pub struct LedgerSigner { - transport: Ledger, + app: LedgerStarknetApp, derivation_path: DerivationPath, } +/// A handle for communicating with the Ledger Starknet app. +#[derive(Debug)] +pub struct LedgerStarknetApp { + transport: Ledger, +} + #[derive(Debug, thiserror::Error)] pub enum LedgerError { #[error("derivation path is empty, not prefixed with m/2645', or is not 6-level long")] @@ -77,8 +84,6 @@ impl LedgerSigner { /// /// Currently, the Ledger app only enforces the length and the first level of the path. pub async fn new(derivation_path: DerivationPath) -> Result { - let transport = Ledger::init().await?; - if !matches!(derivation_path.iter().next(), Some(&EIP_2645_PURPOSE)) || derivation_path.len() != EIP_2645_PATH_LENGTH { @@ -86,7 +91,7 @@ impl LedgerSigner { } Ok(Self { - transport, + app: LedgerStarknetApp::new().await?, derivation_path, }) } @@ -98,12 +103,57 @@ impl Signer for LedgerSigner { type SignError = LedgerError; async fn get_public_key(&self) -> Result { + self.app + .get_public_key(self.derivation_path.clone(), false) + .await + } + + async fn sign_hash(&self, hash: &Felt) -> Result { + self.app.sign_hash(self.derivation_path.clone(), hash).await + } + + fn is_interactive(&self) -> bool { + true + } +} + +impl LedgerStarknetApp { + /// Initializes the Starknet Ledger app. Attempts to find and connect to a Ledger device. The + /// device must be unlocked and have the Starknet app open. + pub async fn new() -> Result { + let transport = Ledger::init().await?; + + Ok(Self { transport }) + } + + /// Gets a public key from the app for a particular derivation path, with optional on-device + /// confirmation for extra security. + /// + /// The derivation path _must_ follow EIP-2645, i.e. having `2645'` as its "purpose" level as + /// per BIP-44, as the Ledger app does not allow other paths to be used. + /// + /// The path _must_ also be 6-level in length. An example path for Starknet would be: + /// + /// `m/2645'/1195502025'/1470455285'/0'/0'/0` + /// + /// where: + /// + /// - `2645'` is the EIP-2645 prefix + /// - `1195502025'`, decimal for `0x4741e9c9`, is the 31 lowest bits for `sha256(starknet)` + /// - `1470455285'`, decimal for `0x57a55df5`, is the 31 lowest bits for `sha256(starkli)` + /// + /// Currently, the Ledger app only enforces the length and the first level of the path. + async fn get_public_key( + &self, + derivation_path: DerivationPath, + display: bool, + ) -> Result { let response = self .transport .exchange( &GetPubKeyCommand { - display: false, - path: self.derivation_path.clone(), + display, + path: derivation_path, } .into(), ) @@ -123,13 +173,34 @@ impl Signer for LedgerSigner { Ok(VerifyingKey::from_scalar(pubkey_x)) } - async fn sign_hash(&self, hash: &Felt) -> Result { + /// Requests a signature for a **raw hash** with a certain derivation path. Currently the Ledger + /// app only supports blind signing raw hashes. + /// + /// The derivation path _must_ follow EIP-2645, i.e. having `2645'` as its "purpose" level as + /// per BIP-44, as the Ledger app does not allow other paths to be used. + /// + /// The path _must_ also be 6-level in length. An example path for Starknet would be: + /// + /// `m/2645'/1195502025'/1470455285'/0'/0'/0` + /// + /// where: + /// + /// - `2645'` is the EIP-2645 prefix + /// - `1195502025'`, decimal for `0x4741e9c9`, is the 31 lowest bits for `sha256(starknet)` + /// - `1470455285'`, decimal for `0x57a55df5`, is the 31 lowest bits for `sha256(starkli)` + /// + /// Currently, the Ledger app only enforces the length and the first level of the path. + async fn sign_hash( + &self, + derivation_path: DerivationPath, + hash: &Felt, + ) -> Result { get_apdu_data( &self .transport .exchange( &SignHashCommand1 { - path: self.derivation_path.clone(), + path: derivation_path, } .into(), ) @@ -163,10 +234,6 @@ impl Signer for LedgerSigner { Ok(signature) } - - fn is_interactive(&self) -> bool { - true - } } impl From for LedgerError { From 50eed828021365f86d346953ea017587f452aa9e Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Sat, 29 Jun 2024 02:38:07 -0600 Subject: [PATCH 17/28] fix: `LedgerStarknetApp` method privacy (#622) --- starknet-signers/src/ledger.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/starknet-signers/src/ledger.rs b/starknet-signers/src/ledger.rs index 5bffac18..beca1775 100644 --- a/starknet-signers/src/ledger.rs +++ b/starknet-signers/src/ledger.rs @@ -143,7 +143,7 @@ impl LedgerStarknetApp { /// - `1470455285'`, decimal for `0x57a55df5`, is the 31 lowest bits for `sha256(starkli)` /// /// Currently, the Ledger app only enforces the length and the first level of the path. - async fn get_public_key( + pub async fn get_public_key( &self, derivation_path: DerivationPath, display: bool, @@ -190,7 +190,7 @@ impl LedgerStarknetApp { /// - `1470455285'`, decimal for `0x57a55df5`, is the 31 lowest bits for `sha256(starkli)` /// /// Currently, the Ledger app only enforces the length and the first level of the path. - async fn sign_hash( + pub async fn sign_hash( &self, derivation_path: DerivationPath, hash: &Felt, From db1fa598232f0698d942cc974f481b5d888ac080 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Sat, 29 Jun 2024 15:42:04 -0600 Subject: [PATCH 18/28] feat: get ledger app version (#623) --- Cargo.lock | 7 +++++++ starknet-signers/Cargo.toml | 3 ++- starknet-signers/src/ledger.rs | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index a46c8dd0..aa130718 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1782,6 +1782,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + [[package]] name = "serde" version = "1.0.203" @@ -2116,6 +2122,7 @@ dependencies = [ "eth-keystore", "getrandom", "rand", + "semver", "starknet-core", "starknet-crypto", "thiserror", diff --git a/starknet-signers/Cargo.toml b/starknet-signers/Cargo.toml index 9a378f45..d0515adf 100644 --- a/starknet-signers/Cargo.toml +++ b/starknet-signers/Cargo.toml @@ -21,6 +21,7 @@ thiserror = "1.0.40" crypto-bigint = { version = "0.5.1", default-features = false } rand = { version = "0.8.5", features = ["std_rng"] } coins-bip32 = { version = "0.11.1", optional = true } +semver = { version = "1.0.23", optional = true } # Using a fork until https://github.com/summa-tx/coins/issues/137 is fixed coins-ledger = { git = "https://github.com/xJonathanLEI/coins", rev = "0e3be5db0b18b683433de6b666556b99c726e785", default-features = false, optional = true } @@ -37,4 +38,4 @@ wasm-bindgen-test = "0.3.34" [features] default = [] -ledger = ["coins-bip32", "coins-ledger"] +ledger = ["coins-bip32", "coins-ledger", "semver"] diff --git a/starknet-signers/src/ledger.rs b/starknet-signers/src/ledger.rs index beca1775..e86ae90d 100644 --- a/starknet-signers/src/ledger.rs +++ b/starknet-signers/src/ledger.rs @@ -5,6 +5,7 @@ use coins_ledger::{ APDUAnswer, APDUCommand, Ledger, }; use crypto_bigint::{ArrayEncoding, U256}; +use semver::Version; use starknet_core::{crypto::Signature, types::Felt}; use crate::{Signer, VerifyingKey}; @@ -19,6 +20,7 @@ const EIP_2645_PURPOSE: u32 = 0x80000a55; const EIP_2645_PATH_LENGTH: usize = 6; +const VERSION_SIZE: usize = 3; const PUBLIC_KEY_SIZE: usize = 65; const SIGNATURE_SIZE: usize = 65; @@ -49,6 +51,9 @@ pub enum LedgerError { UnexpectedResponseLength { expected: usize, actual: usize }, } +/// The `GetPubKey` Ledger command. +struct GetVersion; + /// The `GetPubKey` Ledger command. struct GetPubKeyCommand { display: bool, @@ -126,6 +131,21 @@ impl LedgerStarknetApp { Ok(Self { transport }) } + /// Gets the Ledger app version. + pub async fn get_version(&self) -> Result { + let response = self.transport.exchange(&GetVersion.into()).await?; + + let data = get_apdu_data(&response)?; + if data.len() != VERSION_SIZE { + return Err(LedgerError::UnexpectedResponseLength { + expected: VERSION_SIZE, + actual: data.len(), + }); + } + + Ok(Version::new(data[0] as u64, data[1] as u64, data[2] as u64)) + } + /// Gets a public key from the app for a particular derivation path, with optional on-device /// confirmation for extra security. /// @@ -242,6 +262,19 @@ impl From for LedgerError { } } +impl From for APDUCommand { + fn from(_value: GetVersion) -> Self { + Self { + cla: CLA_STARKNET, + ins: 0x00, + p1: 0x00, + p2: 0x00, + data: APDUData::new(&[]), + response_len: None, + } + } +} + impl From for APDUCommand { fn from(value: GetPubKeyCommand) -> Self { let path = value From b28241c0036cabb2cece8206c6c0b94908a286ff Mon Sep 17 00:00:00 2001 From: Ammar Arif Date: Thu, 4 Jul 2024 23:14:56 +0800 Subject: [PATCH 19/28] re-export starknet-types-core felt module (#616) --- starknet-core/src/types/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starknet-core/src/types/mod.rs b/starknet-core/src/types/mod.rs index e5494a82..16614753 100644 --- a/starknet-core/src/types/mod.rs +++ b/starknet-core/src/types/mod.rs @@ -5,7 +5,7 @@ use serde_with::serde_as; use crate::serde::unsigned_field_element::UfeHex; -pub use starknet_types_core::felt::{Felt, NonZeroFelt}; +pub use starknet_types_core::felt::*; mod conversions; From 7bb13d3f02f23949cf3c263e1b53ffcc43990ce6 Mon Sep 17 00:00:00 2001 From: Guspan Tanadi <36249910+guspan-tanadi@users.noreply.github.com> Date: Thu, 4 Jul 2024 22:19:01 +0700 Subject: [PATCH 20/28] docs(README): link version IAccount.cairo (#624) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99b88ea6..ba8e58a1 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ starknet = { git = "https://github.com/xJonathanLEI/starknet-rs" } - [x] Sequencer gateway / feeder gateway client - [x] Full node JSON-RPC API client - [x] Smart contract deployment -- [x] Signer for using [IAccount](https://github.com/OpenZeppelin/cairo-contracts/blob/main/src/openzeppelin/account/IAccount.cairo) account contracts +- [x] Signer for using [IAccount](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.6.1/src/openzeppelin/account/IAccount.cairo) account contracts - [ ] Strongly-typed smart contract binding code generation from ABI - [x] Ledger hardware wallet support From ee149a4584dfc797b81398ebf6afcd3fee7f3b36 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Sun, 14 Jul 2024 15:51:32 -0600 Subject: [PATCH 21/28] chore: make clippy happy again (#627) --- starknet-providers/src/sequencer/mod.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/starknet-providers/src/sequencer/mod.rs b/starknet-providers/src/sequencer/mod.rs index 8e83a11e..74d05225 100644 --- a/starknet-providers/src/sequencer/mod.rs +++ b/starknet-providers/src/sequencer/mod.rs @@ -174,9 +174,6 @@ enum RawFieldElementResponse { SequencerError(SequencerError), } -#[derive(Deserialize)] -struct EmptyObject {} - impl SequencerGatewayProvider { fn extend_gateway_url(&self, segment: &str) -> Url { let mut url = self.gateway_url.clone(); From fc9b9209e714bcd4b5f439ec32bdc720112f684d Mon Sep 17 00:00:00 2001 From: TheVeloper Date: Mon, 15 Jul 2024 00:04:23 +0200 Subject: [PATCH 22/28] refactor: replace Pedersen implementation with type-rs (#614) --- starknet-crypto/Cargo.toml | 2 +- starknet-crypto/src/pedersen_hash.rs | 45 ++++------------------------ 2 files changed, 6 insertions(+), 41 deletions(-) diff --git a/starknet-crypto/Cargo.toml b/starknet-crypto/Cargo.toml index 2c73c00f..07312853 100644 --- a/starknet-crypto/Cargo.toml +++ b/starknet-crypto/Cargo.toml @@ -25,7 +25,7 @@ rfc6979 = { version = "0.4.0", default-features = false } sha2 = { version = "0.10.6", default-features = false } zeroize = { version = "1.6.0", default-features = false } hex = { version = "0.4.3", default-features = false, optional = true } -starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve"] } +starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve", "hash"] } [features] default = ["std", "signature-display"] diff --git a/starknet-crypto/src/pedersen_hash.rs b/starknet-crypto/src/pedersen_hash.rs index a5026750..a59c5345 100644 --- a/starknet-crypto/src/pedersen_hash.rs +++ b/starknet-crypto/src/pedersen_hash.rs @@ -1,8 +1,7 @@ -use starknet_curve::curve_params; -use starknet_types_core::curve::{AffinePoint, ProjectivePoint}; -use starknet_types_core::felt::Felt; - -use crate::pedersen_points::*; +use starknet_types_core::{ + felt::Felt, + hash::{Pedersen, StarkHash}, +}; /// Computes the Starkware version of the Pedersen hash of x and y. All inputs are little-endian. /// @@ -11,41 +10,7 @@ use crate::pedersen_points::*; /// * `x`: The x coordinate /// * `y`: The y coordinate pub fn pedersen_hash(x: &Felt, y: &Felt) -> Felt { - let x = x.to_bits_le(); - let y = y.to_bits_le(); - - // Preprocessed material is lookup-tables for each chunk of bits - let table_size = (1 << CURVE_CONSTS_BITS) - 1; - let add_points = |acc: &mut ProjectivePoint, bits: &[bool], prep: &[AffinePoint]| { - bits.chunks(CURVE_CONSTS_BITS) - .enumerate() - .for_each(|(i, v)| { - let offset = v - .iter() - .rev() - .fold(0, |acc, &bit| (acc << 1) + bit as usize); - if offset > 0 { - // Table lookup at 'offset-1' in table for chunk 'i' - *acc += &prep[i * table_size + offset - 1]; - } - }); - }; - - // Compute hash - let mut acc = - ProjectivePoint::from_affine(curve_params::SHIFT_POINT.x(), curve_params::SHIFT_POINT.y()) - .unwrap(); - - add_points(&mut acc, &x[..248], &CURVE_CONSTS_P0); // Add a_low * P1 - add_points(&mut acc, &x[248..252], &CURVE_CONSTS_P1); // Add a_high * P2 - add_points(&mut acc, &y[..248], &CURVE_CONSTS_P2); // Add b_low * P3 - add_points(&mut acc, &y[248..252], &CURVE_CONSTS_P3); // Add b_high * P4 - - // Convert to affine - let result = acc.to_affine().unwrap(); - - // Return x-coordinate - result.x() + Pedersen::hash(x, y) } #[cfg(test)] From c943cd876960fc2a2382c991d006f7c8b8df6fc0 Mon Sep 17 00:00:00 2001 From: FabijanC Date: Mon, 15 Jul 2024 15:55:20 +0200 Subject: [PATCH 23/28] Replace declare_v1 suggestion with declare_v2 (#628) --- starknet-accounts/src/account/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starknet-accounts/src/account/mod.rs b/starknet-accounts/src/account/mod.rs index f2e6d62e..94c9031c 100644 --- a/starknet-accounts/src/account/mod.rs +++ b/starknet-accounts/src/account/mod.rs @@ -92,7 +92,7 @@ pub trait Account: ExecutionEncoder + Sized { DeclarationV3::new(contract_class, compiled_class_hash, self) } - #[deprecated = "use version specific variants (`declare_v1` & `declare_v3`) instead"] + #[deprecated = "use version specific variants (`declare_v2` & `declare_v3`) instead"] fn declare( &self, contract_class: Arc, From 6a9f124bf9d973f27360e72bb486576beb7b53a2 Mon Sep 17 00:00:00 2001 From: Ammar Arif Date: Mon, 15 Jul 2024 21:55:39 +0800 Subject: [PATCH 24/28] include `starknet-types-core` std (#615) --- starknet-core/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starknet-core/Cargo.toml b/starknet-core/Cargo.toml index cc501344..7f189a68 100644 --- a/starknet-core/Cargo.toml +++ b/starknet-core/Cargo.toml @@ -39,7 +39,7 @@ wasm-bindgen-test = "0.3.34" [features] default = ["std"] -std = ["dep:flate2", "starknet-crypto/std"] +std = ["dep:flate2", "starknet-crypto/std", "starknet-types-core/std"] no_unknown_fields = [] [[bench]] From 08a7807072c3b327de72eacc467bb7fa4324b346 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Tue, 16 Jul 2024 01:19:38 +0200 Subject: [PATCH 25/28] chore: bump `serde_with` to 3.9 (#625) This is a breaking change as `serde_with` ends up in the public API. --- Cargo.lock | 113 ++++++++++++++++++++++++---------- starknet-contract/Cargo.toml | 2 +- starknet-core/Cargo.toml | 2 +- starknet-providers/Cargo.toml | 2 +- 4 files changed, 85 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa130718..4d5b040b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,15 +112,15 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" [[package]] name = "base64" -version = "0.21.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -277,7 +277,7 @@ checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ "bitflags 1.3.2", "clap_lex", - "indexmap", + "indexmap 1.9.3", "textwrap", ] @@ -527,9 +527,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -537,27 +537,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 1.0.109", + "syn 2.0.63", ] [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 1.0.109", + "syn 2.0.63", ] [[package]] @@ -570,6 +570,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "digest" version = "0.10.7" @@ -630,6 +640,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "eth-keystore" version = "0.5.0" @@ -824,7 +840,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -843,6 +859,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1050,7 +1072,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", "serde", ] @@ -1267,6 +1300,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" version = "0.1.45" @@ -1416,6 +1455,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1844,15 +1889,17 @@ dependencies = [ [[package]] name = "serde_with" -version = "2.3.2" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331bb8c3bf9b92457ab7abecf07078c13f7d270ba490103e84e8b014490cd0b0" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" dependencies = [ - "base64 0.13.1", + "base64 0.22.1", "chrono", "hex", - "indexmap", + "indexmap 1.9.3", + "indexmap 2.2.6", "serde", + "serde_derive", "serde_json", "serde_with_macros", "time", @@ -1860,14 +1907,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "2.3.2" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859011bddcc11f289f07f467cc1fe01c7a941daa4d8f6c40d4d1c92eb6d9319c" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.63", ] [[package]] @@ -2160,9 +2207,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" @@ -2235,11 +2282,14 @@ dependencies = [ [[package]] name = "time" -version = "0.3.20" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ + "deranged", "itoa", + "num-conv", + "powerfmt", "serde", "time-core", "time-macros", @@ -2247,16 +2297,17 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -2361,7 +2412,7 @@ version = "0.19.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" dependencies = [ - "indexmap", + "indexmap 1.9.3", "toml_datetime", "winnow", ] diff --git a/starknet-contract/Cargo.toml b/starknet-contract/Cargo.toml index 290e3e55..1c44ac28 100644 --- a/starknet-contract/Cargo.toml +++ b/starknet-contract/Cargo.toml @@ -19,7 +19,7 @@ starknet-providers = { version = "0.11.0", path = "../starknet-providers" } starknet-accounts = { version = "0.10.0", path = "../starknet-accounts" } serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0.96" -serde_with = "2.3.2" +serde_with = "3.9.0" thiserror = "1.0.40" [dev-dependencies] diff --git a/starknet-core/Cargo.toml b/starknet-core/Cargo.toml index 7f189a68..a9215c23 100644 --- a/starknet-core/Cargo.toml +++ b/starknet-core/Cargo.toml @@ -25,7 +25,7 @@ hex = { version = "0.4.3", default-features = false, features = ["alloc"] } serde = { version = "1.0.160", default-features = false, features = ["derive"] } serde_json = { version = "1.0.96", default-features = false, features = ["alloc", "raw_value"] } serde_json_pythonic = { version = "0.1.2", default-features = false, features = ["alloc", "raw_value"] } -serde_with = { version = "2.3.2", default-features = false, features = ["alloc", "macros"] } +serde_with = { version = "3.9.0", default-features = false, features = ["alloc", "macros"] } sha3 = { version = "0.10.7", default-features = false } starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve", "serde", "num-traits"] } diff --git a/starknet-providers/Cargo.toml b/starknet-providers/Cargo.toml index 3760028c..48db0b55 100644 --- a/starknet-providers/Cargo.toml +++ b/starknet-providers/Cargo.toml @@ -25,7 +25,7 @@ reqwest = { version = "0.11.16", default-features = false, features = ["rustls-t thiserror = "1.0.40" serde = "1.0.160" serde_json = "1.0.96" -serde_with = "2.3.2" +serde_with = "3.9.0" [target.'cfg(target_arch = "wasm32")'.dependencies] getrandom = { version = "0.2.9", features = ["js"] } From b8a0003997b9c2adad4620285916bc75a3e98fbc Mon Sep 17 00:00:00 2001 From: Ammar Arif Date: Tue, 16 Jul 2024 12:11:03 +0800 Subject: [PATCH 26/28] feat: de/serialize based on human readability (#532) Co-authored-by: Jonathan LEI --- Cargo.lock | 10 + starknet-core/Cargo.toml | 1 + starknet-core/src/serde/num_hex.rs | 46 ++++- .../src/serde/unsigned_field_element.rs | 184 ++++++++++++++++-- starknet-core/src/types/hash_256.rs | 50 ++++- 5 files changed, 268 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d5b040b..913a3aa3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,6 +134,15 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -2063,6 +2072,7 @@ name = "starknet-core" version = "0.11.1" dependencies = [ "base64 0.21.0", + "bincode", "criterion", "crypto-bigint", "flate2", diff --git a/starknet-core/Cargo.toml b/starknet-core/Cargo.toml index a9215c23..a035ded2 100644 --- a/starknet-core/Cargo.toml +++ b/starknet-core/Cargo.toml @@ -30,6 +30,7 @@ sha3 = { version = "0.10.7", default-features = false } starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve", "serde", "num-traits"] } [dev-dependencies] +bincode = "1.3.3" criterion = { version = "0.4.0", default-features = false } hex-literal = "0.4.1" starknet-core = { path = ".", features = ["no_unknown_fields"] } diff --git a/starknet-core/src/serde/num_hex.rs b/starknet-core/src/serde/num_hex.rs index 985b9053..6268fb1e 100644 --- a/starknet-core/src/serde/num_hex.rs +++ b/starknet-core/src/serde/num_hex.rs @@ -9,21 +9,29 @@ pub mod u64 { where S: Serializer, { - serializer.serialize_str(&format!("{value:#x}")) + if serializer.is_human_readable() { + serializer.serialize_str(&format!("{value:#x}")) + } else { + serializer.serialize_u64(*value) + } } pub fn deserialize<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { - deserializer.deserialize_any(NumHexVisitor) + if deserializer.is_human_readable() { + deserializer.deserialize_str(NumHexVisitor) + } else { + deserializer.deserialize_u64(NumHexVisitor) + } } impl<'de> Visitor<'de> for NumHexVisitor { type Value = u64; fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { - write!(formatter, "string") + write!(formatter, "string, or an array of u8") } fn visit_str(self, v: &str) -> Result @@ -33,5 +41,37 @@ pub mod u64 { u64::from_str_radix(v.trim_start_matches("0x"), 16) .map_err(|err| serde::de::Error::custom(format!("invalid u64 hex string: {err}"))) } + + fn visit_u64(self, v: u64) -> Result + where + E: serde::de::Error, + { + Ok(v) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use hex_literal::hex; + use serde::{Deserialize, Serialize}; + + #[derive(Serialize, Deserialize)] + struct TestStruct(#[serde(with = "u64")] pub u64); + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn bin_ser() { + let r = bincode::serialize(&TestStruct(0x1234)).unwrap(); + assert_eq!(r, hex!("3412000000000000")); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn bin_deser() { + let r = bincode::deserialize::(&hex!("3412000000000000")).unwrap(); + assert_eq!(r.0, 0x1234); } } diff --git a/starknet-core/src/serde/unsigned_field_element.rs b/starknet-core/src/serde/unsigned_field_element.rs index 38317ff9..f443797a 100644 --- a/starknet-core/src/serde/unsigned_field_element.rs +++ b/starknet-core/src/serde/unsigned_field_element.rs @@ -1,5 +1,6 @@ use alloc::{fmt::Formatter, format}; +use crypto_bigint::U256; use serde::{ de::{Error as DeError, Visitor}, Deserializer, Serializer, @@ -8,6 +9,9 @@ use serde_with::{DeserializeAs, SerializeAs}; use starknet_types_core::felt::Felt; +const PRIME: U256 = + U256::from_be_hex("0800000000000011000000000000000000000000000000000000000000000001"); + pub struct UfeHex; pub struct UfeHexOption; @@ -23,7 +27,11 @@ impl SerializeAs for UfeHex { where S: Serializer, { - serializer.serialize_str(&format!("{value:#x}")) + if serializer.is_human_readable() { + serializer.serialize_str(&format!("{value:#x}")) + } else { + serializer.serialize_bytes(&value.to_bytes_be()) + } } } @@ -32,7 +40,11 @@ impl<'de> DeserializeAs<'de, Felt> for UfeHex { where D: Deserializer<'de>, { - deserializer.deserialize_any(UfeHexVisitor) + if deserializer.is_human_readable() { + deserializer.deserialize_any(UfeHexVisitor) + } else { + deserializer.deserialize_bytes(UfeHexVisitor) + } } } @@ -40,7 +52,7 @@ impl<'de> Visitor<'de> for UfeHexVisitor { type Value = Felt; fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { - write!(formatter, "string") + write!(formatter, "a hex string, or an array of u8") } fn visit_str(self, v: &str) -> Result @@ -49,6 +61,16 @@ impl<'de> Visitor<'de> for UfeHexVisitor { { Felt::from_hex(v).map_err(|err| DeError::custom(format!("invalid hex string: {err}"))) } + + fn visit_bytes(self, v: &[u8]) -> Result { + let buf = <[u8; 32]>::try_from(v).map_err(serde::de::Error::custom)?; + + if U256::from_be_slice(&buf) < PRIME { + Ok(Felt::from_bytes_be(&buf)) + } else { + Err(serde::de::Error::custom("field element value out of range")) + } + } } impl SerializeAs> for UfeHexOption { @@ -56,9 +78,16 @@ impl SerializeAs> for UfeHexOption { where S: Serializer, { - match value { - Some(value) => serializer.serialize_str(&format!("{value:#064x}")), - None => serializer.serialize_none(), + if serializer.is_human_readable() { + match value { + Some(value) => serializer.serialize_str(&format!("{value:#064x}")), + None => serializer.serialize_none(), + } + } else { + match value { + Some(value) => serializer.serialize_bytes(&value.to_bytes_be()), + None => serializer.serialize_bytes(&[]), + } } } } @@ -68,7 +97,11 @@ impl<'de> DeserializeAs<'de, Option> for UfeHexOption { where D: Deserializer<'de>, { - deserializer.deserialize_any(UfeHexOptionVisitor) + if deserializer.is_human_readable() { + deserializer.deserialize_any(UfeHexOptionVisitor) + } else { + deserializer.deserialize_bytes(UfeHexOptionVisitor) + } } } @@ -91,6 +124,20 @@ impl<'de> Visitor<'de> for UfeHexOptionVisitor { }, } } + + fn visit_bytes(self, v: &[u8]) -> Result { + if v.is_empty() { + return Ok(None); + } + + let buf = <[u8; 32]>::try_from(v).map_err(serde::de::Error::custom)?; + + if U256::from_be_slice(&buf) < PRIME { + Ok(Some(Felt::from_bytes_be(&buf))) + } else { + Err(serde::de::Error::custom("field element value out of range")) + } + } } impl SerializeAs> for UfePendingBlockHash { @@ -98,10 +145,17 @@ impl SerializeAs> for UfePendingBlockHash { where S: Serializer, { - match value { - Some(value) => serializer.serialize_str(&format!("{value:#064x}")), - // We don't know if it's `null` or `"pending"` - None => serializer.serialize_none(), + if serializer.is_human_readable() { + match value { + Some(value) => serializer.serialize_str(&format!("{value:#064x}")), + // We don't know if it's `null` or `"pending"` + None => serializer.serialize_none(), + } + } else { + match value { + Some(value) => serializer.serialize_bytes(&value.to_bytes_be()), + None => serializer.serialize_bytes(&[]), + } } } } @@ -111,7 +165,11 @@ impl<'de> DeserializeAs<'de, Option> for UfePendingBlockHash { where D: Deserializer<'de>, { - deserializer.deserialize_any(UfePendingBlockHashVisitor) + if deserializer.is_human_readable() { + deserializer.deserialize_any(UfePendingBlockHashVisitor) + } else { + deserializer.deserialize_bytes(UfePendingBlockHashVisitor) + } } } @@ -135,23 +193,115 @@ impl<'de> Visitor<'de> for UfePendingBlockHashVisitor { } } } + + fn visit_bytes(self, v: &[u8]) -> Result { + if v.is_empty() { + return Ok(None); + } + + let buf = <[u8; 32]>::try_from(v).map_err(serde::de::Error::custom)?; + + if U256::from_be_slice(&buf) < PRIME { + Ok(Some(Felt::from_bytes_be(&buf))) + } else { + Err(serde::de::Error::custom("field element value out of range")) + } + } } #[cfg(test)] mod tests { use super::*; - use serde::Deserialize; + use hex_literal::hex; + use serde::{Deserialize, Serialize}; use serde_with::serde_as; #[serde_as] - #[derive(Deserialize)] - struct TestStruct(#[serde_as(as = "UfeHexOption")] pub Option); + #[derive(Serialize, Deserialize)] + struct TestStruct(#[serde_as(as = "UfeHex")] pub Felt); + + #[serde_as] + #[derive(Serialize, Deserialize)] + struct TestOptionStruct(#[serde_as(as = "UfeHexOption")] pub Option); + + #[serde_as] + #[derive(Serialize, Deserialize)] + struct TestBlockHashStruct(#[serde_as(as = "UfePendingBlockHash")] pub Option); + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn bin_ser() { + let r = bincode::serialize(&TestStruct(Felt::ONE)).unwrap(); + assert_eq!( + r, + hex!( + "2000000000000000 0000000000000000000000000000000000000000000000000000000000000001" + ) + ); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn bin_deser() { + let r = bincode::deserialize::(&hex!( + "2000000000000000 0000000000000000000000000000000000000000000000000000000000000001" + )) + .unwrap(); + assert_eq!(r.0, Felt::ONE); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn bin_deser_out_of_range() { + if bincode::deserialize::(&hex!( + "2000000000000000 0800000000000011000000000000000000000000000000000000000000000001" + )) + .is_ok() + { + panic!("deserialization should fail") + } + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn option_deser_empty_string() { + let r = serde_json::from_str::("\"\"").unwrap(); + assert_eq!(r.0, None); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn option_bin_ser_none() { + let r = bincode::serialize(&TestOptionStruct(None)).unwrap(); + assert_eq!(r, hex!("0000000000000000")); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn option_bin_deser_none() { + let r = bincode::deserialize::(&hex!("0000000000000000")).unwrap(); + assert_eq!(r.0, None); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn pending_block_hash_deser_pending() { + let r = serde_json::from_str::("\"pending\"").unwrap(); + assert_eq!(r.0, None); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn pending_block_hash_bin_ser_none() { + let r = bincode::serialize(&TestBlockHashStruct(None)).unwrap(); + assert_eq!(r, hex!("0000000000000000")); + } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn empty_string_deser() { - let r = serde_json::from_str::("\"\"").unwrap(); + fn pending_block_hash_bin_deser_none() { + let r = bincode::deserialize::(&hex!("0000000000000000")).unwrap(); assert_eq!(r.0, None); } } diff --git a/starknet-core/src/types/hash_256.rs b/starknet-core/src/types/hash_256.rs index dd3e31d0..ec0bb839 100644 --- a/starknet-core/src/types/hash_256.rs +++ b/starknet-core/src/types/hash_256.rs @@ -78,7 +78,11 @@ impl Serialize for Hash256 { where S: serde::Serializer, { - serializer.serialize_str(&format!("0x{}", hex::encode(self.inner))) + if serializer.is_human_readable() { + serializer.serialize_str(&format!("0x{}", hex::encode(self.inner))) + } else { + serializer.serialize_bytes(self.as_bytes()) + } } } @@ -87,7 +91,11 @@ impl<'de> Deserialize<'de> for Hash256 { where D: serde::Deserializer<'de>, { - deserializer.deserialize_any(Hash256Visitor) + if deserializer.is_human_readable() { + deserializer.deserialize_any(Hash256Visitor) + } else { + deserializer.deserialize_bytes(Hash256Visitor) + } } } @@ -95,7 +103,7 @@ impl<'de> Visitor<'de> for Hash256Visitor { type Value = Hash256; fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { - write!(formatter, "string") + write!(formatter, "string, or an array of u8") } fn visit_str(self, v: &str) -> Result @@ -105,6 +113,12 @@ impl<'de> Visitor<'de> for Hash256Visitor { v.parse() .map_err(|err| serde::de::Error::custom(format!("{}", err))) } + + fn visit_bytes(self, v: &[u8]) -> Result { + <[u8; HASH_256_BYTE_COUNT]>::try_from(v) + .map(Hash256::from_bytes) + .map_err(serde::de::Error::custom) + } } impl FromStr for Hash256 { @@ -186,6 +200,8 @@ impl From<[u8; HASH_256_BYTE_COUNT]> for Hash256 { mod tests { use super::{Felt, FromHexError, Hash256, HASH_256_BYTE_COUNT}; + use hex_literal::hex; + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn test_hash_256_from_hex_error_unexpected_length() { @@ -243,4 +259,32 @@ mod tests { // Assert that the conversion from the `Felt` to `Hash256` is successful assert_eq!(Hash256::from_felt(&felt), hash_256); } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn bin_ser() { + let r = bincode::serialize(&Hash256::from_bytes(hex!( + "1111111111111111111111111111111111111111111111111111111111111111" + ))) + .unwrap(); + assert_eq!( + r, + hex!( + "2000000000000000 1111111111111111111111111111111111111111111111111111111111111111" + ) + ); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + fn bin_deser() { + let r = bincode::deserialize::(&hex!( + "2000000000000000 1111111111111111111111111111111111111111111111111111111111111111" + )) + .unwrap(); + assert_eq!( + r.inner, + hex!("1111111111111111111111111111111111111111111111111111111111111111") + ); + } } From bd7c62906a4a242fdc7ce0624ce8b4c5b6110760 Mon Sep 17 00:00:00 2001 From: Charpa <102919164+jbcaron@users.noreply.github.com> Date: Tue, 16 Jul 2024 06:33:20 +0200 Subject: [PATCH 27/28] feat(sequencer): add get_state_update_with_block (#597) --- starknet-providers/src/sequencer/mod.rs | 18 ++++++++++++++++++ starknet-providers/src/sequencer/models/mod.rs | 2 +- .../src/sequencer/models/state_update.rs | 10 ++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/starknet-providers/src/sequencer/mod.rs b/starknet-providers/src/sequencer/mod.rs index 74d05225..4453a3ed 100644 --- a/starknet-providers/src/sequencer/mod.rs +++ b/starknet-providers/src/sequencer/mod.rs @@ -313,6 +313,24 @@ impl SequencerGatewayProvider { .into() } + #[deprecated( + note = "Sequencer-specific functions are deprecated. Use it via the Provider trait instead." + )] + pub async fn get_state_update_with_block( + &self, + block_identifier: BlockId, + ) -> Result { + let mut request_url = self.extend_feeder_gateway_url("get_state_update"); + append_block_id(&mut request_url, block_identifier); + request_url + .query_pairs_mut() + .append_pair("includeBlock", "true"); + + self.send_get_request::>(request_url) + .await? + .into() + } + #[deprecated( note = "Sequencer-specific functions are deprecated. Use it via the Provider trait instead." )] diff --git a/starknet-providers/src/sequencer/models/mod.rs b/starknet-providers/src/sequencer/models/mod.rs index 3e269958..c1c0922e 100644 --- a/starknet-providers/src/sequencer/models/mod.rs +++ b/starknet-providers/src/sequencer/models/mod.rs @@ -46,7 +46,7 @@ mod contract; pub use contract::{CompressedLegacyContractClass, DeployedClass}; pub mod state_update; -pub use state_update::StateUpdate; +pub use state_update::{StateUpdate, StateUpdateWithBlock}; pub mod trace; pub use trace::{BlockTraces, TransactionTrace}; diff --git a/starknet-providers/src/sequencer/models/state_update.rs b/starknet-providers/src/sequencer/models/state_update.rs index 0447b96c..c0e56316 100644 --- a/starknet-providers/src/sequencer/models/state_update.rs +++ b/starknet-providers/src/sequencer/models/state_update.rs @@ -3,6 +3,16 @@ use serde_with::serde_as; use starknet_core::{serde::unsigned_field_element::UfeHex, types::Felt}; use std::collections::HashMap; +use super::Block; + +#[serde_as] +#[derive(Debug, Deserialize)] +#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] +pub struct StateUpdateWithBlock { + pub state_update: StateUpdate, + pub block: Block, +} + #[serde_as] #[derive(Debug, Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] From a8ee4e28468ee28e384b105a5c4f92d10df73fbd Mon Sep 17 00:00:00 2001 From: Aniket Prajapati <46114123+aniketpr01@users.noreply.github.com> Date: Tue, 16 Jul 2024 11:34:31 +0530 Subject: [PATCH 28/28] chore: more clippy lints (#598) --- Cargo.toml | 75 +++++++++ starknet-accounts/Cargo.toml | 3 + starknet-accounts/src/account/declaration.rs | 32 ++-- starknet-accounts/src/account/execution.rs | 20 +-- starknet-accounts/src/account/mod.rs | 45 +++--- starknet-accounts/src/factory/argent.rs | 1 + starknet-accounts/src/factory/mod.rs | 64 ++++---- .../src/factory/open_zeppelin.rs | 1 + starknet-accounts/src/single_owner.rs | 8 +- .../tests/single_owner_account.rs | 2 +- starknet-contract/Cargo.toml | 3 + starknet-contract/src/factory.rs | 35 +++-- .../tests/contract_deployment.rs | 4 +- starknet-core/Cargo.toml | 3 + starknet-core/src/chain_id.rs | 4 +- starknet-core/src/serde/byte_array.rs | 2 +- starknet-core/src/serde/num_hex.rs | 2 +- .../src/serde/unsigned_field_element.rs | 9 +- starknet-core/src/types/codegen.rs | 5 +- starknet-core/src/types/contract/legacy.rs | 22 ++- starknet-core/src/types/contract/mod.rs | 40 ++--- starknet-core/src/types/conversions.rs | 30 ++-- starknet-core/src/types/eth_address.rs | 6 +- starknet-core/src/types/execution_result.rs | 10 +- starknet-core/src/types/hash_256.rs | 10 +- starknet-core/src/types/mod.rs | 142 +++++++++--------- starknet-core/src/types/msg.rs | 8 +- starknet-core/src/types/receipt_block.rs | 24 +-- starknet-core/src/types/serde_impls.rs | 24 ++- starknet-core/src/types/u256.rs | 62 ++++---- starknet-core/src/utils.rs | 12 +- starknet-crypto-codegen/Cargo.toml | 3 + starknet-crypto/Cargo.toml | 3 + starknet-crypto/src/ecdsa.rs | 6 +- starknet-crypto/src/lib.rs | 1 + starknet-crypto/src/pedersen_hash.rs | 2 +- starknet-crypto/src/poseidon_hash.rs | 19 ++- starknet-crypto/src/rfc6979.rs | 4 +- starknet-curve/Cargo.toml | 3 + starknet-macros/Cargo.toml | 3 + starknet-macros/src/lib.rs | 2 +- starknet-providers/Cargo.toml | 3 + starknet-providers/src/any.rs | 2 +- starknet-providers/src/jsonrpc/mod.rs | 56 +++---- .../src/jsonrpc/transports/http.rs | 6 +- starknet-providers/src/provider.rs | 4 +- starknet-providers/src/sequencer/mod.rs | 40 +++-- .../src/sequencer/models/contract.rs | 2 +- .../src/sequencer/models/conversions.rs | 7 +- .../src/sequencer/models/serde_impls.rs | 6 +- .../src/sequencer/models/transaction.rs | 14 +- starknet-providers/src/sequencer/provider.rs | 5 +- starknet-providers/tests/jsonrpc.rs | 2 +- starknet-signers/Cargo.toml | 3 + starknet-signers/src/key_pair.rs | 8 +- 55 files changed, 504 insertions(+), 408 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b3c0f9cc..cb1a68f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,3 +54,78 @@ no_unknown_fields = [ "starknet-core/no_unknown_fields", "starknet-providers/no_unknown_fields", ] + +[workspace.lints] +rust.missing_debug_implementations = "warn" +rust.missing_docs = "allow" +rust.unreachable_pub = "allow" +rust.unused_must_use = "deny" +rust.rust_2018_idioms = { level = "deny", priority = -1 } +rustdoc.all = "warn" + +[workspace.lints.clippy] +# These are some of clippy's nursery (i.e., experimental) lints that we like. +# By default, nursery lints are allowed. Some of the lints below have made good +# suggestions which we fixed. The others didn't have any findings, so we can +# assume they don't have that many false positives. Let's enable them to +# prevent future problems. +branches_sharing_code = "warn" +clear_with_drain = "warn" +derive_partial_eq_without_eq = "warn" +empty_line_after_outer_attr = "warn" +equatable_if_let = "warn" +imprecise_flops = "warn" +iter_on_empty_collections = "warn" +iter_with_drain = "warn" +large_stack_frames = "warn" +manual_clamp = "warn" +mutex_integer = "warn" +needless_pass_by_ref_mut = "warn" +nonstandard_macro_braces = "warn" +or_fun_call = "warn" +path_buf_push_overwrite = "warn" +read_zero_byte_vec = "warn" +redundant_clone = "warn" +suboptimal_flops = "warn" +suspicious_operation_groupings = "warn" +trailing_empty_array = "warn" +trait_duplication_in_bounds = "warn" +transmute_undefined_repr = "warn" +trivial_regex = "warn" +tuple_array_conversions = "warn" +uninhabited_references = "warn" +unused_peekable = "warn" +unused_rounding = "warn" +useless_let_if_seq = "warn" +use_self = "warn" +missing_const_for_fn = "warn" +empty_line_after_doc_comments = "warn" +iter_on_single_items = "warn" +match_same_arms = "warn" +doc_markdown = "warn" +unnecessary_struct_initialization = "warn" +string_lit_as_bytes = "warn" +explicit_into_iter_loop = "warn" +explicit_iter_loop = "warn" +type_repetition_in_bounds = "allow" +manual_string_new = "warn" +naive_bytecount = "warn" +needless_bitwise_bool = "warn" +zero_sized_map_values = "warn" +single_char_pattern = "warn" +needless_continue = "warn" + +# These are nursery lints which have findings. Allow them for now. Some are not +# quite mature enough for use in our codebase and some we don't really want. +# Explicitly listing should make it easier to fix in the future. +as_ptr_cast_mut = "allow" +cognitive_complexity = "allow" +collection_is_never_read = "allow" +debug_assert_with_mut_call = "allow" +fallible_impl_from = "allow" +future_not_send = "allow" +needless_collect = "allow" +non_send_fields_in_send_ty = "allow" +redundant_pub_crate = "allow" +significant_drop_in_scrutinee = "allow" +significant_drop_tightening = "allow" diff --git a/starknet-accounts/Cargo.toml b/starknet-accounts/Cargo.toml index 6ad3ad82..442a53fe 100644 --- a/starknet-accounts/Cargo.toml +++ b/starknet-accounts/Cargo.toml @@ -27,3 +27,6 @@ serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0.96" tokio = { version = "1.27.0", features = ["full"] } url = "2.3.1" + +[lints] +workspace = true diff --git a/starknet-accounts/src/account/declaration.rs b/starknet-accounts/src/account/declaration.rs index 360dc924..d8d2de4e 100644 --- a/starknet-accounts/src/account/declaration.rs +++ b/starknet-accounts/src/account/declaration.rs @@ -52,7 +52,7 @@ const QUERY_VERSION_THREE: Felt = Felt::from_raw([ ]); impl<'a, A> DeclarationV2<'a, A> { - pub fn new( + pub const fn new( contract_class: Arc, compiled_class_hash: Felt, account: &'a A, @@ -88,8 +88,8 @@ impl<'a, A> DeclarationV2<'a, A> { } } - /// Calling this function after manually specifying `nonce` and `max_fee` turns [DeclarationV2] - /// into [PreparedDeclarationV2]. Returns `Err` if either field is `None`. + /// Calling this function after manually specifying `nonce` and `max_fee` turns [`DeclarationV2`] + /// into [`PreparedDeclarationV2`]. Returns `Err` if either field is `None`. pub fn prepared(self) -> Result, NotPreparedError> { let nonce = self.nonce.ok_or(NotPreparedError)?; let max_fee = self.max_fee.ok_or(NotPreparedError)?; @@ -275,7 +275,7 @@ where } impl<'a, A> DeclarationV3<'a, A> { - pub fn new( + pub const fn new( contract_class: Arc, compiled_class_hash: Felt, account: &'a A, @@ -328,7 +328,7 @@ impl<'a, A> DeclarationV3<'a, A> { } /// Calling this function after manually specifying `nonce`, `gas` and `gas_price` turns - /// [DeclarationV3] into [PreparedDeclarationV3]. Returns `Err` if any field is `None`. + /// [`DeclarationV3`] into [`PreparedDeclarationV3`]. Returns `Err` if any field is `None`. pub fn prepared(self) -> Result, NotPreparedError> { let nonce = self.nonce.ok_or(NotPreparedError)?; let gas = self.gas.ok_or(NotPreparedError)?; @@ -570,7 +570,7 @@ where } impl<'a, A> LegacyDeclaration<'a, A> { - pub fn new(contract_class: Arc, account: &'a A) -> Self { + pub const fn new(contract_class: Arc, account: &'a A) -> Self { Self { account, contract_class, @@ -602,7 +602,7 @@ impl<'a, A> LegacyDeclaration<'a, A> { } /// Calling this function after manually specifying `nonce` and `max_fee` turns - /// [LegacyDeclaration] into [PreparedLegacyDeclaration]. Returns `Err` if either field is + /// [`LegacyDeclaration`] into [`PreparedLegacyDeclaration`]. Returns `Err` if either field is /// `None`. pub fn prepared(self) -> Result, NotPreparedError> { let nonce = self.nonce.ok_or(NotPreparedError)?; @@ -809,15 +809,15 @@ impl RawDeclarationV2 { &self.contract_class } - pub fn compiled_class_hash(&self) -> Felt { + pub const fn compiled_class_hash(&self) -> Felt { self.compiled_class_hash } - pub fn nonce(&self) -> Felt { + pub const fn nonce(&self) -> Felt { self.nonce } - pub fn max_fee(&self) -> Felt { + pub const fn max_fee(&self) -> Felt { self.max_fee } } @@ -880,19 +880,19 @@ impl RawDeclarationV3 { &self.contract_class } - pub fn compiled_class_hash(&self) -> Felt { + pub const fn compiled_class_hash(&self) -> Felt { self.compiled_class_hash } - pub fn nonce(&self) -> Felt { + pub const fn nonce(&self) -> Felt { self.nonce } - pub fn gas(&self) -> u64 { + pub const fn gas(&self) -> u64 { self.gas } - pub fn gas_price(&self) -> u128 { + pub const fn gas_price(&self) -> u128 { self.gas_price } } @@ -924,11 +924,11 @@ impl RawLegacyDeclaration { &self.contract_class } - pub fn nonce(&self) -> Felt { + pub const fn nonce(&self) -> Felt { self.nonce } - pub fn max_fee(&self) -> Felt { + pub const fn max_fee(&self) -> Felt { self.max_fee } } diff --git a/starknet-accounts/src/account/execution.rs b/starknet-accounts/src/account/execution.rs index 99757da0..3e529a45 100644 --- a/starknet-accounts/src/account/execution.rs +++ b/starknet-accounts/src/account/execution.rs @@ -41,7 +41,7 @@ const QUERY_VERSION_THREE: Felt = Felt::from_raw([ ]); impl<'a, A> ExecutionV1<'a, A> { - pub fn new(calls: Vec, account: &'a A) -> Self { + pub const fn new(calls: Vec, account: &'a A) -> Self { Self { account, calls, @@ -72,8 +72,8 @@ impl<'a, A> ExecutionV1<'a, A> { } } - /// Calling this function after manually specifying `nonce` and `max_fee` turns [ExecutionV1] into - /// [PreparedExecutionV1]. Returns `Err` if either field is `None`. + /// Calling this function after manually specifying `nonce` and `max_fee` turns [`ExecutionV1`] into + /// [`PreparedExecutionV1`]. Returns `Err` if either field is `None`. pub fn prepared(self) -> Result, NotPreparedError> { let nonce = self.nonce.ok_or(NotPreparedError)?; let max_fee = self.max_fee.ok_or(NotPreparedError)?; @@ -90,7 +90,7 @@ impl<'a, A> ExecutionV1<'a, A> { } impl<'a, A> ExecutionV3<'a, A> { - pub fn new(calls: Vec, account: &'a A) -> Self { + pub const fn new(calls: Vec, account: &'a A) -> Self { Self { account, calls, @@ -138,7 +138,7 @@ impl<'a, A> ExecutionV3<'a, A> { } /// Calling this function after manually specifying `nonce`, `gas` and `gas_price` turns - /// [ExecutionV3] into [PreparedExecutionV3]. Returns `Err` if any field is `None`. + /// [`ExecutionV3`] into [`PreparedExecutionV3`]. Returns `Err` if any field is `None`. pub fn prepared(self) -> Result, NotPreparedError> { let nonce = self.nonce.ok_or(NotPreparedError)?; let gas = self.gas.ok_or(NotPreparedError)?; @@ -583,11 +583,11 @@ impl RawExecutionV1 { &self.calls } - pub fn nonce(&self) -> Felt { + pub const fn nonce(&self) -> Felt { self.nonce } - pub fn max_fee(&self) -> Felt { + pub const fn max_fee(&self) -> Felt { self.max_fee } } @@ -667,15 +667,15 @@ impl RawExecutionV3 { &self.calls } - pub fn nonce(&self) -> Felt { + pub const fn nonce(&self) -> Felt { self.nonce } - pub fn gas(&self) -> u64 { + pub const fn gas(&self) -> u64 { self.gas } - pub fn gas_price(&self) -> u128 { + pub const fn gas_price(&self) -> u128 { self.gas_price } } diff --git a/starknet-accounts/src/account/mod.rs b/starknet-accounts/src/account/mod.rs index 94c9031c..5bb2db3e 100644 --- a/starknet-accounts/src/account/mod.rs +++ b/starknet-accounts/src/account/mod.rs @@ -63,16 +63,16 @@ pub trait Account: ExecutionEncoder + Sized { /// estimation/simulation purposes. fn is_signer_interactive(&self) -> bool; - fn execute_v1(&self, calls: Vec) -> ExecutionV1 { + fn execute_v1(&self, calls: Vec) -> ExecutionV1<'_, Self> { ExecutionV1::new(calls, self) } - fn execute_v3(&self, calls: Vec) -> ExecutionV3 { + fn execute_v3(&self, calls: Vec) -> ExecutionV3<'_, Self> { ExecutionV3::new(calls, self) } #[deprecated = "use version specific variants (`execute_v1` & `execute_v3`) instead"] - fn execute(&self, calls: Vec) -> ExecutionV1 { + fn execute(&self, calls: Vec) -> ExecutionV1<'_, Self> { self.execute_v1(calls) } @@ -80,7 +80,7 @@ pub trait Account: ExecutionEncoder + Sized { &self, contract_class: Arc, compiled_class_hash: Felt, - ) -> DeclarationV2 { + ) -> DeclarationV2<'_, Self> { DeclarationV2::new(contract_class, compiled_class_hash, self) } @@ -88,7 +88,7 @@ pub trait Account: ExecutionEncoder + Sized { &self, contract_class: Arc, compiled_class_hash: Felt, - ) -> DeclarationV3 { + ) -> DeclarationV3<'_, Self> { DeclarationV3::new(contract_class, compiled_class_hash, self) } @@ -97,11 +97,14 @@ pub trait Account: ExecutionEncoder + Sized { &self, contract_class: Arc, compiled_class_hash: Felt, - ) -> DeclarationV2 { + ) -> DeclarationV2<'_, Self> { self.declare_v2(contract_class, compiled_class_hash) } - fn declare_legacy(&self, contract_class: Arc) -> LegacyDeclaration { + fn declare_legacy( + &self, + contract_class: Arc, + ) -> LegacyDeclaration<'_, Self> { LegacyDeclaration::new(contract_class, self) } } @@ -135,7 +138,7 @@ pub trait ConnectedAccount: Account { /// Abstraction over `INVOKE` transactions from accounts for invoking contracts. This struct uses /// v1 `INVOKE` transactions under the hood, and hence pays transaction fees in ETH. To use v3 -/// transactions for STRK fee payment, use [ExecutionV3] instead. +/// transactions for STRK fee payment, use [`ExecutionV3`] instead. /// /// This is an intermediate type allowing users to optionally specify `nonce` and/or `max_fee`. #[must_use] @@ -150,7 +153,7 @@ pub struct ExecutionV1<'a, A> { /// Abstraction over `INVOKE` transactions from accounts for invoking contracts. This struct uses /// v3 `INVOKE` transactions under the hood, and hence pays transaction fees in STRK. To use v1 -/// transactions for ETH fee payment, use [ExecutionV1] instead. +/// transactions for ETH fee payment, use [`ExecutionV1`] instead. /// /// This is an intermediate type allowing users to optionally specify `nonce`, `gas`, and/or /// `gas_price`. @@ -168,7 +171,7 @@ pub struct ExecutionV3<'a, A> { /// Abstraction over `DECLARE` transactions from accounts for invoking contracts. This struct uses /// v2 `DECLARE` transactions under the hood, and hence pays transaction fees in ETH. To use v3 -/// transactions for STRK fee payment, use [DeclarationV3] instead. +/// transactions for STRK fee payment, use [`DeclarationV3`] instead. /// /// An intermediate type allowing users to optionally specify `nonce` and/or `max_fee`. #[must_use] @@ -184,7 +187,7 @@ pub struct DeclarationV2<'a, A> { /// Abstraction over `DECLARE` transactions from accounts for invoking contracts. This struct uses /// v3 `DECLARE` transactions under the hood, and hence pays transaction fees in STRK. To use v2 -/// transactions for ETH fee payment, use [DeclarationV2] instead. +/// transactions for ETH fee payment, use [`DeclarationV2`] instead. /// /// This is an intermediate type allowing users to optionally specify `nonce`, `gas`, and/or /// `gas_price`. @@ -212,7 +215,7 @@ pub struct LegacyDeclaration<'a, A> { fee_estimate_multiplier: f64, } -/// [ExecutionV1] but with `nonce` and `max_fee` already determined. +/// [`ExecutionV1`] but with `nonce` and `max_fee` already determined. #[derive(Debug)] pub struct RawExecutionV1 { calls: Vec, @@ -220,7 +223,7 @@ pub struct RawExecutionV1 { max_fee: Felt, } -/// [ExecutionV3] but with `nonce`, `gas` and `gas_price` already determined. +/// [`ExecutionV3`] but with `nonce`, `gas` and `gas_price` already determined. #[derive(Debug)] pub struct RawExecutionV3 { calls: Vec, @@ -229,7 +232,7 @@ pub struct RawExecutionV3 { gas_price: u128, } -/// [DeclarationV2] but with `nonce` and `max_fee` already determined. +/// [`DeclarationV2`] but with `nonce` and `max_fee` already determined. #[derive(Debug)] pub struct RawDeclarationV2 { contract_class: Arc, @@ -238,7 +241,7 @@ pub struct RawDeclarationV2 { max_fee: Felt, } -/// [DeclarationV3] but with `nonce`, `gas` and `gas_price` already determined. +/// [`DeclarationV3`] but with `nonce`, `gas` and `gas_price` already determined. #[derive(Debug)] pub struct RawDeclarationV3 { contract_class: Arc, @@ -248,7 +251,7 @@ pub struct RawDeclarationV3 { gas_price: u128, } -/// [LegacyDeclaration] but with `nonce` and `max_fee` already determined. +/// [`LegacyDeclaration`] but with `nonce` and `max_fee` already determined. #[derive(Debug)] pub struct RawLegacyDeclaration { contract_class: Arc, @@ -256,35 +259,35 @@ pub struct RawLegacyDeclaration { max_fee: Felt, } -/// [RawExecutionV1] but with an account associated. +/// [`RawExecutionV1`] but with an account associated. #[derive(Debug)] pub struct PreparedExecutionV1<'a, A> { account: &'a A, inner: RawExecutionV1, } -/// [RawExecutionV3] but with an account associated. +/// [`RawExecutionV3`] but with an account associated. #[derive(Debug)] pub struct PreparedExecutionV3<'a, A> { account: &'a A, inner: RawExecutionV3, } -/// [RawDeclarationV2] but with an account associated. +/// [`RawDeclarationV2`] but with an account associated. #[derive(Debug)] pub struct PreparedDeclarationV2<'a, A> { account: &'a A, inner: RawDeclarationV2, } -/// [RawDeclarationV3] but with an account associated. +/// [`RawDeclarationV3`] but with an account associated. #[derive(Debug)] pub struct PreparedDeclarationV3<'a, A> { account: &'a A, inner: RawDeclarationV3, } -/// [RawLegacyDeclaration] but with an account associated. +/// [`RawLegacyDeclaration`] but with an account associated. #[derive(Debug)] pub struct PreparedLegacyDeclaration<'a, A> { account: &'a A, diff --git a/starknet-accounts/src/factory/argent.rs b/starknet-accounts/src/factory/argent.rs index 5bfa0476..a8cf6482 100644 --- a/starknet-accounts/src/factory/argent.rs +++ b/starknet-accounts/src/factory/argent.rs @@ -8,6 +8,7 @@ use starknet_core::types::{BlockId, BlockTag, Felt}; use starknet_providers::Provider; use starknet_signers::Signer; +#[derive(Debug)] pub struct ArgentAccountFactory { class_hash: Felt, chain_id: Felt, diff --git a/starknet-accounts/src/factory/mod.rs b/starknet-accounts/src/factory/mod.rs index 1dc3b773..17f3d2a2 100644 --- a/starknet-accounts/src/factory/mod.rs +++ b/starknet-accounts/src/factory/mod.rs @@ -18,7 +18,7 @@ use std::error::Error; pub mod argent; pub mod open_zeppelin; -/// Cairo string for "deploy_account" +/// Cairo string for `deploy_account` const PREFIX_DEPLOY_ACCOUNT: Felt = Felt::from_raw([ 461298303000467581, 18446744073709551615, @@ -42,7 +42,7 @@ const QUERY_VERSION_THREE: Felt = Felt::from_raw([ 18446744073700081569, ]); -/// Cairo string for "STARKNET_CONTRACT_ADDRESS" +/// Cairo string for `STARKNET_CONTRACT_ADDRESS` const PREFIX_CONTRACT_ADDRESS: Felt = Felt::from_raw([ 533439743893157637, 8635008616843941496, @@ -98,23 +98,23 @@ pub trait AccountFactory: Sized { query_only: bool, ) -> Result, Self::SignError>; - fn deploy_v1(&self, salt: Felt) -> AccountDeploymentV1 { + fn deploy_v1(&self, salt: Felt) -> AccountDeploymentV1<'_, Self> { AccountDeploymentV1::new(salt, self) } - fn deploy_v3(&self, salt: Felt) -> AccountDeploymentV3 { + fn deploy_v3(&self, salt: Felt) -> AccountDeploymentV3<'_, Self> { AccountDeploymentV3::new(salt, self) } #[deprecated = "use version specific variants (`deploy_v1` & `deploy_v3`) instead"] - fn deploy(&self, salt: Felt) -> AccountDeploymentV1 { + fn deploy(&self, salt: Felt) -> AccountDeploymentV1<'_, Self> { self.deploy_v1(salt) } } /// Abstraction over `DEPLOY_ACCOUNT` transactions for account contract deployment. This struct uses /// v1 `DEPLOY_ACCOUNT` transactions under the hood, and hence pays transaction fees in ETH. To use -/// v3 transactions for STRK fee payment, use [AccountDeploymentV3] instead. +/// v3 transactions for STRK fee payment, use [`AccountDeploymentV3`] instead. /// /// An intermediate type allowing users to optionally specify `nonce` and/or `max_fee`. #[must_use] @@ -131,7 +131,7 @@ pub struct AccountDeploymentV1<'f, F> { /// Abstraction over `DEPLOY_ACCOUNT` transactions for account contract deployment. This struct uses /// v3 `DEPLOY_ACCOUNT` transactions under the hood, and hence pays transaction fees in STRK. To use -/// v1 transactions for ETH fee payment, use [AccountDeploymentV1] instead. +/// v1 transactions for ETH fee payment, use [`AccountDeploymentV1`] instead. /// /// This is an intermediate type allowing users to optionally specify `nonce`, `gas`, and/or /// `gas_price`. @@ -149,7 +149,7 @@ pub struct AccountDeploymentV3<'f, F> { gas_price_estimate_multiplier: f64, } -/// [AccountDeploymentV1] but with `nonce` and `max_fee` already determined. +/// [`AccountDeploymentV1`] but with `nonce` and `max_fee` already determined. #[derive(Debug, Clone)] pub struct RawAccountDeploymentV1 { salt: Felt, @@ -157,7 +157,7 @@ pub struct RawAccountDeploymentV1 { max_fee: Felt, } -/// [AccountDeploymentV3] but with `nonce`, `gas` and `gas_price` already determined. +/// [`AccountDeploymentV3`] but with `nonce`, `gas` and `gas_price` already determined. #[derive(Debug, Clone)] pub struct RawAccountDeploymentV3 { salt: Felt, @@ -166,14 +166,14 @@ pub struct RawAccountDeploymentV3 { gas_price: u128, } -/// [RawAccountDeploymentV1] but with a factory associated. +/// [`RawAccountDeploymentV1`] but with a factory associated. #[derive(Debug)] pub struct PreparedAccountDeploymentV1<'f, F> { factory: &'f F, inner: RawAccountDeploymentV1, } -/// [RawAccountDeploymentV3] but with a factory associated. +/// [`RawAccountDeploymentV3`] but with a factory associated. #[derive(Debug)] pub struct PreparedAccountDeploymentV3<'f, F> { factory: &'f F, @@ -191,7 +191,7 @@ pub enum AccountFactoryError { } impl<'f, F> AccountDeploymentV1<'f, F> { - pub fn new(salt: Felt, factory: &'f F) -> Self { + pub const fn new(salt: Felt, factory: &'f F) -> Self { Self { factory, salt, @@ -201,21 +201,21 @@ impl<'f, F> AccountDeploymentV1<'f, F> { } } - pub fn nonce(self, nonce: Felt) -> Self { + pub const fn nonce(self, nonce: Felt) -> Self { Self { nonce: Some(nonce), ..self } } - pub fn max_fee(self, max_fee: Felt) -> Self { + pub const fn max_fee(self, max_fee: Felt) -> Self { Self { max_fee: Some(max_fee), ..self } } - pub fn fee_estimate_multiplier(self, fee_estimate_multiplier: f64) -> Self { + pub const fn fee_estimate_multiplier(self, fee_estimate_multiplier: f64) -> Self { Self { fee_estimate_multiplier, ..self @@ -223,7 +223,7 @@ impl<'f, F> AccountDeploymentV1<'f, F> { } /// Calling this function after manually specifying `nonce` and `max_fee` turns - /// [AccountDeploymentV1] into [PreparedAccountDeploymentV1]. Returns `Err` if either field is + /// [`AccountDeploymentV1`] into [`PreparedAccountDeploymentV1`]. Returns `Err` if either field is /// `None`. pub fn prepared(self) -> Result, NotPreparedError> { let nonce = self.nonce.ok_or(NotPreparedError)?; @@ -241,7 +241,7 @@ impl<'f, F> AccountDeploymentV1<'f, F> { } impl<'f, F> AccountDeploymentV3<'f, F> { - pub fn new(salt: Felt, factory: &'f F) -> Self { + pub const fn new(salt: Felt, factory: &'f F) -> Self { Self { factory, salt, @@ -253,35 +253,35 @@ impl<'f, F> AccountDeploymentV3<'f, F> { } } - pub fn nonce(self, nonce: Felt) -> Self { + pub const fn nonce(self, nonce: Felt) -> Self { Self { nonce: Some(nonce), ..self } } - pub fn gas(self, gas: u64) -> Self { + pub const fn gas(self, gas: u64) -> Self { Self { gas: Some(gas), ..self } } - pub fn gas_price(self, gas_price: u128) -> Self { + pub const fn gas_price(self, gas_price: u128) -> Self { Self { gas_price: Some(gas_price), ..self } } - pub fn gas_estimate_multiplier(self, gas_estimate_multiplier: f64) -> Self { + pub const fn gas_estimate_multiplier(self, gas_estimate_multiplier: f64) -> Self { Self { gas_estimate_multiplier, ..self } } - pub fn gas_price_estimate_multiplier(self, gas_price_estimate_multiplier: f64) -> Self { + pub const fn gas_price_estimate_multiplier(self, gas_price_estimate_multiplier: f64) -> Self { Self { gas_price_estimate_multiplier, ..self @@ -289,7 +289,7 @@ impl<'f, F> AccountDeploymentV3<'f, F> { } /// Calling this function after manually specifying `nonce` and `max_fee` turns - /// [AccountDeploymentV3] into [PreparedAccountDeploymentV3]. Returns `Err` if either field is + /// [`AccountDeploymentV3`] into [`PreparedAccountDeploymentV3`]. Returns `Err` if either field is /// `None`. pub fn prepared(self) -> Result, NotPreparedError> { let nonce = self.nonce.ok_or(NotPreparedError)?; @@ -760,39 +760,39 @@ where } impl RawAccountDeploymentV1 { - pub fn salt(&self) -> Felt { + pub const fn salt(&self) -> Felt { self.salt } - pub fn nonce(&self) -> Felt { + pub const fn nonce(&self) -> Felt { self.nonce } - pub fn max_fee(&self) -> Felt { + pub const fn max_fee(&self) -> Felt { self.max_fee } } impl RawAccountDeploymentV3 { - pub fn salt(&self) -> Felt { + pub const fn salt(&self) -> Felt { self.salt } - pub fn nonce(&self) -> Felt { + pub const fn nonce(&self) -> Felt { self.nonce } - pub fn gas(&self) -> u64 { + pub const fn gas(&self) -> u64 { self.gas } - pub fn gas_price(&self) -> u128 { + pub const fn gas_price(&self) -> u128 { self.gas_price } } impl<'f, F> PreparedAccountDeploymentV1<'f, F> { - pub fn from_raw(raw_deployment: RawAccountDeploymentV1, factory: &'f F) -> Self { + pub const fn from_raw(raw_deployment: RawAccountDeploymentV1, factory: &'f F) -> Self { Self { factory, inner: raw_deployment, @@ -801,7 +801,7 @@ impl<'f, F> PreparedAccountDeploymentV1<'f, F> { } impl<'f, F> PreparedAccountDeploymentV3<'f, F> { - pub fn from_raw(raw_deployment: RawAccountDeploymentV3, factory: &'f F) -> Self { + pub const fn from_raw(raw_deployment: RawAccountDeploymentV3, factory: &'f F) -> Self { Self { factory, inner: raw_deployment, diff --git a/starknet-accounts/src/factory/open_zeppelin.rs b/starknet-accounts/src/factory/open_zeppelin.rs index 3b23b16e..8fa95022 100644 --- a/starknet-accounts/src/factory/open_zeppelin.rs +++ b/starknet-accounts/src/factory/open_zeppelin.rs @@ -8,6 +8,7 @@ use starknet_core::types::{BlockId, BlockTag, Felt}; use starknet_providers::Provider; use starknet_signers::Signer; +#[derive(Debug)] pub struct OpenZeppelinAccountFactory { class_hash: Felt, chain_id: Felt, diff --git a/starknet-accounts/src/single_owner.rs b/starknet-accounts/src/single_owner.rs index 0677a8d8..4fc44ede 100644 --- a/starknet-accounts/src/single_owner.rs +++ b/starknet-accounts/src/single_owner.rs @@ -54,7 +54,7 @@ where /// * `address`: Account contract address. /// * `chain_id`: Network chain ID. /// * `encoding`: How `__execute__` calldata should be encoded. - pub fn new( + pub const fn new( provider: P, signer: S, address: Felt, @@ -187,13 +187,13 @@ where match self.encoding { ExecutionEncoding::Legacy => { let mut concated_calldata: Vec = vec![]; - for call in calls.iter() { + for call in calls { execute_calldata.push(call.to); // to execute_calldata.push(call.selector); // selector execute_calldata.push(concated_calldata.len().into()); // data_offset execute_calldata.push(call.calldata.len().into()); // data_len - for item in call.calldata.iter() { + for item in &call.calldata { concated_calldata.push(*item); } } @@ -202,7 +202,7 @@ where execute_calldata.extend_from_slice(&concated_calldata); } ExecutionEncoding::New => { - for call in calls.iter() { + for call in calls { execute_calldata.push(call.to); // to execute_calldata.push(call.selector); // selector diff --git a/starknet-accounts/tests/single_owner_account.rs b/starknet-accounts/tests/single_owner_account.rs index c779c491..46d895f4 100644 --- a/starknet-accounts/tests/single_owner_account.rs +++ b/starknet-accounts/tests/single_owner_account.rs @@ -32,7 +32,7 @@ fn create_sequencer_client() -> SequencerGatewayProvider { fn create_jsonrpc_client() -> JsonRpcClient { let rpc_url = std::env::var("STARKNET_RPC") - .unwrap_or("https://juno.rpc.sepolia.starknet.rs/rpc/v0_7".into()); + .unwrap_or_else(|_| "https://juno.rpc.sepolia.starknet.rs/rpc/v0_7".into()); JsonRpcClient::new(HttpTransport::new(url::Url::parse(&rpc_url).unwrap())) } diff --git a/starknet-contract/Cargo.toml b/starknet-contract/Cargo.toml index 1c44ac28..f6a89f3c 100644 --- a/starknet-contract/Cargo.toml +++ b/starknet-contract/Cargo.toml @@ -27,3 +27,6 @@ rand = { version = "0.8.5", features=["std_rng"] } starknet-signers = { version = "0.9.0", path = "../starknet-signers" } tokio = { version = "1.27.0", features = ["full"] } url = "2.3.1" + +[lints] +workspace = true diff --git a/starknet-contract/src/factory.rs b/starknet-contract/src/factory.rs index 0cbd6065..299ff0f1 100644 --- a/starknet-contract/src/factory.rs +++ b/starknet-contract/src/factory.rs @@ -20,6 +20,7 @@ const SELECTOR_DEPLOYCONTRACT: Felt = Felt::from_raw([ 18249998464715511309, ]); +#[derive(Debug)] pub struct ContractFactory { class_hash: Felt, udc_address: Felt, @@ -28,8 +29,9 @@ pub struct ContractFactory { /// Abstraction over contract deployment via the UDC. This type uses `INVOKE` v1 transactions under /// the hood, and hence pays transaction fees in ETH. To use v3 transactions for STRK fee payment, -/// use [DeploymentV3] instead. +/// use [`DeploymentV3`] instead. #[must_use] +#[derive(Debug)] pub struct DeploymentV1<'f, A> { factory: &'f ContractFactory, constructor_calldata: Vec, @@ -43,8 +45,9 @@ pub struct DeploymentV1<'f, A> { /// Abstraction over contract deployment via the UDC. This type uses `INVOKE` v3 transactions under /// the hood, and hence pays transaction fees in STRK. To use v1 transactions for ETH fee payment, -/// use [DeploymentV1] instead. +/// use [`DeploymentV1`] instead. #[must_use] +#[derive(Debug)] pub struct DeploymentV3<'f, A> { factory: &'f ContractFactory, constructor_calldata: Vec, @@ -59,11 +62,11 @@ pub struct DeploymentV3<'f, A> { } impl ContractFactory { - pub fn new(class_hash: Felt, account: A) -> Self { + pub const fn new(class_hash: Felt, account: A) -> Self { Self::new_with_udc(class_hash, account, UDC_ADDRESS) } - pub fn new_with_udc(class_hash: Felt, account: A, udc_address: Felt) -> Self { + pub const fn new_with_udc(class_hash: Felt, account: A, udc_address: Felt) -> Self { Self { class_hash, udc_address, @@ -76,12 +79,12 @@ impl ContractFactory where A: Account, { - pub fn deploy_v1( + pub const fn deploy_v1( &self, constructor_calldata: Vec, salt: Felt, unique: bool, - ) -> DeploymentV1 { + ) -> DeploymentV1<'_, A> { DeploymentV1 { factory: self, constructor_calldata, @@ -93,12 +96,12 @@ where } } - pub fn deploy_v3( + pub const fn deploy_v3( &self, constructor_calldata: Vec, salt: Felt, unique: bool, - ) -> DeploymentV3 { + ) -> DeploymentV3<'_, A> { DeploymentV3 { factory: self, constructor_calldata, @@ -113,12 +116,12 @@ where } #[deprecated = "use version specific variants (`deploy_v1` & `deploy_v3`) instead"] - pub fn deploy( + pub const fn deploy( &self, constructor_calldata: Vec, salt: Felt, unique: bool, - ) -> DeploymentV1 { + ) -> DeploymentV1<'_, A> { self.deploy_v1(constructor_calldata, salt, unique) } } @@ -232,7 +235,7 @@ where A: ConnectedAccount + Sync, { pub async fn estimate_fee(&self) -> Result> { - let execution: ExecutionV1 = self.into(); + let execution: ExecutionV1<'_, A> = self.into(); execution.estimate_fee().await } @@ -241,12 +244,12 @@ where skip_validate: bool, skip_fee_charge: bool, ) -> Result> { - let execution: ExecutionV1 = self.into(); + let execution: ExecutionV1<'_, A> = self.into(); execution.simulate(skip_validate, skip_fee_charge).await } pub async fn send(&self) -> Result> { - let execution: ExecutionV1 = self.into(); + let execution: ExecutionV1<'_, A> = self.into(); execution.send().await } } @@ -256,7 +259,7 @@ where A: ConnectedAccount + Sync, { pub async fn estimate_fee(&self) -> Result> { - let execution: ExecutionV3 = self.into(); + let execution: ExecutionV3<'_, A> = self.into(); execution.estimate_fee().await } @@ -265,12 +268,12 @@ where skip_validate: bool, skip_fee_charge: bool, ) -> Result> { - let execution: ExecutionV3 = self.into(); + let execution: ExecutionV3<'_, A> = self.into(); execution.simulate(skip_validate, skip_fee_charge).await } pub async fn send(&self) -> Result> { - let execution: ExecutionV3 = self.into(); + let execution: ExecutionV3<'_, A> = self.into(); execution.send().await } } diff --git a/starknet-contract/tests/contract_deployment.rs b/starknet-contract/tests/contract_deployment.rs index 14ab3f26..eff7f2cc 100644 --- a/starknet-contract/tests/contract_deployment.rs +++ b/starknet-contract/tests/contract_deployment.rs @@ -17,7 +17,7 @@ const CHAIN_ID: Felt = Felt::from_raw([ #[tokio::test] async fn can_deploy_contract_to_alpha_sepolia_with_invoke_v1() { let rpc_url = std::env::var("STARKNET_RPC") - .unwrap_or("https://pathfinder.rpc.sepolia.starknet.rs/rpc/v0_6".into()); + .unwrap_or_else(|_| "https://pathfinder.rpc.sepolia.starknet.rs/rpc/v0_6".into()); let provider = JsonRpcClient::new(HttpTransport::new(Url::parse(&rpc_url).unwrap())); let signer = LocalWallet::from(SigningKey::from_secret_scalar( Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), @@ -55,7 +55,7 @@ async fn can_deploy_contract_to_alpha_sepolia_with_invoke_v1() { #[tokio::test] async fn can_deploy_contract_to_alpha_sepolia_with_invoke_v3() { let rpc_url = std::env::var("STARKNET_RPC") - .unwrap_or("https://pathfinder.rpc.sepolia.starknet.rs/rpc/v0_6".into()); + .unwrap_or_else(|_| "https://pathfinder.rpc.sepolia.starknet.rs/rpc/v0_6".into()); let provider = JsonRpcClient::new(HttpTransport::new(Url::parse(&rpc_url).unwrap())); let signer = LocalWallet::from(SigningKey::from_secret_scalar( Felt::from_hex("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), diff --git a/starknet-core/Cargo.toml b/starknet-core/Cargo.toml index a035ded2..363ca0c7 100644 --- a/starknet-core/Cargo.toml +++ b/starknet-core/Cargo.toml @@ -50,3 +50,6 @@ harness = false [[bench]] name = "sierra_class_hash" harness = false + +[lints] +workspace = true diff --git a/starknet-core/src/chain_id.rs b/starknet-core/src/chain_id.rs index cbb430fa..715dc437 100644 --- a/starknet-core/src/chain_id.rs +++ b/starknet-core/src/chain_id.rs @@ -45,9 +45,7 @@ mod test { ("SN_GOERLI", TESTNET), ("SN_GOERLI2", TESTNET2), ("SN_SEPOLIA", SEPOLIA), - ] - .into_iter() - { + ] { assert_eq!(cairo_short_string_to_felt(text).unwrap(), felt); } } diff --git a/starknet-core/src/serde/byte_array.rs b/starknet-core/src/serde/byte_array.rs index 9d171396..0d2bb46e 100644 --- a/starknet-core/src/serde/byte_array.rs +++ b/starknet-core/src/serde/byte_array.rs @@ -24,7 +24,7 @@ pub mod base64 { impl<'de> Visitor<'de> for Base64Visitor { type Value = Vec; - fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { + fn expecting(&self, formatter: &mut Formatter<'_>) -> alloc::fmt::Result { write!(formatter, "string") } diff --git a/starknet-core/src/serde/num_hex.rs b/starknet-core/src/serde/num_hex.rs index 6268fb1e..f285a18a 100644 --- a/starknet-core/src/serde/num_hex.rs +++ b/starknet-core/src/serde/num_hex.rs @@ -30,7 +30,7 @@ pub mod u64 { impl<'de> Visitor<'de> for NumHexVisitor { type Value = u64; - fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { + fn expecting(&self, formatter: &mut Formatter<'_>) -> alloc::fmt::Result { write!(formatter, "string, or an array of u8") } diff --git a/starknet-core/src/serde/unsigned_field_element.rs b/starknet-core/src/serde/unsigned_field_element.rs index f443797a..87f311cb 100644 --- a/starknet-core/src/serde/unsigned_field_element.rs +++ b/starknet-core/src/serde/unsigned_field_element.rs @@ -12,10 +12,13 @@ use starknet_types_core::felt::Felt; const PRIME: U256 = U256::from_be_hex("0800000000000011000000000000000000000000000000000000000000000001"); +#[derive(Debug)] pub struct UfeHex; +#[derive(Debug)] pub struct UfeHexOption; +#[derive(Debug)] pub struct UfePendingBlockHash; struct UfeHexVisitor; @@ -51,7 +54,7 @@ impl<'de> DeserializeAs<'de, Felt> for UfeHex { impl<'de> Visitor<'de> for UfeHexVisitor { type Value = Felt; - fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { + fn expecting(&self, formatter: &mut Formatter<'_>) -> alloc::fmt::Result { write!(formatter, "a hex string, or an array of u8") } @@ -108,7 +111,7 @@ impl<'de> DeserializeAs<'de, Option> for UfeHexOption { impl<'de> Visitor<'de> for UfeHexOptionVisitor { type Value = Option; - fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { + fn expecting(&self, formatter: &mut Formatter<'_>) -> alloc::fmt::Result { write!(formatter, "string") } @@ -176,7 +179,7 @@ impl<'de> DeserializeAs<'de, Option> for UfePendingBlockHash { impl<'de> Visitor<'de> for UfePendingBlockHashVisitor { type Value = Option; - fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { + fn expecting(&self, formatter: &mut Formatter<'_>) -> alloc::fmt::Result { write!(formatter, "string") } diff --git a/starknet-core/src/types/codegen.rs b/starknet-core/src/types/codegen.rs index 46e11560..2d7e0d02 100644 --- a/starknet-core/src/types/codegen.rs +++ b/starknet-core/src/types/codegen.rs @@ -3,7 +3,7 @@ // https://github.com/xJonathanLEI/starknet-jsonrpc-codegen // Code generated with version: -// https://github.com/xJonathanLEI/starknet-jsonrpc-codegen#4118b48cc450a8ff558c2ac480aa12bf5efdd3bd +// https://github.com/xJonathanLEI/starknet-jsonrpc-codegen#fbd3aed2a08d6b29328e87ee0bbfb7e80f7051b0 // These types are ignored from code generation. Implement them manually: // - `RECEIPT_BLOCK` @@ -24,6 +24,9 @@ // - `TXN` // - `TXN_RECEIPT` +#![allow(clippy::doc_markdown)] +#![allow(clippy::missing_const_for_fn)] + use alloc::{format, string::*, vec::*}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; diff --git a/starknet-core/src/types/contract/legacy.rs b/starknet-core/src/types/contract/legacy.rs index 83294a82..3803a218 100644 --- a/starknet-core/src/types/contract/legacy.rs +++ b/starknet-core/src/types/contract/legacy.rs @@ -361,26 +361,26 @@ impl<'de> Deserialize<'de> for RawLegacyAbiEntry { let temp_value = serde_json::Value::deserialize(deserializer)?; match &temp_value["type"] { serde_json::Value::String(type_str) => match &type_str[..] { - "constructor" => Ok(RawLegacyAbiEntry::Constructor( + "constructor" => Ok(Self::Constructor( RawLegacyConstructor::deserialize(temp_value).map_err(|err| { DeError::custom(format!("invalid constructor variant: {err}")) })?, )), - "function" => Ok(RawLegacyAbiEntry::Function( + "function" => Ok(Self::Function( RawLegacyFunction::deserialize(temp_value).map_err(|err| { DeError::custom(format!("invalid function variant: {err}")) })?, )), - "struct" => Ok(RawLegacyAbiEntry::Struct( + "struct" => Ok(Self::Struct( RawLegacyStruct::deserialize(temp_value) .map_err(|err| DeError::custom(format!("invalid struct variant: {err}")))?, )), - "l1_handler" => Ok(RawLegacyAbiEntry::L1Handler( + "l1_handler" => Ok(Self::L1Handler( RawLegacyL1Handler::deserialize(temp_value).map_err(|err| { DeError::custom(format!("invalid l1_handler variant: {err}")) })?, )), - "event" => Ok(RawLegacyAbiEntry::Event( + "event" => Ok(Self::Event( RawLegacyEvent::deserialize(temp_value) .map_err(|err| DeError::custom(format!("invalid event variant: {err}")))?, )), @@ -402,7 +402,7 @@ impl LegacyContractClass { // Hashes external entry points elements.push({ let mut buffer = Vec::new(); - for entrypoint in self.entry_points_by_type.external.iter() { + for entrypoint in &self.entry_points_by_type.external { buffer.push(entrypoint.selector); buffer.push(entrypoint.offset.into()); } @@ -412,7 +412,7 @@ impl LegacyContractClass { // Hashes L1 handler entry points elements.push({ let mut buffer = Vec::new(); - for entrypoint in self.entry_points_by_type.l1_handler.iter() { + for entrypoint in &self.entry_points_by_type.l1_handler { buffer.push(entrypoint.selector); buffer.push(entrypoint.offset.into()); } @@ -422,7 +422,7 @@ impl LegacyContractClass { // Hashes constructor entry points elements.push({ let mut buffer = Vec::new(); - for entrypoint in self.entry_points_by_type.constructor.iter() { + for entrypoint in &self.entry_points_by_type.constructor { buffer.push(entrypoint.selector); buffer.push(entrypoint.offset.into()); } @@ -853,9 +853,7 @@ mod tests { include_str!( "../../../test-data/contracts/cairo0/artifacts/pre-0.11.0/event_example.txt" ), - ] - .into_iter() - { + ] { serde_json::from_str::(raw_artifact).unwrap(); } } @@ -893,7 +891,6 @@ mod tests { ), ), ] - .into_iter() { let artifact = serde_json::from_str::(raw_artifact).unwrap(); let computed_hash = artifact.class_hash().unwrap(); @@ -938,7 +935,6 @@ mod tests { ), ), ] - .into_iter() { let artifact = serde_json::from_str::(raw_artifact).unwrap(); let computed_hash = artifact.hinted_class_hash().unwrap(); diff --git a/starknet-core/src/types/contract/mod.rs b/starknet-core/src/types/contract/mod.rs index 24046f9b..ba1b17ba 100644 --- a/starknet-core/src/types/contract/mod.rs +++ b/starknet-core/src/types/contract/mod.rs @@ -16,7 +16,7 @@ use crate::{ /// Module containing types related to artifacts of contracts compiled with a Cairo 0.x compiler. pub mod legacy; -/// Cairo string for "CONTRACT_CLASS_V0.1.0" +/// Cairo string for `CONTRACT_CLASS_V0.1.0` const PREFIX_CONTRACT_CLASS_V0_1_0: Felt = Felt::from_raw([ 37302452645455172, 18446734822722598327, @@ -24,7 +24,7 @@ const PREFIX_CONTRACT_CLASS_V0_1_0: Felt = Felt::from_raw([ 5800711240972404213, ]); -/// Cairo string for "COMPILED_CLASS_V1" +/// Cairo string for `COMPILED_CLASS_V1` const PREFIX_COMPILED_CLASS_V1: Felt = Felt::from_raw([ 324306817650036332, 18446744073709549462, @@ -278,7 +278,7 @@ struct BytecodeSegmentedNode { /// Internal structure used for post-Sierra-1.5.0 CASM hash calculation. /// -/// Represents a child of [BytecodeSegmentedNode]. +/// Represents a child of [`BytecodeSegmentedNode`]. struct BytecodeSegment { segment_length: u64, #[allow(unused)] @@ -545,12 +545,12 @@ impl CompiledClass { ) -> Result { let mut hasher = PoseidonHasher::new(); - for entry in entrypoints.iter() { + for entry in entrypoints { hasher.update(entry.selector); hasher.update(entry.offset.into()); let mut builtin_hasher = PoseidonHasher::new(); - for builtin in entry.builtins.iter() { + for builtin in &entry.builtins { builtin_hasher.update(cairo_short_string_to_felt(builtin)?) } @@ -594,7 +594,7 @@ impl CompiledClass { let mut res = Vec::new(); let mut total_len = 0; - for item in bytecode_segment_lengths.iter() { + for item in bytecode_segment_lengths { let visited_pc_before = if !visited_pcs.is_empty() { Some(visited_pcs[visited_pcs.len() - 1]) } else { @@ -666,7 +666,7 @@ impl BytecodeLeaf { impl BytecodeSegmentedNode { fn hash(&self) -> Felt { let mut hasher = PoseidonHasher::new(); - for node in self.segments.iter() { + for node in &self.segments { hasher.update(node.segment_length.into()); hasher.update(node.inner_structure.hash()); } @@ -761,7 +761,7 @@ impl Serialize for TypedAbiEvent { } match self { - TypedAbiEvent::Struct(inner) => StructRef::serialize( + Self::Struct(inner) => StructRef::serialize( &StructRef { name: &inner.name, kind: "struct", @@ -769,7 +769,7 @@ impl Serialize for TypedAbiEvent { }, serializer, ), - TypedAbiEvent::Enum(inner) => EnumRef::serialize( + Self::Enum(inner) => EnumRef::serialize( &EnumRef { name: &inner.name, kind: "enum", @@ -790,7 +790,7 @@ impl Serialize for IntOrList { Self::Int(int) => serializer.serialize_u64(*int), Self::List(list) => { let mut seq = serializer.serialize_seq(Some(list.len()))?; - for item in list.iter() { + for item in list { seq.serialize_element(item)?; } seq.end() @@ -802,7 +802,7 @@ impl Serialize for IntOrList { impl<'de> Visitor<'de> for IntOrListVisitor { type Value = IntOrList; - fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(formatter, "number or list") } @@ -837,7 +837,7 @@ impl<'de> Deserialize<'de> for IntOrList { fn hash_sierra_entrypoints(entrypoints: &[SierraEntryPoint]) -> Felt { let mut hasher = PoseidonHasher::new(); - for entry in entrypoints.iter() { + for entry in entrypoints { hasher.update(entry.selector); hasher.update(entry.function_idx.into()); } @@ -864,9 +864,7 @@ mod tests { include_str!("../../../test-data/contracts/cairo2/artifacts/abi_types_sierra.txt"), include_str!("../../../test-data/contracts/cairo2/artifacts/erc20_sierra.txt"), include_str!("../../../test-data/contracts/cairo2.6/artifacts/erc20_sierra.txt"), - ] - .into_iter() - { + ] { match serde_json::from_str::(raw_artifact) { Ok(ContractArtifact::SierraClass(_)) => {} _ => panic!("Unexpected result"), @@ -883,9 +881,7 @@ mod tests { include_str!("../../../test-data/contracts/cairo2/artifacts/abi_types_compiled.txt"), include_str!("../../../test-data/contracts/cairo2/artifacts/erc20_compiled.txt"), include_str!("../../../test-data/contracts/cairo2.6/artifacts/erc20_compiled.txt"), - ] - .into_iter() - { + ] { match serde_json::from_str::(raw_artifact) { Ok(ContractArtifact::CompiledClass(_)) => {} _ => panic!("Unexpected result"), @@ -924,9 +920,7 @@ mod tests { include_str!("../../../test-data/contracts/cairo2/artifacts/abi_types_sierra.txt"), include_str!("../../../test-data/contracts/cairo2/artifacts/abi_types.hashes.json"), ), - ] - .into_iter() - { + ] { let sierra_class = serde_json::from_str::(raw_artifact).unwrap(); let computed_hash = sierra_class.class_hash().unwrap(); @@ -965,9 +959,7 @@ mod tests { include_str!("../../../test-data/contracts/cairo2.6/artifacts/erc20_compiled.txt"), include_str!("../../../test-data/contracts/cairo2.6/artifacts/erc20.hashes.json"), ), - ] - .into_iter() - { + ] { let compiled_class = serde_json::from_str::(raw_artifact).unwrap(); let computed_hash = compiled_class.class_hash().unwrap(); diff --git a/starknet-core/src/types/conversions.rs b/starknet-core/src/types/conversions.rs index 38e7aa5f..a4a9ba1d 100644 --- a/starknet-core/src/types/conversions.rs +++ b/starknet-core/src/types/conversions.rs @@ -10,33 +10,29 @@ impl From for RawLegacyAbiEntry { fn from(value: LegacyContractAbiEntry) -> Self { match value { LegacyContractAbiEntry::Function(inner) => match inner.r#type { - LegacyFunctionAbiType::Function => RawLegacyAbiEntry::Function(RawLegacyFunction { + LegacyFunctionAbiType::Function => Self::Function(RawLegacyFunction { inputs: inner.inputs, name: inner.name, outputs: inner.outputs, state_mutability: inner.state_mutability, }), - LegacyFunctionAbiType::L1Handler => { - RawLegacyAbiEntry::L1Handler(RawLegacyL1Handler { - inputs: inner.inputs, - name: inner.name, - outputs: inner.outputs, - }) - } - LegacyFunctionAbiType::Constructor => { - RawLegacyAbiEntry::Constructor(RawLegacyConstructor { - inputs: inner.inputs, - name: inner.name, - outputs: inner.outputs, - }) - } + LegacyFunctionAbiType::L1Handler => Self::L1Handler(RawLegacyL1Handler { + inputs: inner.inputs, + name: inner.name, + outputs: inner.outputs, + }), + LegacyFunctionAbiType::Constructor => Self::Constructor(RawLegacyConstructor { + inputs: inner.inputs, + name: inner.name, + outputs: inner.outputs, + }), }, - LegacyContractAbiEntry::Event(inner) => RawLegacyAbiEntry::Event(RawLegacyEvent { + LegacyContractAbiEntry::Event(inner) => Self::Event(RawLegacyEvent { data: inner.data, keys: inner.keys, name: inner.name, }), - LegacyContractAbiEntry::Struct(inner) => RawLegacyAbiEntry::Struct(RawLegacyStruct { + LegacyContractAbiEntry::Struct(inner) => Self::Struct(RawLegacyStruct { members: inner .members .into_iter() diff --git a/starknet-core/src/types/eth_address.rs b/starknet-core/src/types/eth_address.rs index dfc3028e..5bfa95bd 100644 --- a/starknet-core/src/types/eth_address.rs +++ b/starknet-core/src/types/eth_address.rs @@ -83,7 +83,7 @@ impl EthAddress { felt.try_into() } - pub fn as_bytes(&self) -> &[u8; 20] { + pub const fn as_bytes(&self) -> &[u8; 20] { &self.inner } } @@ -109,7 +109,7 @@ impl<'de> Deserialize<'de> for EthAddress { impl<'de> Visitor<'de> for EthAddressVisitor { type Value = EthAddress; - fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { + fn expecting(&self, formatter: &mut Formatter<'_>) -> alloc::fmt::Result { write!(formatter, "string") } @@ -169,7 +169,7 @@ impl TryFrom<&Felt> for EthAddress { impl From for Felt { fn from(value: EthAddress) -> Self { // Safe to unwrap here as the value is never out of range - Felt::from_bytes_be_slice(&value.inner) + Self::from_bytes_be_slice(&value.inner) } } diff --git a/starknet-core/src/types/execution_result.rs b/starknet-core/src/types/execution_result.rs index 2a757531..b0d56a1c 100644 --- a/starknet-core/src/types/execution_result.rs +++ b/starknet-core/src/types/execution_result.rs @@ -12,10 +12,10 @@ pub enum ExecutionResult { } impl ExecutionResult { - pub fn status(&self) -> TransactionExecutionStatus { + pub const fn status(&self) -> TransactionExecutionStatus { match self { - ExecutionResult::Succeeded => TransactionExecutionStatus::Succeeded, - ExecutionResult::Reverted { .. } => TransactionExecutionStatus::Reverted, + Self::Succeeded => TransactionExecutionStatus::Succeeded, + Self::Reverted { .. } => TransactionExecutionStatus::Reverted, } } @@ -25,8 +25,8 @@ impl ExecutionResult { /// variant. pub fn revert_reason(&self) -> Option<&str> { match self { - ExecutionResult::Succeeded => None, - ExecutionResult::Reverted { reason } => Some(reason), + Self::Succeeded => None, + Self::Reverted { reason } => Some(reason), } } } diff --git a/starknet-core/src/types/hash_256.rs b/starknet-core/src/types/hash_256.rs index ec0bb839..b6ad9061 100644 --- a/starknet-core/src/types/hash_256.rs +++ b/starknet-core/src/types/hash_256.rs @@ -68,7 +68,7 @@ impl Hash256 { felt.into() } - pub fn as_bytes(&self) -> &[u8; HASH_256_BYTE_COUNT] { + pub const fn as_bytes(&self) -> &[u8; HASH_256_BYTE_COUNT] { &self.inner } } @@ -102,7 +102,7 @@ impl<'de> Deserialize<'de> for Hash256 { impl<'de> Visitor<'de> for Hash256Visitor { type Value = Hash256; - fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { + fn expecting(&self, formatter: &mut Formatter<'_>) -> alloc::fmt::Result { write!(formatter, "string, or an array of u8") } @@ -186,7 +186,7 @@ impl TryFrom<&Hash256> for Felt { type Error = ToFieldElementError; fn try_from(value: &Hash256) -> Result { - Ok(Felt::from_bytes_be(&value.inner)) + Ok(Self::from_bytes_be(&value.inner)) } } @@ -212,7 +212,7 @@ mod tests { "25c5b1592b1743b62d7fabd4373d98219c2ff3750f49ec0608a8355fa3bb060f5", ]; - for item in test_data.into_iter() { + for item in test_data { match Hash256::from_hex(item) { Err(FromHexError::UnexpectedLength) => {} _ => panic!("Unexpected test result"), @@ -230,7 +230,7 @@ mod tests { "0x?5c5b1592b1743b62d7fabd4373d98219c2f63750f49ec0608a8355fa3bb060", ]; - for item in test_data.into_iter() { + for item in test_data { match Hash256::from_hex(item) { Err(FromHexError::InvalidHexString) => {} _ => panic!("Unexpected test result"), diff --git a/starknet-core/src/types/mod.rs b/starknet-core/src/types/mod.rs index 16614753..0d5321f8 100644 --- a/starknet-core/src/types/mod.rs +++ b/starknet-core/src/types/mod.rs @@ -336,7 +336,7 @@ pub enum ExecuteInvocation { mod errors { use core::fmt::{Display, Formatter, Result}; - #[derive(Debug, PartialEq)] + #[derive(Debug, PartialEq, Eq)] pub enum ParseMsgToL2Error { EmptyCalldata, FromAddressOutOfRange, @@ -366,15 +366,15 @@ pub use errors::ParseMsgToL2Error; impl MaybePendingBlockWithTxHashes { pub fn transactions(&self) -> &[Felt] { match self { - MaybePendingBlockWithTxHashes::Block(block) => &block.transactions, - MaybePendingBlockWithTxHashes::PendingBlock(block) => &block.transactions, + Self::Block(block) => &block.transactions, + Self::PendingBlock(block) => &block.transactions, } } - pub fn l1_gas_price(&self) -> &ResourcePrice { + pub const fn l1_gas_price(&self) -> &ResourcePrice { match self { - MaybePendingBlockWithTxHashes::Block(block) => &block.l1_gas_price, - MaybePendingBlockWithTxHashes::PendingBlock(block) => &block.l1_gas_price, + Self::Block(block) => &block.l1_gas_price, + Self::PendingBlock(block) => &block.l1_gas_price, } } } @@ -382,15 +382,15 @@ impl MaybePendingBlockWithTxHashes { impl MaybePendingBlockWithTxs { pub fn transactions(&self) -> &[Transaction] { match self { - MaybePendingBlockWithTxs::Block(block) => &block.transactions, - MaybePendingBlockWithTxs::PendingBlock(block) => &block.transactions, + Self::Block(block) => &block.transactions, + Self::PendingBlock(block) => &block.transactions, } } - pub fn l1_gas_price(&self) -> &ResourcePrice { + pub const fn l1_gas_price(&self) -> &ResourcePrice { match self { - MaybePendingBlockWithTxs::Block(block) => &block.l1_gas_price, - MaybePendingBlockWithTxs::PendingBlock(block) => &block.l1_gas_price, + Self::Block(block) => &block.l1_gas_price, + Self::PendingBlock(block) => &block.l1_gas_price, } } } @@ -398,100 +398,100 @@ impl MaybePendingBlockWithTxs { impl MaybePendingBlockWithReceipts { pub fn transactions(&self) -> &[TransactionWithReceipt] { match self { - MaybePendingBlockWithReceipts::Block(block) => &block.transactions, - MaybePendingBlockWithReceipts::PendingBlock(block) => &block.transactions, + Self::Block(block) => &block.transactions, + Self::PendingBlock(block) => &block.transactions, } } - pub fn l1_gas_price(&self) -> &ResourcePrice { + pub const fn l1_gas_price(&self) -> &ResourcePrice { match self { - MaybePendingBlockWithReceipts::Block(block) => &block.l1_gas_price, - MaybePendingBlockWithReceipts::PendingBlock(block) => &block.l1_gas_price, + Self::Block(block) => &block.l1_gas_price, + Self::PendingBlock(block) => &block.l1_gas_price, } } } impl TransactionStatus { - pub fn finality_status(&self) -> SequencerTransactionStatus { + pub const fn finality_status(&self) -> SequencerTransactionStatus { match self { - TransactionStatus::Received => SequencerTransactionStatus::Received, - TransactionStatus::Rejected => SequencerTransactionStatus::Rejected, - TransactionStatus::AcceptedOnL2(_) => SequencerTransactionStatus::AcceptedOnL2, - TransactionStatus::AcceptedOnL1(_) => SequencerTransactionStatus::AcceptedOnL1, + Self::Received => SequencerTransactionStatus::Received, + Self::Rejected => SequencerTransactionStatus::Rejected, + Self::AcceptedOnL2(_) => SequencerTransactionStatus::AcceptedOnL2, + Self::AcceptedOnL1(_) => SequencerTransactionStatus::AcceptedOnL1, } } } impl Transaction { - pub fn transaction_hash(&self) -> &Felt { + pub const fn transaction_hash(&self) -> &Felt { match self { - Transaction::Invoke(tx) => tx.transaction_hash(), - Transaction::L1Handler(tx) => &tx.transaction_hash, - Transaction::Declare(tx) => tx.transaction_hash(), - Transaction::Deploy(tx) => &tx.transaction_hash, - Transaction::DeployAccount(tx) => tx.transaction_hash(), + Self::Invoke(tx) => tx.transaction_hash(), + Self::L1Handler(tx) => &tx.transaction_hash, + Self::Declare(tx) => tx.transaction_hash(), + Self::Deploy(tx) => &tx.transaction_hash, + Self::DeployAccount(tx) => tx.transaction_hash(), } } } impl InvokeTransaction { - pub fn transaction_hash(&self) -> &Felt { + pub const fn transaction_hash(&self) -> &Felt { match self { - InvokeTransaction::V0(tx) => &tx.transaction_hash, - InvokeTransaction::V1(tx) => &tx.transaction_hash, - InvokeTransaction::V3(tx) => &tx.transaction_hash, + Self::V0(tx) => &tx.transaction_hash, + Self::V1(tx) => &tx.transaction_hash, + Self::V3(tx) => &tx.transaction_hash, } } } impl DeclareTransaction { - pub fn transaction_hash(&self) -> &Felt { + pub const fn transaction_hash(&self) -> &Felt { match self { - DeclareTransaction::V0(tx) => &tx.transaction_hash, - DeclareTransaction::V1(tx) => &tx.transaction_hash, - DeclareTransaction::V2(tx) => &tx.transaction_hash, - DeclareTransaction::V3(tx) => &tx.transaction_hash, + Self::V0(tx) => &tx.transaction_hash, + Self::V1(tx) => &tx.transaction_hash, + Self::V2(tx) => &tx.transaction_hash, + Self::V3(tx) => &tx.transaction_hash, } } } impl DeployAccountTransaction { - pub fn transaction_hash(&self) -> &Felt { + pub const fn transaction_hash(&self) -> &Felt { match self { - DeployAccountTransaction::V1(tx) => &tx.transaction_hash, - DeployAccountTransaction::V3(tx) => &tx.transaction_hash, + Self::V1(tx) => &tx.transaction_hash, + Self::V3(tx) => &tx.transaction_hash, } } } impl TransactionReceipt { - pub fn transaction_hash(&self) -> &Felt { + pub const fn transaction_hash(&self) -> &Felt { match self { - TransactionReceipt::Invoke(receipt) => &receipt.transaction_hash, - TransactionReceipt::L1Handler(receipt) => &receipt.transaction_hash, - TransactionReceipt::Declare(receipt) => &receipt.transaction_hash, - TransactionReceipt::Deploy(receipt) => &receipt.transaction_hash, - TransactionReceipt::DeployAccount(receipt) => &receipt.transaction_hash, + Self::Invoke(receipt) => &receipt.transaction_hash, + Self::L1Handler(receipt) => &receipt.transaction_hash, + Self::Declare(receipt) => &receipt.transaction_hash, + Self::Deploy(receipt) => &receipt.transaction_hash, + Self::DeployAccount(receipt) => &receipt.transaction_hash, } } - pub fn finality_status(&self) -> &TransactionFinalityStatus { + pub const fn finality_status(&self) -> &TransactionFinalityStatus { match self { - TransactionReceipt::Invoke(receipt) => &receipt.finality_status, - TransactionReceipt::L1Handler(receipt) => &receipt.finality_status, - TransactionReceipt::Declare(receipt) => &receipt.finality_status, - TransactionReceipt::Deploy(receipt) => &receipt.finality_status, - TransactionReceipt::DeployAccount(receipt) => &receipt.finality_status, + Self::Invoke(receipt) => &receipt.finality_status, + Self::L1Handler(receipt) => &receipt.finality_status, + Self::Declare(receipt) => &receipt.finality_status, + Self::Deploy(receipt) => &receipt.finality_status, + Self::DeployAccount(receipt) => &receipt.finality_status, } } - pub fn execution_result(&self) -> &ExecutionResult { + pub const fn execution_result(&self) -> &ExecutionResult { match self { - TransactionReceipt::Invoke(receipt) => &receipt.execution_result, - TransactionReceipt::L1Handler(receipt) => &receipt.execution_result, - TransactionReceipt::Declare(receipt) => &receipt.execution_result, - TransactionReceipt::Deploy(receipt) => &receipt.execution_result, - TransactionReceipt::DeployAccount(receipt) => &receipt.execution_result, + Self::Invoke(receipt) => &receipt.execution_result, + Self::L1Handler(receipt) => &receipt.execution_result, + Self::Declare(receipt) => &receipt.execution_result, + Self::Deploy(receipt) => &receipt.execution_result, + Self::DeployAccount(receipt) => &receipt.execution_result, } } } @@ -515,44 +515,44 @@ impl L1HandlerTransaction { } } -impl AsRef for BlockId { - fn as_ref(&self) -> &BlockId { +impl AsRef for BlockId { + fn as_ref(&self) -> &Self { self } } -impl AsRef for FunctionCall { - fn as_ref(&self) -> &FunctionCall { +impl AsRef for FunctionCall { + fn as_ref(&self) -> &Self { self } } -impl AsRef for MsgFromL1 { - fn as_ref(&self) -> &MsgFromL1 { +impl AsRef for MsgFromL1 { + fn as_ref(&self) -> &Self { self } } -impl AsRef for BroadcastedTransaction { - fn as_ref(&self) -> &BroadcastedTransaction { +impl AsRef for BroadcastedTransaction { + fn as_ref(&self) -> &Self { self } } -impl AsRef for BroadcastedInvokeTransaction { - fn as_ref(&self) -> &BroadcastedInvokeTransaction { +impl AsRef for BroadcastedInvokeTransaction { + fn as_ref(&self) -> &Self { self } } -impl AsRef for BroadcastedDeclareTransaction { - fn as_ref(&self) -> &BroadcastedDeclareTransaction { +impl AsRef for BroadcastedDeclareTransaction { + fn as_ref(&self) -> &Self { self } } -impl AsRef for BroadcastedDeployAccountTransaction { - fn as_ref(&self) -> &BroadcastedDeployAccountTransaction { +impl AsRef for BroadcastedDeployAccountTransaction { + fn as_ref(&self) -> &Self { self } } diff --git a/starknet-core/src/types/msg.rs b/starknet-core/src/types/msg.rs index e1f1ce04..c34919e9 100644 --- a/starknet-core/src/types/msg.rs +++ b/starknet-core/src/types/msg.rs @@ -17,7 +17,7 @@ pub struct MsgToL2 { impl MsgToL2 { /// Calculates the message hash based on the algorithm documented here: /// - /// https://docs.starknet.io/documentation/architecture_and_concepts/L1-L2_Communication/messaging-mechanism/ + /// pub fn hash(&self) -> Hash256 { let mut hasher = Keccak256::new(); @@ -40,7 +40,7 @@ impl MsgToL2 { hasher.update((self.payload.len() as u64).to_be_bytes()); // Payload - for item in self.payload.iter() { + for item in &self.payload { hasher.update(item.to_bytes_be()); } @@ -54,7 +54,7 @@ impl MsgToL2 { impl MsgToL1 { /// Calculates the message hash based on the algorithm documented here: /// - /// https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/messaging-mechanism/#structure_and_hashing_l2-l1 + /// pub fn hash(&self) -> Hash256 { let mut hasher = Keccak256::new(); @@ -69,7 +69,7 @@ impl MsgToL1 { hasher.update((self.payload.len() as u64).to_be_bytes()); // Payload - for item in self.payload.iter() { + for item in &self.payload { hasher.update(item.to_bytes_be()); } diff --git a/starknet-core/src/types/receipt_block.rs b/starknet-core/src/types/receipt_block.rs index 5c73d03d..a6216dfe 100644 --- a/starknet-core/src/types/receipt_block.rs +++ b/starknet-core/src/types/receipt_block.rs @@ -13,38 +13,38 @@ pub enum ReceiptBlock { impl ReceiptBlock { /// Returns `true` if and only if it's the `Pending` variant. - pub fn is_pending(&self) -> bool { + pub const fn is_pending(&self) -> bool { match self { - ReceiptBlock::Pending => true, - ReceiptBlock::Block { .. } => false, + Self::Pending => true, + Self::Block { .. } => false, } } /// Returns `true` if and only if it's the `Block` variant. - pub fn is_block(&self) -> bool { + pub const fn is_block(&self) -> bool { match self { - ReceiptBlock::Pending => false, - ReceiptBlock::Block { .. } => true, + Self::Pending => false, + Self::Block { .. } => true, } } /// Returns `None` if block is not `Block`. /// /// A more idiomatic way of accessing the block hash is to match the `Block` enum variant. - pub fn block_hash(&self) -> Option { + pub const fn block_hash(&self) -> Option { match self { - ReceiptBlock::Pending => None, - ReceiptBlock::Block { block_hash, .. } => Some(*block_hash), + Self::Pending => None, + Self::Block { block_hash, .. } => Some(*block_hash), } } /// Returns `None` if block is not `Block`. /// /// A more idiomatic way of accessing the block number is to match the `Block` enum variant. - pub fn block_number(&self) -> Option { + pub const fn block_number(&self) -> Option { match self { - ReceiptBlock::Pending => None, - ReceiptBlock::Block { block_number, .. } => Some(*block_number), + Self::Pending => None, + Self::Block { block_number, .. } => Some(*block_number), } } } diff --git a/starknet-core/src/types/serde_impls.rs b/starknet-core/src/types/serde_impls.rs index 95a5221f..925321c8 100644 --- a/starknet-core/src/types/serde_impls.rs +++ b/starknet-core/src/types/serde_impls.rs @@ -58,7 +58,7 @@ impl<'de> DeserializeAs<'de, u128> for NumAsHex { impl<'de> Visitor<'de> for NumAsHexVisitorU64 { type Value = u64; - fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { + fn expecting(&self, formatter: &mut Formatter<'_>) -> alloc::fmt::Result { write!(formatter, "string or number") } @@ -98,7 +98,7 @@ impl<'de> Visitor<'de> for NumAsHexVisitorU64 { impl<'de> Visitor<'de> for NumAsHexVisitorU128 { type Value = u128; - fn expecting(&self, formatter: &mut Formatter) -> alloc::fmt::Result { + fn expecting(&self, formatter: &mut Formatter<'_>) -> alloc::fmt::Result { write!(formatter, "string or number") } @@ -128,8 +128,8 @@ impl Serialize for SyncStatusType { S: serde::Serializer, { match self { - SyncStatusType::NotSyncing => serializer.serialize_bool(false), - SyncStatusType::Syncing(sync_status) => SyncStatus::serialize(sync_status, serializer), + Self::NotSyncing => serializer.serialize_bool(false), + Self::Syncing(sync_status) => SyncStatus::serialize(sync_status, serializer), } } } @@ -145,7 +145,7 @@ impl<'de> Deserialize<'de> for SyncStatusType { false => Ok(Self::NotSyncing), }, - SyncStatusTypeDe::SyncStatus(value) => Ok(SyncStatusType::Syncing(value)), + SyncStatusTypeDe::SyncStatus(value) => Ok(Self::Syncing(value)), } } } @@ -233,19 +233,19 @@ mod transaction_status { S: Serializer, { let raw = match self { - TransactionStatus::Received => Raw { + Self::Received => Raw { finality_status: SequencerTransactionStatus::Received, execution_status: None, }, - TransactionStatus::Rejected => Raw { + Self::Rejected => Raw { finality_status: SequencerTransactionStatus::Rejected, execution_status: None, }, - TransactionStatus::AcceptedOnL2(exe) => Raw { + Self::AcceptedOnL2(exe) => Raw { finality_status: SequencerTransactionStatus::AcceptedOnL2, execution_status: Some(*exe), }, - TransactionStatus::AcceptedOnL1(exe) => Raw { + Self::AcceptedOnL1(exe) => Raw { finality_status: SequencerTransactionStatus::AcceptedOnL1, execution_status: Some(*exe), }, @@ -419,9 +419,7 @@ mod tests { (BlockId::Number(1234), "{\"block_number\":1234}"), (BlockId::Tag(BlockTag::Latest), "\"latest\""), (BlockId::Tag(BlockTag::Pending), "\"pending\""), - ] - .into_iter() - { + ] { assert_eq!(serde_json::to_string(&block_id).unwrap(), json); assert_eq!(serde_json::from_str::(json).unwrap(), block_id); } @@ -434,7 +432,7 @@ mod tests { #[derive(Debug, PartialEq, Eq, Deserialize)] struct Value(#[serde_as(as = "NumAsHex")] u64); - for (num, json) in [(Value(100), "\"0x64\""), (Value(100), "100")].into_iter() { + for (num, json) in [(Value(100), "\"0x64\""), (Value(100), "100")] { assert_eq!(serde_json::from_str::(json).unwrap(), num); } } diff --git a/starknet-core/src/types/u256.rs b/starknet-core/src/types/u256.rs index 7f731e3e..f02b87c0 100644 --- a/starknet-core/src/types/u256.rs +++ b/starknet-core/src/types/u256.rs @@ -12,7 +12,7 @@ pub struct U256(crypto_bigint::U256); impl U256 { #[cfg(target_pointer_width = "64")] - pub fn from_words(low: u128, high: u128) -> Self { + pub const fn from_words(low: u128, high: u128) -> Self { Self(crypto_bigint::U256::from_words([ low as u64, (low >> 64) as u64, @@ -22,7 +22,7 @@ impl U256 { } #[cfg(target_pointer_width = "32")] - pub fn from_words(low: u128, high: u128) -> Self { + pub const fn from_words(low: u128, high: u128) -> Self { Self(crypto_bigint::U256::from_words([ low as u32, (low >> 32) as u32, @@ -35,83 +35,83 @@ impl U256 { ])) } - pub fn low(&self) -> u128 { + pub const fn low(&self) -> u128 { let words = u256_to_u64_array(&self.0); words[0] as u128 + ((words[1] as u128) << 64) } - pub fn high(&self) -> u128 { + pub const fn high(&self) -> u128 { let words = u256_to_u64_array(&self.0); words[2] as u128 + ((words[3] as u128) << 64) } } -impl core::ops::Add for U256 { - type Output = U256; +impl core::ops::Add for U256 { + type Output = Self; - fn add(self, rhs: U256) -> Self::Output { + fn add(self, rhs: Self) -> Self::Output { Self(self.0.checked_add(&rhs.0).unwrap()) } } -impl core::ops::AddAssign for U256 { - fn add_assign(&mut self, rhs: U256) { +impl core::ops::AddAssign for U256 { + fn add_assign(&mut self, rhs: Self) { self.0 = self.0.checked_add(&rhs.0).unwrap() } } -impl core::ops::Sub for U256 { - type Output = U256; +impl core::ops::Sub for U256 { + type Output = Self; - fn sub(self, rhs: U256) -> Self::Output { + fn sub(self, rhs: Self) -> Self::Output { Self(self.0.checked_sub(&rhs.0).unwrap()) } } -impl core::ops::SubAssign for U256 { - fn sub_assign(&mut self, rhs: U256) { +impl core::ops::SubAssign for U256 { + fn sub_assign(&mut self, rhs: Self) { self.0 = self.0.checked_sub(&rhs.0).unwrap() } } -impl core::ops::Mul for U256 { - type Output = U256; +impl core::ops::Mul for U256 { + type Output = Self; - fn mul(self, rhs: U256) -> Self::Output { + fn mul(self, rhs: Self) -> Self::Output { Self(self.0.checked_mul(&rhs.0).unwrap()) } } -impl core::ops::MulAssign for U256 { - fn mul_assign(&mut self, rhs: U256) { +impl core::ops::MulAssign for U256 { + fn mul_assign(&mut self, rhs: Self) { self.0 = self.0.checked_mul(&rhs.0).unwrap() } } -impl core::ops::Div for U256 { - type Output = U256; +impl core::ops::Div for U256 { + type Output = Self; - fn div(self, rhs: U256) -> Self::Output { + fn div(self, rhs: Self) -> Self::Output { Self(self.0.checked_div(&rhs.0).unwrap()) } } -impl core::ops::DivAssign for U256 { - fn div_assign(&mut self, rhs: U256) { +impl core::ops::DivAssign for U256 { + fn div_assign(&mut self, rhs: Self) { self.0 = self.0.checked_div(&rhs.0).unwrap() } } -impl core::ops::Rem for U256 { - type Output = U256; +impl core::ops::Rem for U256 { + type Output = Self; - fn rem(self, rhs: U256) -> Self::Output { + fn rem(self, rhs: Self) -> Self::Output { Self(self.0.checked_rem(&rhs.0).unwrap()) } } -impl core::ops::RemAssign for U256 { - fn rem_assign(&mut self, rhs: U256) { +impl core::ops::RemAssign for U256 { + fn rem_assign(&mut self, rhs: Self) { self.0 = self.0.checked_rem(&rhs.0).unwrap() } } @@ -253,13 +253,13 @@ impl From for U256 { #[cfg(target_pointer_width = "64")] #[inline] -fn u256_to_u64_array(num: &crypto_bigint::U256) -> [u64; 4] { +const fn u256_to_u64_array(num: &crypto_bigint::U256) -> [u64; 4] { num.to_words() } #[cfg(target_pointer_width = "32")] #[inline] -fn u256_to_u64_array(num: &crypto_bigint::U256) -> [u64; 4] { +const fn u256_to_u64_array(num: &crypto_bigint::U256) -> [u64; 4] { unsafe { core::mem::transmute::<[u32; 8], [u64; 4]>(num.to_words()) } } diff --git a/starknet-core/src/utils.rs b/starknet-core/src/utils.rs index c1fa8273..10bac139 100644 --- a/starknet-core/src/utils.rs +++ b/starknet-core/src/utils.rs @@ -126,7 +126,7 @@ pub fn get_storage_var_address(var_name: &str, args: &[Felt]) -> Result Result Result { if !str.is_ascii() { return Err(CairoShortStringToFeltError::NonAsciiCharacter); @@ -153,7 +153,7 @@ pub fn cairo_short_string_to_felt(str: &str) -> Result Result { if felt == &Felt::ZERO { return Ok(String::new()); @@ -165,7 +165,7 @@ pub fn parse_cairo_short_string(felt: &Felt) -> Result for Signature { #[cfg(feature = "signature-display")] impl core::fmt::Display for Signature { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, "{}{}", @@ -57,7 +57,7 @@ impl core::fmt::Display for Signature { #[cfg(feature = "signature-display")] impl core::fmt::Display for ExtendedSignature { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, "{}{}{:02x}", @@ -278,7 +278,7 @@ mod tests { serde_json::from_str(json_data).expect("Unable to parse the JSON"); // Iterating over each element in the JSON - for (private_key, expected_public_key) in key_map.into_iter() { + for (private_key, expected_public_key) in key_map { let private_key = if private_key.len() % 2 != 0 { format!("0{}", private_key.trim_start_matches("0x")) } else { diff --git a/starknet-crypto/src/lib.rs b/starknet-crypto/src/lib.rs index 16470b64..47b7db8b 100644 --- a/starknet-crypto/src/lib.rs +++ b/starknet-crypto/src/lib.rs @@ -1,6 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![doc = include_str!("../README.md")] +#[allow(unused_extern_crates)] #[cfg(all(not(feature = "std"), any(test, feature = "alloc")))] extern crate alloc; diff --git a/starknet-crypto/src/pedersen_hash.rs b/starknet-crypto/src/pedersen_hash.rs index a59c5345..5080a826 100644 --- a/starknet-crypto/src/pedersen_hash.rs +++ b/starknet-crypto/src/pedersen_hash.rs @@ -37,7 +37,7 @@ mod tests { ), ]; - for (in1, in2, expected_hash) in test_data.into_iter() { + for (in1, in2, expected_hash) in test_data { let in1 = field_element_from_be_hex(in1); let in2 = field_element_from_be_hex(in2); let expected_hash = field_element_from_be_hex(expected_hash); diff --git a/starknet-crypto/src/poseidon_hash.rs b/starknet-crypto/src/poseidon_hash.rs index 4f3db345..ff96efbb 100644 --- a/starknet-crypto/src/poseidon_hash.rs +++ b/starknet-crypto/src/poseidon_hash.rs @@ -8,7 +8,7 @@ poseidon_consts!(); /// A hasher for Starknet Poseidon hash. /// -/// Using this hasher is the same as calling [poseidon_hash_many]. +/// Using this hasher is the same as calling [`poseidon_hash_many`]. #[derive(Debug, Default)] pub struct PoseidonHasher { state: [Felt; 3], @@ -16,7 +16,7 @@ pub struct PoseidonHasher { } impl PoseidonHasher { - /// Creates a new [PoseidonHasher]. + /// Creates a new [`PoseidonHasher`]. pub fn new() -> Self { Self::default() } @@ -61,7 +61,7 @@ pub fn poseidon_hash(x: Felt, y: Felt) -> Felt { state[0] } -/// Computes the Starknet Poseidon hash of a single [Felt]. +/// Computes the Starknet Poseidon hash of a single [`Felt`]. pub fn poseidon_hash_single(x: Felt) -> Felt { let mut state = [x, Felt::ZERO, Felt::ONE]; poseidon_permute_comp(&mut state); @@ -69,9 +69,9 @@ pub fn poseidon_hash_single(x: Felt) -> Felt { state[0] } -/// Computes the Starknet Poseidon hash of an arbitrary number of [Felt]s. +/// Computes the Starknet Poseidon hash of an arbitrary number of [`Felt`]s. /// -/// Using this function is the same as using [PoseidonHasher]. +/// Using this function is the same as using [`PoseidonHasher`]. pub fn poseidon_hash_many<'a, I: IntoIterator>(msgs: I) -> Felt { let mut state = [Felt::ZERO, Felt::ZERO, Felt::ZERO]; let mut iter = msgs.into_iter(); @@ -141,11 +141,10 @@ fn round_comp(state: &mut [Felt; 3], idx: usize, full: bool) { state[2] += POSEIDON_COMP_CONSTS[idx + 2]; state[0] = state[0] * state[0] * state[0]; state[1] = state[1] * state[1] * state[1]; - state[2] = state[2] * state[2] * state[2]; } else { state[2] += POSEIDON_COMP_CONSTS[idx]; - state[2] = state[2] * state[2] * state[2]; } + state[2] = state[2] * state[2] * state[2]; mix(state); } @@ -176,7 +175,7 @@ mod tests { ), ]; - for (x, y, hash) in test_data.into_iter() { + for (x, y, hash) in test_data { assert_eq!(poseidon_hash(x, y), hash); } } @@ -200,7 +199,7 @@ mod tests { ), ]; - for (x, hash) in test_data.into_iter() { + for (x, hash) in test_data { assert_eq!(poseidon_hash_single(x), hash); } } @@ -252,7 +251,7 @@ mod tests { ), ]; - for (input, hash) in test_data.into_iter() { + for (input, hash) in test_data { // Direct function call assert_eq!(poseidon_hash_many(&input), hash); diff --git a/starknet-crypto/src/rfc6979.rs b/starknet-crypto/src/rfc6979.rs index af2897a9..cd7ea7da 100644 --- a/starknet-crypto/src/rfc6979.rs +++ b/starknet-crypto/src/rfc6979.rs @@ -104,9 +104,9 @@ mod tests { } fn test_generate_k_from_json_str(json_str: &'static str) { - let test_vectors: Vec = serde_json::from_str(json_str).unwrap(); + let test_vectors: Vec> = serde_json::from_str(json_str).unwrap(); - for test_vector in test_vectors.iter() { + for test_vector in &test_vectors { let msg_hash = field_element_from_be_hex(test_vector.msg_hash); let priv_key = field_element_from_be_hex(test_vector.priv_key); let seed = field_element_from_be_hex(test_vector.seed); diff --git a/starknet-curve/Cargo.toml b/starknet-curve/Cargo.toml index 83c291ba..7c01748b 100644 --- a/starknet-curve/Cargo.toml +++ b/starknet-curve/Cargo.toml @@ -14,3 +14,6 @@ keywords = ["ethereum", "starknet", "web3", "no_std"] [dependencies] starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve"] } + +[lints] +workspace = true diff --git a/starknet-macros/Cargo.toml b/starknet-macros/Cargo.toml index 82d6471c..e402e0fb 100644 --- a/starknet-macros/Cargo.toml +++ b/starknet-macros/Cargo.toml @@ -22,3 +22,6 @@ syn = "2.0.15" [features] default = [] use_imported_type = [] + +[lints] +workspace = true diff --git a/starknet-macros/src/lib.rs b/starknet-macros/src/lib.rs index ebeebe38..79d1aade 100644 --- a/starknet-macros/src/lib.rs +++ b/starknet-macros/src/lib.rs @@ -121,6 +121,6 @@ fn field_element_path() -> &'static str { } #[cfg(not(feature = "use_imported_type"))] -fn field_element_path() -> &'static str { +const fn field_element_path() -> &'static str { "::starknet::core::types::Felt" } diff --git a/starknet-providers/Cargo.toml b/starknet-providers/Cargo.toml index 48db0b55..15055413 100644 --- a/starknet-providers/Cargo.toml +++ b/starknet-providers/Cargo.toml @@ -39,3 +39,6 @@ default = [] no_unknown_fields = [ "starknet-core/no_unknown_fields" ] + +[lints] +workspace = true diff --git a/starknet-providers/src/any.rs b/starknet-providers/src/any.rs index 7bbd7f13..beff9c47 100644 --- a/starknet-providers/src/any.rs +++ b/starknet-providers/src/any.rs @@ -20,7 +20,7 @@ use crate::{ /// the [Provider] trait itself cannot be Box-ed due to the use of associated type. /// /// A recommended pattern is to make your business logic code (e.g. functions) generic over the -/// [Provider] trait, while using this [AnyProvider] type for bootstrapping your application. +/// [Provider] trait, while using this [`AnyProvider`] type for bootstrapping your application. /// /// NOTE: This type was introduced when [Provider] was not Box-able. It should be reviewed whether /// it's still needed anymore. diff --git a/starknet-providers/src/jsonrpc/mod.rs b/starknet-providers/src/jsonrpc/mod.rs index e57550cc..be9b9571 100644 --- a/starknet-providers/src/jsonrpc/mod.rs +++ b/starknet-providers/src/jsonrpc/mod.rs @@ -155,7 +155,7 @@ pub enum JsonRpcResponse { Error { id: u64, error: JsonRpcError }, } -/// Failures trying to parse a [JsonRpcError] into [StarknetError]. +/// Failures trying to parse a [`JsonRpcError`] into [`StarknetError`]. #[derive(Debug, thiserror::Error)] pub enum JsonRpcErrorConversionError { #[error("unknown error code")] @@ -175,7 +175,7 @@ struct Felt(#[serde_as(as = "UfeHex")] pub FeltPrimitive); struct FeltArray(#[serde_as(as = "Vec")] pub Vec); impl JsonRpcClient { - pub fn new(transport: T) -> Self { + pub const fn new(transport: T) -> Self { Self { transport } } } @@ -884,16 +884,16 @@ impl TryFrom<&JsonRpcError> for StarknetError { fn try_from(value: &JsonRpcError) -> Result { match value.code { - 1 => Ok(StarknetError::FailedToReceiveTransaction), - 20 => Ok(StarknetError::ContractNotFound), - 24 => Ok(StarknetError::BlockNotFound), - 27 => Ok(StarknetError::InvalidTransactionIndex), - 28 => Ok(StarknetError::ClassHashNotFound), - 29 => Ok(StarknetError::TransactionHashNotFound), - 31 => Ok(StarknetError::PageSizeTooBig), - 32 => Ok(StarknetError::NoBlocks), - 33 => Ok(StarknetError::InvalidContinuationToken), - 34 => Ok(StarknetError::TooManyKeysInFilter), + 1 => Ok(Self::FailedToReceiveTransaction), + 20 => Ok(Self::ContractNotFound), + 24 => Ok(Self::BlockNotFound), + 27 => Ok(Self::InvalidTransactionIndex), + 28 => Ok(Self::ClassHashNotFound), + 29 => Ok(Self::TransactionHashNotFound), + 31 => Ok(Self::PageSizeTooBig), + 32 => Ok(Self::NoBlocks), + 33 => Ok(Self::InvalidContinuationToken), + 34 => Ok(Self::TooManyKeysInFilter), 40 => { let data = ContractErrorData::deserialize( value @@ -902,7 +902,7 @@ impl TryFrom<&JsonRpcError> for StarknetError { .ok_or(JsonRpcErrorConversionError::MissingData)?, ) .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?; - Ok(StarknetError::ContractError(data)) + Ok(Self::ContractError(data)) } 41 => { let data = TransactionExecutionErrorData::deserialize( @@ -912,12 +912,12 @@ impl TryFrom<&JsonRpcError> for StarknetError { .ok_or(JsonRpcErrorConversionError::MissingData)?, ) .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?; - Ok(StarknetError::TransactionExecutionError(data)) + Ok(Self::TransactionExecutionError(data)) } - 51 => Ok(StarknetError::ClassAlreadyDeclared), - 52 => Ok(StarknetError::InvalidTransactionNonce), - 53 => Ok(StarknetError::InsufficientMaxFee), - 54 => Ok(StarknetError::InsufficientAccountBalance), + 51 => Ok(Self::ClassAlreadyDeclared), + 52 => Ok(Self::InvalidTransactionNonce), + 53 => Ok(Self::InsufficientMaxFee), + 54 => Ok(Self::InsufficientAccountBalance), 55 => { let data = String::deserialize( value @@ -926,15 +926,15 @@ impl TryFrom<&JsonRpcError> for StarknetError { .ok_or(JsonRpcErrorConversionError::MissingData)?, ) .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?; - Ok(StarknetError::ValidationFailure(data)) + Ok(Self::ValidationFailure(data)) } - 56 => Ok(StarknetError::CompilationFailed), - 57 => Ok(StarknetError::ContractClassSizeIsTooLarge), - 58 => Ok(StarknetError::NonAccount), - 59 => Ok(StarknetError::DuplicateTx), - 60 => Ok(StarknetError::CompiledClassHashMismatch), - 61 => Ok(StarknetError::UnsupportedTxVersion), - 62 => Ok(StarknetError::UnsupportedContractClassVersion), + 56 => Ok(Self::CompilationFailed), + 57 => Ok(Self::ContractClassSizeIsTooLarge), + 58 => Ok(Self::NonAccount), + 59 => Ok(Self::DuplicateTx), + 60 => Ok(Self::CompiledClassHashMismatch), + 61 => Ok(Self::UnsupportedTxVersion), + 62 => Ok(Self::UnsupportedContractClassVersion), 63 => { let data = String::deserialize( value @@ -943,7 +943,7 @@ impl TryFrom<&JsonRpcError> for StarknetError { .ok_or(JsonRpcErrorConversionError::MissingData)?, ) .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?; - Ok(StarknetError::UnexpectedError(data)) + Ok(Self::UnexpectedError(data)) } 10 => { let data = NoTraceAvailableErrorData::deserialize( @@ -953,7 +953,7 @@ impl TryFrom<&JsonRpcError> for StarknetError { .ok_or(JsonRpcErrorConversionError::MissingData)?, ) .map_err(|_| JsonRpcErrorConversionError::DataParsingFailure)?; - Ok(StarknetError::NoTraceAvailable(data)) + Ok(Self::NoTraceAvailable(data)) } _ => Err(JsonRpcErrorConversionError::UnknownCode), } diff --git a/starknet-providers/src/jsonrpc/transports/http.rs b/starknet-providers/src/jsonrpc/transports/http.rs index bd54d8b4..f50bb46a 100644 --- a/starknet-providers/src/jsonrpc/transports/http.rs +++ b/starknet-providers/src/jsonrpc/transports/http.rs @@ -40,8 +40,8 @@ impl HttpTransport { } } - /// Consumes the current [HttpTransport] instance and returns a new one with the header - /// appended. Same as calling [add_header]. + /// Consumes the current [`HttpTransport`] instance and returns a new one with the header + /// appended. Same as calling [`add_header`]. pub fn with_header(self, name: String, value: String) -> Self { let mut headers = self.headers; headers.push((name, value)); @@ -88,7 +88,7 @@ impl JsonRpcTransport for HttpTransport { .post(self.url.clone()) .body(request_body) .header("Content-Type", "application/json"); - for (name, value) in self.headers.iter() { + for (name, value) in &self.headers { request = request.header(name, value); } diff --git a/starknet-providers/src/provider.rs b/starknet-providers/src/provider.rs index 0ee4958a..1d0588da 100644 --- a/starknet-providers/src/provider.rs +++ b/starknet-providers/src/provider.rs @@ -302,10 +302,10 @@ pub trait Provider { /// Trait for implementation-specific error type. These errors are irrelevant in most cases, /// assuming that users typically care more about the specifics of RPC errors instead of the -/// underlying transport. Therefore, it makes little sense to bloat [ProviderError] with a generic +/// underlying transport. Therefore, it makes little sense to bloat [`ProviderError`] with a generic /// parameter just for these errors. Instead, they're erased to this trait object. /// -/// This trait is used instead of a plain [std::error::Error] to allow downcasting, in case access +/// This trait is used instead of a plain [`std::error::Error`] to allow downcasting, in case access /// to the specific error type is indeed desired. This is achieved with the `as_any()` method. pub trait ProviderImplError: Error + Debug + Send + Sync { fn as_any(&self) -> &dyn Any; diff --git a/starknet-providers/src/sequencer/mod.rs b/starknet-providers/src/sequencer/mod.rs index 4453a3ed..b12c91e8 100644 --- a/starknet-providers/src/sequencer/mod.rs +++ b/starknet-providers/src/sequencer/mod.rs @@ -37,7 +37,7 @@ pub enum GatewayClientError { /// JSON serialization/deserialization error #[error(transparent)] Serde(SerdeJsonError), - /// Sequencer error responses not parsable into [StarknetError] + /// Sequencer error responses not parsable into [`StarknetError`] #[error(transparent)] SequencerError(SequencerError), /// Method is not supported (only when using as [Provider]) @@ -139,8 +139,8 @@ impl SequencerGatewayProvider { ) } - /// Consumes the current [SequencerGatewayProvider] instance and returns a new one with the - /// header appended. Same as calling [add_header]. + /// Consumes the current [`SequencerGatewayProvider`] instance and returns a new one with the + /// header appended. Same as calling [`add_header`]. pub fn with_header(self, name: String, value: String) -> Self { let mut headers = self.headers; headers.push((name, value)); @@ -194,7 +194,7 @@ impl SequencerGatewayProvider { trace!("Sending GET request to sequencer API ({})", url); let mut request = self.client.get(url); - for (name, value) in self.headers.iter() { + for (name, value) in &self.headers { request = request.header(name, value); } @@ -228,7 +228,7 @@ impl SequencerGatewayProvider { .post(url) .header("Content-Type", "application/json") .body(request_body); - for (name, value) in self.headers.iter() { + for (name, value) in &self.headers { request = request.header(name, value); } @@ -475,29 +475,27 @@ impl From for ProviderError { fn from(value: SequencerError) -> Self { let matching_code = match value.code { ErrorCode::BlockNotFound => Some(StarknetError::BlockNotFound), - ErrorCode::EntryPointNotFoundInContract => None, - ErrorCode::InvalidProgram => None, - ErrorCode::TransactionFailed => { + ErrorCode::EntryPointNotFoundInContract + | ErrorCode::InvalidContractClass + | ErrorCode::DeprecatedEndpoint + | ErrorCode::MalformedRequest + | ErrorCode::InvalidProgram => None, + ErrorCode::TransactionFailed | ErrorCode::ValidateFailure => { Some(StarknetError::ValidationFailure(value.message.clone())) } - ErrorCode::TransactionNotFound => Some(StarknetError::ContractNotFound), - ErrorCode::UninitializedContract => Some(StarknetError::ContractNotFound), - ErrorCode::MalformedRequest => None, + ErrorCode::TransactionNotFound | ErrorCode::UninitializedContract => { + Some(StarknetError::ContractNotFound) + } ErrorCode::UndeclaredClass => Some(StarknetError::ClassHashNotFound), ErrorCode::InvalidTransactionNonce => Some(StarknetError::InvalidTransactionNonce), - ErrorCode::ValidateFailure => { - Some(StarknetError::ValidationFailure(value.message.clone())) - } ErrorCode::ClassAlreadyDeclared => Some(StarknetError::ClassAlreadyDeclared), ErrorCode::CompilationFailed => Some(StarknetError::CompilationFailed), ErrorCode::InvalidCompiledClassHash => Some(StarknetError::CompiledClassHashMismatch), ErrorCode::DuplicatedTransaction => Some(StarknetError::DuplicateTx), - ErrorCode::InvalidContractClass => None, - ErrorCode::DeprecatedEndpoint => None, }; match matching_code { - Some(code) => ProviderError::StarknetError(code), + Some(code) => Self::StarknetError(code), None => GatewayClientError::SequencerError(value).into(), } } @@ -539,10 +537,10 @@ where { let temp_value = serde_json::Value::deserialize(deserializer)?; if let Ok(value) = T::deserialize(&temp_value) { - return Ok(GatewayResponse::Data(value)); + return Ok(Self::Data(value)); } if let Ok(value) = SequencerError::deserialize(&temp_value) { - return Ok(GatewayResponse::SequencerError(value)); + return Ok(Self::SequencerError(value)); } Err(serde::de::Error::custom( "data did not match any variant of enum GatewayResponse", @@ -583,9 +581,7 @@ mod tests { for raw in [ include_str!("../../test-data/raw_gateway_responses/get_class_by_hash/1_cairo_0.txt"), include_str!("../../test-data/raw_gateway_responses/get_class_by_hash/3_cairo_1.txt"), - ] - .into_iter() - { + ] { serde_json::from_str::>(raw).unwrap(); } } diff --git a/starknet-providers/src/sequencer/models/contract.rs b/starknet-providers/src/sequencer/models/contract.rs index 04584d51..0ef6a2e6 100644 --- a/starknet-providers/src/sequencer/models/contract.rs +++ b/starknet-providers/src/sequencer/models/contract.rs @@ -91,7 +91,7 @@ impl CompressedSierraClass { let compressed_program = gzip_encoder.finish().map_err(DecompressProgramError::Io)?; - Ok(CompressedSierraClass { + Ok(Self { sierra_program: compressed_program, contract_class_version: flattened_class.contract_class_version.clone(), entry_points_by_type: flattened_class.entry_points_by_type.clone(), diff --git a/starknet-providers/src/sequencer/models/conversions.rs b/starknet-providers/src/sequencer/models/conversions.rs index 8e2c6efe..6af9f96a 100644 --- a/starknet-providers/src/sequencer/models/conversions.rs +++ b/starknet-providers/src/sequencer/models/conversions.rs @@ -604,8 +604,9 @@ impl TryFrom for core::TransactionFinalityStatus { fn try_from(value: TransactionFinalityStatus) -> Result { match value { - TransactionFinalityStatus::NotReceived => Err(ConversionError), - TransactionFinalityStatus::Received => Err(ConversionError), + TransactionFinalityStatus::NotReceived | TransactionFinalityStatus::Received => { + Err(ConversionError) + } TransactionFinalityStatus::AcceptedOnL2 => Ok(Self::AcceptedOnL2), TransactionFinalityStatus::AcceptedOnL1 => Ok(Self::AcceptedOnL1), } @@ -1209,7 +1210,7 @@ fn convert_execution_result( } } -fn convert_legacy_entry_point( +const fn convert_legacy_entry_point( value: core::LegacyContractEntryPoint, ) -> contract_legacy::RawLegacyEntryPoint { // WARNING: this causes pre-0.11.0 contract declaration to fail due to `offset` issue diff --git a/starknet-providers/src/sequencer/models/serde_impls.rs b/starknet-providers/src/sequencer/models/serde_impls.rs index f54d344f..fda5b8e7 100644 --- a/starknet-providers/src/sequencer/models/serde_impls.rs +++ b/starknet-providers/src/sequencer/models/serde_impls.rs @@ -20,7 +20,7 @@ pub(crate) mod u64_hex { impl<'de> Visitor<'de> for U64HexVisitor { type Value = u64; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(formatter, "string") } @@ -56,7 +56,7 @@ pub(crate) mod u128_hex { impl<'de> Visitor<'de> for U128HexVisitor { type Value = u128; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(formatter, "string") } @@ -95,7 +95,7 @@ pub(crate) mod u64_hex_opt { impl<'de> Visitor<'de> for U64HexOptVisitor { type Value = Option; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(formatter, "null or string") } diff --git a/starknet-providers/src/sequencer/models/transaction.rs b/starknet-providers/src/sequencer/models/transaction.rs index 388ace7d..75aaa0b6 100644 --- a/starknet-providers/src/sequencer/models/transaction.rs +++ b/starknet-providers/src/sequencer/models/transaction.rs @@ -246,13 +246,13 @@ pub enum DataAvailabilityMode { struct DataAvailabilityModeVisitor; impl TransactionType { - pub fn transaction_hash(&self) -> Felt { + pub const fn transaction_hash(&self) -> Felt { match self { - TransactionType::Declare(inner) => inner.transaction_hash, - TransactionType::Deploy(inner) => inner.transaction_hash, - TransactionType::DeployAccount(inner) => inner.transaction_hash, - TransactionType::InvokeFunction(inner) => inner.transaction_hash, - TransactionType::L1Handler(inner) => inner.transaction_hash, + Self::Declare(inner) => inner.transaction_hash, + Self::Deploy(inner) => inner.transaction_hash, + Self::DeployAccount(inner) => inner.transaction_hash, + Self::InvokeFunction(inner) => inner.transaction_hash, + Self::L1Handler(inner) => inner.transaction_hash, } } } @@ -281,7 +281,7 @@ impl<'de> Deserialize<'de> for DataAvailabilityMode { impl<'de> Visitor<'de> for DataAvailabilityModeVisitor { type Value = DataAvailabilityMode; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(formatter, "integer") } diff --git a/starknet-providers/src/sequencer/provider.rs b/starknet-providers/src/sequencer/provider.rs index b6b44bcd..313cda9c 100644 --- a/starknet-providers/src/sequencer/provider.rs +++ b/starknet-providers/src/sequencer/provider.rs @@ -113,7 +113,10 @@ impl Provider for SequencerGatewayProvider { .await?; // `NotReceived` is not a valid status for JSON-RPC. It's an error. - if let Some(TransactionFinalityStatus::NotReceived) = &status.finality_status { + if matches!( + &status.finality_status, + Some(TransactionFinalityStatus::NotReceived) + ) { return Err(ProviderError::StarknetError( StarknetError::TransactionHashNotFound, )); diff --git a/starknet-providers/tests/jsonrpc.rs b/starknet-providers/tests/jsonrpc.rs index bddd2ab4..dac0910a 100644 --- a/starknet-providers/tests/jsonrpc.rs +++ b/starknet-providers/tests/jsonrpc.rs @@ -18,7 +18,7 @@ use url::Url; fn create_jsonrpc_client() -> JsonRpcClient { let rpc_url = std::env::var("STARKNET_RPC") - .unwrap_or("https://pathfinder.rpc.sepolia.starknet.rs/rpc/v0_7".into()); + .unwrap_or_else(|_| "https://pathfinder.rpc.sepolia.starknet.rs/rpc/v0_7".into()); JsonRpcClient::new(HttpTransport::new(Url::parse(&rpc_url).unwrap())) } diff --git a/starknet-signers/Cargo.toml b/starknet-signers/Cargo.toml index d0515adf..f608b25f 100644 --- a/starknet-signers/Cargo.toml +++ b/starknet-signers/Cargo.toml @@ -39,3 +39,6 @@ wasm-bindgen-test = "0.3.34" default = [] ledger = ["coins-bip32", "coins-ledger", "semver"] + +[lints] +workspace = true diff --git a/starknet-signers/src/key_pair.rs b/starknet-signers/src/key_pair.rs index 31a7cefe..65047f20 100644 --- a/starknet-signers/src/key_pair.rs +++ b/starknet-signers/src/key_pair.rs @@ -47,7 +47,7 @@ impl SigningKey { Self { secret_scalar } } - pub fn from_secret_scalar(secret_scalar: Felt) -> Self { + pub const fn from_secret_scalar(secret_scalar: Felt) -> Self { Self { secret_scalar } } @@ -92,7 +92,7 @@ impl SigningKey { Ok(()) } - pub fn secret_scalar(&self) -> Felt { + pub const fn secret_scalar(&self) -> Felt { self.secret_scalar } @@ -106,11 +106,11 @@ impl SigningKey { } impl VerifyingKey { - pub fn from_scalar(scalar: Felt) -> Self { + pub const fn from_scalar(scalar: Felt) -> Self { Self { scalar } } - pub fn scalar(&self) -> Felt { + pub const fn scalar(&self) -> Felt { self.scalar }