diff --git a/.github/workflows/binaries.yml b/.github/workflows/binaries.yml index 42ddb786a..08641b9ad 100644 --- a/.github/workflows/binaries.yml +++ b/.github/workflows/binaries.yml @@ -13,6 +13,11 @@ defaults: run: shell: bash +permissions: + id-token: write + contents: write + attestations: write + jobs: build: @@ -62,6 +67,11 @@ jobs: CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc working-directory: ${{ env.BUILD_WORKING_DIR }} run: cargo build --target-dir="$GITHUB_WORKSPACE/target" --package ${{ matrix.crate.name }} --features opt --release --target ${{ matrix.sys.target }} + - name: Build provenance for attestation (release only) + if: github.event_name == 'release' + uses: actions/attest-build-provenance@v1 + with: + subject-path: target/${{ matrix.sys.target }}/release/${{ matrix.crate.binary }}${{ matrix.sys.ext }} - name: Compress run: | cd target/${{ matrix.sys.target }}/release diff --git a/.github/workflows/dependency-check.yml b/.github/workflows/dependency-check.yml index cef838a7c..fe8c0e8bc 100644 --- a/.github/workflows/dependency-check.yml +++ b/.github/workflows/dependency-check.yml @@ -14,12 +14,6 @@ defaults: shell: bash jobs: - dependency-sanity-checker: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: rustup update - - run: scripts/check-dependencies.bash validate-rust-git-rev-deps: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/full-help-docs.yml b/.github/workflows/full-help-docs.yml deleted file mode 100644 index f564ae9ae..000000000 --- a/.github/workflows/full-help-docs.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: CLI Help Doc - -on: - push: - branches: [main, release/**] - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref_protected == 'true' && github.sha || github.ref }} - cancel-in-progress: true - -permissions: - contents: read - # Optional: allow read access to pull request. Use with `only-new-issues` option. - pull-requests: read - -jobs: - complete: - if: always() - needs: [doc-check] - runs-on: ubuntu-latest - steps: - - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') - run: exit 1 - - doc-check: - runs-on: ubuntu-latest-16-cores - steps: - - uses: actions/checkout@v4 - - uses: stellar/actions/rust-cache@main - - run: rustup update - - name: Generate help doc - # this looks goofy to get GITHUB_OUTPUT to work with multi-line return values; - # see https://stackoverflow.com/a/74266196/249801 - run: | - make generate-full-help-doc - raw_diff=$(git diff FULL_HELP_DOCS.md) - if [ "$raw_diff" != "" ]; then echo ""; echo "Unexpected docs change:"; echo "======================="; echo ""; echo "$raw_diff"; echo ""; echo "======================="; echo ""; fi - echo diff=$raw_diff >> $GITHUB_OUTPUT - id: doc-gen - - - name: Check diff - if: steps.doc-gen.outputs.diff != '' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Expected `doc-gen` to generate no diffs, but got diff shown in previous step.\n\nUpdate the full help docs:\n\n cargo md-gen\n\nDo this automatically on every commit by installing the pre-commit hook as explained in the README.') diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index eb4e4c414..048015009 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -17,7 +17,7 @@ jobs: complete: if: always() - needs: [fmt, build-and-test, publish-dry-run] + needs: [fmt, check-generated-full-help-docs, build-and-test, publish-dry-run] runs-on: ubuntu-latest steps: - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') @@ -30,13 +30,14 @@ jobs: - run: rustup update - run: cargo fmt --all --check - check-generated-examples-list: - runs-on: ubuntu-latest + check-generated-full-help-docs: + runs-on: ubuntu-latest-16-cores steps: - uses: actions/checkout@v4 - - run: make generate-examples-list - - name: Check no diffs exist - run: git add -N . && git diff HEAD --exit-code + - uses: stellar/actions/rust-cache@main + - run: rustup update + - run: make generate-full-help-doc + - run: git add -N . && git diff HEAD --exit-code build-and-test: strategy: diff --git a/Cargo.lock b/Cargo.lock index 7ce514d54..55ebf62a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,18 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -106,10 +118,122 @@ dependencies = [ ] [[package]] -name = "arc-swap" -version = "1.7.1" +name = "ark-bls12-381" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits", + "zeroize", +] + +[[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 0.10.7", + "itertools 0.10.5", + "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-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[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 = "arrayref" @@ -117,6 +241,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "ascii-canvas" version = "3.0.0" @@ -591,15 +721,6 @@ dependencies = [ "serde", ] -[[package]] -name = "btoi" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad" -dependencies = [ - "num-traits", -] - [[package]] name = "bumpalo" version = "3.16.0" @@ -757,12 +878,6 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" -[[package]] -name = "clru" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd0f76e066e64fdc5631e3bb46381254deab9ef1158292f27c8c57e3bf3fe59" - [[package]] name = "codespan-reporting" version = "0.11.1" @@ -1108,6 +1223,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_arbitrary" version = "1.3.2" @@ -1252,12 +1378,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - [[package]] name = "dyn-clone" version = "1.0.17" @@ -1266,9 +1386,9 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ecdsa" -version = "0.16.7" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", "digest 0.10.7", @@ -1466,12 +1586,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "faster-hex" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" - [[package]] name = "fastrand" version = "1.9.0" @@ -1503,18 +1617,6 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" -[[package]] -name = "filetime" -version = "0.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.4.1", - "windows-sys 0.52.0", -] - [[package]] name = "fixedbitset" version = "0.4.2" @@ -1730,886 +1832,144 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] -name = "gix" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31887c304d9a935f3e5494fb5d6a0106c34e965168ec0db9b457424eedd0c741" -dependencies = [ - "gix-actor", - "gix-attributes", - "gix-command", - "gix-commitgraph", - "gix-config", - "gix-credentials", - "gix-date", - "gix-diff", - "gix-discover", - "gix-features", - "gix-filter", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-hashtable", - "gix-ignore", - "gix-index", - "gix-lock", - "gix-macros", - "gix-negotiate", - "gix-object", - "gix-odb", - "gix-pack", - "gix-path", - "gix-pathspec", - "gix-prompt", - "gix-protocol", - "gix-ref", - "gix-refspec", - "gix-revision", - "gix-revwalk", - "gix-sec", - "gix-submodule", - "gix-tempfile", - "gix-trace", - "gix-transport", - "gix-traverse", - "gix-url", - "gix-utils", - "gix-validate", - "gix-worktree", - "gix-worktree-state", - "once_cell", - "parking_lot", - "reqwest 0.11.27", - "smallvec", - "thiserror", -] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] -name = "gix-actor" -version = "0.30.0" +name = "globset" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a7bb9fad6125c81372987c06469601d37e1a2d421511adb69971b9083517a8a" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ + "aho-corasick", "bstr", - "btoi", - "gix-date", - "itoa", - "thiserror", - "winnow 0.5.40", + "log", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] -name = "gix-attributes" -version = "0.22.3" +name = "globwalk" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37ce99c7e81288c28b703641b6d5d119aacc45c1a6b247156e6249afa486257" +checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bstr", - "gix-glob", - "gix-path", - "gix-quote", - "gix-trace", - "kstring", - "smallvec", - "thiserror", - "unicode-bom", + "bitflags 2.6.0", + "ignore", + "walkdir", ] [[package]] -name = "gix-bitmap" -version = "0.2.11" +name = "gloo-timers" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a371db66cbd4e13f0ed9dc4c0fea712d7276805fccc877f77e96374d317e87ae" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" dependencies = [ - "thiserror", + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "gix-chunk" -version = "0.4.8" +name = "group" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c8751169961ba7640b513c3b24af61aa962c967aaf04116734975cd5af0c52" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "thiserror", + "ff", + "rand_core 0.6.4", + "subtle", ] [[package]] -name = "gix-command" -version = "0.3.8" +name = "h2" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d76867867da891cbe32021ad454e8cae90242f6afb06762e4dd0d357afd1d7b" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ - "bstr", - "gix-path", - "gix-trace", - "shell-words", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.3.0", + "slab", + "tokio", + "tokio-util", + "tracing", ] [[package]] -name = "gix-commitgraph" -version = "0.24.3" +name = "h2" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133b06f67f565836ec0c473e2116a60fb74f80b6435e21d88013ac0e3c60fc78" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ - "bstr", - "gix-chunk", - "gix-features", - "gix-hash", - "memmap2", - "thiserror", + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.3.0", + "slab", + "tokio", + "tokio-util", + "tracing", ] [[package]] -name = "gix-config" -version = "0.34.0" +name = "hashbrown" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e62bf2073b6ce3921ffa6d8326f645f30eec5fc4a8e8a4bc0fcb721a2f3f69dc" -dependencies = [ - "bstr", - "gix-config-value", - "gix-features", - "gix-glob", - "gix-path", - "gix-ref", - "gix-sec", - "memchr", - "once_cell", - "smallvec", - "thiserror", - "unicode-bom", - "winnow 0.5.40", -] +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] -name = "gix-config-value" -version = "0.14.7" +name = "hashbrown" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b328997d74dd15dc71b2773b162cb4af9a25c424105e4876e6d0686ab41c383e" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "bitflags 2.6.0", - "bstr", - "gix-path", - "libc", - "thiserror", + "ahash", ] [[package]] -name = "gix-credentials" -version = "0.24.4" +name = "hashbrown" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "198588f532e4d1202e04e6c3f50e4d7c060dffc66801c6f53cc246f1d234739e" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "bstr", - "gix-command", - "gix-config-value", - "gix-path", - "gix-prompt", - "gix-sec", - "gix-trace", - "gix-url", - "thiserror", + "ahash", ] [[package]] -name = "gix-date" -version = "0.8.7" +name = "heck" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eed6931f21491ee0aeb922751bd7ec97b4b2fe8fbfedcb678e2a2dce5f3b8c0" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ - "bstr", - "itoa", - "thiserror", - "time", + "unicode-segmentation", ] [[package]] -name = "gix-diff" -version = "0.40.0" +name = "heck" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdcb5e49c4b9729dd1c361040ae5c3cd7c497b2260b18c954f62db3a63e98cf" -dependencies = [ - "bstr", - "gix-hash", - "gix-object", - "thiserror", -] +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] -name = "gix-discover" -version = "0.29.0" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4669218f3ec0cbbf8f16857b32200890f8ca585f36f5817242e4115fe4551af" -dependencies = [ - "bstr", - "dunce", - "gix-fs", - "gix-hash", - "gix-path", - "gix-ref", - "gix-sec", - "thiserror", -] +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] -name = "gix-features" -version = "0.38.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac7045ac9fe5f9c727f38799d002a7ed3583cd777e3322a7c4b43e3cf437dc69" -dependencies = [ - "bytes", - "crc32fast", - "flate2", - "gix-hash", - "gix-trace", - "gix-utils", - "libc", - "once_cell", - "prodash", - "sha1_smol", - "thiserror", - "walkdir", -] - -[[package]] -name = "gix-filter" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9240862840fb740d209422937195e129e4ed3da49af212383260134bea8f6c1a" -dependencies = [ - "bstr", - "encoding_rs", - "gix-attributes", - "gix-command", - "gix-hash", - "gix-object", - "gix-packetline-blocking", - "gix-path", - "gix-quote", - "gix-trace", - "gix-utils", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-fs" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2184c40e7910529677831c8b481acf788ffd92427ed21fad65b6aa637e631b8" -dependencies = [ - "gix-features", - "gix-utils", -] - -[[package]] -name = "gix-glob" -version = "0.16.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7df15afa265cc8abe92813cd354d522f1ac06b29ec6dfa163ad320575cb447" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "gix-features", - "gix-path", -] - -[[package]] -name = "gix-hash" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93d7df7366121b5018f947a04d37f034717e113dcf9ccd85c34b58e57a74d5e" -dependencies = [ - "faster-hex", - "thiserror", -] - -[[package]] -name = "gix-hashtable" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ddf80e16f3c19ac06ce415a38b8591993d3f73aede049cb561becb5b3a8e242" -dependencies = [ - "gix-hash", - "hashbrown 0.14.5", - "parking_lot", -] - -[[package]] -name = "gix-ignore" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6afb8f98e314d4e1adc822449389ada863c174b5707cedd327d67b84dba527" -dependencies = [ - "bstr", - "gix-glob", - "gix-path", - "gix-trace", - "unicode-bom", -] - -[[package]] -name = "gix-index" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7152181ba8f0a3addc5075dd612cea31fc3e252b29c8be8c45f4892bf87426" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "btoi", - "filetime", - "gix-bitmap", - "gix-features", - "gix-fs", - "gix-hash", - "gix-lock", - "gix-object", - "gix-traverse", - "itoa", - "libc", - "memmap2", - "rustix 0.38.34", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-lock" -version = "13.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c359f81f01b8352063319bcb39789b7ea0887b406406381106e38c4a34d049" -dependencies = [ - "gix-tempfile", - "gix-utils", - "thiserror", -] - -[[package]] -name = "gix-macros" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "999ce923619f88194171a67fb3e6d613653b8d4d6078b529b15a765da0edcc17" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "gix-negotiate" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a163adb84149e522e991cbe27250a6e01de56f98cd05b174614ce3f8a4e8b140" -dependencies = [ - "bitflags 2.6.0", - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-object", - "gix-revwalk", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-object" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693ce9d30741506cb082ef2d8b797415b48e032cce0ab23eff894c19a7e4777b" -dependencies = [ - "bstr", - "btoi", - "gix-actor", - "gix-date", - "gix-features", - "gix-hash", - "gix-validate", - "itoa", - "smallvec", - "thiserror", - "winnow 0.5.40", -] - -[[package]] -name = "gix-odb" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba2fa9e81f2461b78b4d81a807867667326c84cdab48e0aed7b73a593aa1be4" -dependencies = [ - "arc-swap", - "gix-date", - "gix-features", - "gix-fs", - "gix-hash", - "gix-object", - "gix-pack", - "gix-path", - "gix-quote", - "parking_lot", - "tempfile", - "thiserror", -] - -[[package]] -name = "gix-pack" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da5f3e78c96b76c4e6fe5e8e06b76221e4a0ee9a255aa935ed1fdf68988dfd8" -dependencies = [ - "clru", - "gix-chunk", - "gix-features", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-path", - "gix-tempfile", - "memmap2", - "parking_lot", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-packetline" -version = "0.17.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b70486beda0903b6d5b65dfa6e40585098cdf4e6365ca2dff4f74c387354a515" -dependencies = [ - "bstr", - "faster-hex", - "gix-trace", - "thiserror", -] - -[[package]] -name = "gix-packetline-blocking" -version = "0.17.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31d42378a3d284732e4d589979930d0d253360eccf7ec7a80332e5ccb77e14a" -dependencies = [ - "bstr", - "faster-hex", - "gix-trace", - "thiserror", -] - -[[package]] -name = "gix-path" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d23d5bbda31344d8abc8de7c075b3cf26e5873feba7c4a15d916bce67382bd9" -dependencies = [ - "bstr", - "gix-trace", - "home", - "once_cell", - "thiserror", -] - -[[package]] -name = "gix-pathspec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cbd49750edb26b0a691e5246fc635fa554d344da825cd20fa9ee0da9c1b761f" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "gix-attributes", - "gix-config-value", - "gix-glob", - "gix-path", - "thiserror", -] - -[[package]] -name = "gix-prompt" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e0595d2be4b6d6a71a099e989bdd610882b882da35fb8503d91d6f81aa0936f" -dependencies = [ - "gix-command", - "gix-config-value", - "parking_lot", - "rustix 0.38.34", - "thiserror", -] - -[[package]] -name = "gix-protocol" -version = "0.44.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a905cd00946ed8ed6f4f2281f98a889c5b3d38361cd94b8d5a5771d25ab33b99" -dependencies = [ - "bstr", - "gix-credentials", - "gix-date", - "gix-features", - "gix-hash", - "gix-transport", - "gix-utils", - "maybe-async", - "thiserror", - "winnow 0.6.18", -] - -[[package]] -name = "gix-quote" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbff4f9b9ea3fa7a25a70ee62f545143abef624ac6aa5884344e70c8b0a1d9ff" -dependencies = [ - "bstr", - "gix-utils", - "thiserror", -] - -[[package]] -name = "gix-ref" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5818958994ad7879fa566f5441ebcc48f0926aa027b28948e6fbf6578894dc31" -dependencies = [ - "gix-actor", - "gix-date", - "gix-features", - "gix-fs", - "gix-hash", - "gix-lock", - "gix-object", - "gix-path", - "gix-tempfile", - "gix-utils", - "gix-validate", - "memmap2", - "thiserror", - "winnow 0.5.40", -] - -[[package]] -name = "gix-refspec" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613aa4d93034c5791d13bdc635e530f4ddab1412ddfb4a8215f76213177b61c7" -dependencies = [ - "bstr", - "gix-hash", - "gix-revision", - "gix-validate", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-revision" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "288f6549d7666db74dc3f169a9a333694fc28ecd2f5aa7b2c979c89eb556751a" -dependencies = [ - "bstr", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-revwalk", - "gix-trace", - "thiserror", -] - -[[package]] -name = "gix-revwalk" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9b4d91dfc5c14fee61a28c65113ded720403b65a0f46169c0460f731a5d03c" -dependencies = [ - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-sec" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1547d26fa5693a7f34f05b4a3b59a90890972922172653bcb891ab3f09f436df" -dependencies = [ - "bitflags 2.6.0", - "gix-path", - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "gix-submodule" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73182f6c1f5ed1ed94ba16581ac62593d5e29cd1c028b2af618f836283b8f8d4" -dependencies = [ - "bstr", - "gix-config", - "gix-path", - "gix-pathspec", - "gix-refspec", - "gix-url", - "thiserror", -] - -[[package]] -name = "gix-tempfile" -version = "13.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a761d76594f4443b675e85928e4902dec333273836bd386906f01e7e346a0d11" -dependencies = [ - "gix-fs", - "libc", - "once_cell", - "parking_lot", - "tempfile", -] - -[[package]] -name = "gix-trace" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e" - -[[package]] -name = "gix-transport" -version = "0.41.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8e5f72ec9cad9ee44714b9a4ec7427b540a2418b62111f5e3a715bebe1ed9d" -dependencies = [ - "base64 0.21.7", - "bstr", - "gix-command", - "gix-credentials", - "gix-features", - "gix-packetline", - "gix-quote", - "gix-sec", - "gix-url", - "reqwest 0.11.27", - "thiserror", -] - -[[package]] -name = "gix-traverse" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfc30c5b5e4e838683b59e1b0574ce6bc1c35916df9709aaab32bb7751daf08b" -dependencies = [ - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-revwalk", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-url" -version = "0.27.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2eb9b35bba92ea8f0b5ab406fad3cf6b87f7929aa677ff10aa042c6da621156" -dependencies = [ - "bstr", - "gix-features", - "gix-path", - "home", - "thiserror", - "url", -] - -[[package]] -name = "gix-utils" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35192df7fd0fa112263bad8021e2df7167df4cc2a6e6d15892e1e55621d3d4dc" -dependencies = [ - "fastrand 2.1.0", - "unicode-normalization", -] - -[[package]] -name = "gix-validate" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c27dd34a49b1addf193c92070bcbf3beaf6e10f16a78544de6372e146a0acf" -dependencies = [ - "bstr", - "thiserror", -] - -[[package]] -name = "gix-worktree" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca36bb3dc54038c66507dc75c4d8edbee2d6d5cc45227b4eb508ad13dd60a006" -dependencies = [ - "bstr", - "gix-attributes", - "gix-features", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-ignore", - "gix-index", - "gix-object", - "gix-path", -] - -[[package]] -name = "gix-worktree-state" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae178614b70bdb0c7f6f21b8c9fb711ab78bd7e8e1866f565fcf28876747f1d" -dependencies = [ - "bstr", - "gix-features", - "gix-filter", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-index", - "gix-object", - "gix-path", - "gix-worktree", - "io-close", - "thiserror", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "globset" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", -] - -[[package]] -name = "globwalk" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" -dependencies = [ - "bitflags 2.6.0", - "ignore", - "walkdir", -] - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.3.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "h2" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http 1.1.0", - "indexmap 2.3.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -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 = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" +name = "hermit-abi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" @@ -2943,7 +2303,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.0", "tower-service", - "webpki-roots 0.26.3", + "webpki-roots", ] [[package]] @@ -3112,18 +2472,8 @@ name = "instant" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-close" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" -dependencies = [ - "libc", - "winapi", +dependencies = [ + "cfg-if", ] [[package]] @@ -3277,9 +2627,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", @@ -3296,15 +2646,6 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "kstring" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" -dependencies = [ - "static_assertions", -] - [[package]] name = "kv-log-macro" version = "1.0.7" @@ -3486,32 +2827,12 @@ dependencies = [ "regex-automata 0.1.10", ] -[[package]] -name = "maybe-async" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "memmap2" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" -dependencies = [ - "libc", -] - [[package]] name = "mime" version = "0.3.17" @@ -3563,6 +2884,12 @@ dependencies = [ "tokio", ] +[[package]] +name = "multi-stash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685a9ac4b61f4e728e1d2c6a7844609c16527aeb5e6c865915c08e619c16410f" + [[package]] name = "native-tls" version = "0.2.12" @@ -3655,15 +2982,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - [[package]] name = "object" version = "0.32.2" @@ -3788,7 +3106,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.3", + "redox_syscall", "smallvec", "windows-targets 0.52.6", ] @@ -4102,12 +3420,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prodash" -version = "28.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" - [[package]] name = "quick-error" version = "1.2.3" @@ -4207,15 +3519,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.3" @@ -4295,7 +3598,6 @@ dependencies = [ "http 0.2.12", "http-body 0.4.6", "hyper 0.14.30", - "hyper-rustls 0.24.2", "hyper-tls", "ipnet", "js-sys", @@ -4305,7 +3607,6 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.12", "rustls-pemfile 1.0.4", "serde", "serde_json", @@ -4314,13 +3615,11 @@ dependencies = [ "system-configuration", "tokio", "tokio-native-tls", - "tokio-rustls 0.24.1", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.4", "winreg", ] @@ -4369,7 +3668,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.26.3", + "webpki-roots", "windows-registry", ] @@ -4939,12 +4238,6 @@ dependencies = [ "syn 2.0.77", ] -[[package]] -name = "sha1_smol" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" - [[package]] name = "sha2" version = "0.9.9" @@ -4988,12 +4281,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shell-words" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" - [[package]] name = "shlex" version = "1.3.0" @@ -5128,6 +4415,18 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "soroban-builtin-sdk-macros" +version = "22.0.0-rc.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4c8668199d95e3061cd42e1b96a91451c656a238a607fa53f96f0a3fdcf5f3" +dependencies = [ + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "soroban-cli" version = "21.5.0" @@ -5155,7 +4454,6 @@ dependencies = [ "fqdn", "futures", "futures-util", - "gix", "glob", "heck 0.5.0", "hex", @@ -5182,17 +4480,16 @@ dependencies = [ "serde_json", "sha2 0.10.8", "shlex", - "soroban-env-host", - "soroban-ledger-snapshot", - "soroban-sdk", - "soroban-spec", + "soroban-ledger-snapshot 22.0.0-rc.1.1", + "soroban-sdk 22.0.0-rc.1.1", + "soroban-spec 22.0.0-rc.1.1", "soroban-spec-json", - "soroban-spec-rust", + "soroban-spec-rust 22.0.0-rc.1.1", "soroban-spec-tools", "soroban-spec-typescript", "stellar-rpc-client", "stellar-strkey 0.0.11", - "stellar-xdr", + "stellar-xdr 22.0.0-rc.1.1", "strsim 0.10.0", "strum 0.17.1", "strum_macros 0.17.1", @@ -5227,10 +4524,28 @@ dependencies = [ "num-derive", "num-traits", "serde", - "soroban-env-macros", - "soroban-wasmi", + "soroban-env-macros 21.2.1", + "soroban-wasmi 0.31.1-soroban.20.0.1", + "static_assertions", + "stellar-xdr 21.2.0", + "wasmparser 0.116.1", +] + +[[package]] +name = "soroban-env-common" +version = "22.0.0-rc.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdf1d66133d6b29e2834acea79decb57c47c71aa01885cae2b9ad621d67525c" +dependencies = [ + "crate-git-revision 0.0.6", + "ethnum", + "num-derive", + "num-traits", + "serde", + "soroban-env-macros 22.0.0-rc.1.1", + "soroban-wasmi 0.36.1-soroban.22.0.0", "static_assertions", - "stellar-xdr", + "stellar-xdr 22.0.0-rc.1.1", "wasmparser 0.116.1", ] @@ -5240,7 +4555,17 @@ version = "21.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bfb2536811045d5cd0c656a324cbe9ce4467eb734c7946b74410d90dea5d0ce" dependencies = [ - "soroban-env-common", + "soroban-env-common 21.2.1", + "static_assertions", +] + +[[package]] +name = "soroban-env-guest" +version = "22.0.0-rc.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa9610ac8a4a900e6f35b2ed171bc325c7e9883929f5e9da758e85f1226dd284" +dependencies = [ + "soroban-env-common 22.0.0-rc.1.1", "static_assertions", ] @@ -5269,14 +4594,50 @@ dependencies = [ "sec1", "sha2 0.10.8", "sha3", - "soroban-builtin-sdk-macros", - "soroban-env-common", - "soroban-wasmi", + "soroban-builtin-sdk-macros 21.2.1", + "soroban-env-common 21.2.1", + "soroban-wasmi 0.31.1-soroban.20.0.1", "static_assertions", "stellar-strkey 0.0.8", "wasmparser 0.116.1", ] +[[package]] +name = "soroban-env-host" +version = "22.0.0-rc.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c695d22888ede1f98c016a4a690be307817d133be0e0f32a25fd6e53bb6c929" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", + "curve25519-dalek 4.1.3", + "ecdsa", + "ed25519-dalek 2.1.1", + "elliptic-curve", + "generic-array", + "getrandom", + "hex-literal", + "hmac 0.12.1", + "k256", + "num-derive", + "num-integer", + "num-traits", + "p256", + "rand", + "rand_chacha", + "sec1", + "sha2 0.10.8", + "sha3", + "soroban-builtin-sdk-macros 22.0.0-rc.1.1", + "soroban-env-common 22.0.0-rc.1.1", + "soroban-wasmi 0.36.1-soroban.22.0.0", + "static_assertions", + "stellar-strkey 0.0.9", + "wasmparser 0.116.1", +] + [[package]] name = "soroban-env-macros" version = "21.2.1" @@ -5288,7 +4649,22 @@ dependencies = [ "quote", "serde", "serde_json", - "stellar-xdr", + "stellar-xdr 21.2.0", + "syn 2.0.77", +] + +[[package]] +name = "soroban-env-macros" +version = "22.0.0-rc.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d926d0daa3ba798cd70ce962ea10012e630d75088352369a6d248b2644dd7a2c" +dependencies = [ + "itertools 0.10.5", + "proc-macro2", + "quote", + "serde", + "serde_json", + "stellar-xdr 22.0.0-rc.1.1", "syn 2.0.77", ] @@ -5298,15 +4674,29 @@ version = "21.5.0" [[package]] name = "soroban-ledger-snapshot" -version = "21.7.2" +version = "21.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84589856911dfd6731695c9b51c858aed6d4540118c0a1e5c4c858ea13bc744c" +dependencies = [ + "serde", + "serde_json", + "serde_with", + "soroban-env-common 21.2.1", + "soroban-env-host 21.2.1", + "thiserror", +] + +[[package]] +name = "soroban-ledger-snapshot" +version = "22.0.0-rc.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf596b2083946a95914a55d7d29cee6a8095b515fd06211851f45bf6af5a496" +checksum = "c07ca63290730b803f0637e00994f803d2f24cc6383ac8680724050d07690a89" dependencies = [ "serde", "serde_json", "serde_with", - "soroban-env-common", - "soroban-env-host", + "soroban-env-common 22.0.0-rc.1.1", + "soroban-env-host 22.0.0-rc.1.1", "thiserror", ] @@ -5323,18 +4713,35 @@ dependencies = [ "rand", "serde", "serde_json", - "soroban-env-guest", - "soroban-env-host", - "soroban-ledger-snapshot", - "soroban-sdk-macros", + "soroban-env-guest 21.2.1", + "soroban-env-host 21.2.1", + "soroban-ledger-snapshot 21.7.3", + "soroban-sdk-macros 21.7.3", "stellar-strkey 0.0.8", ] +[[package]] +name = "soroban-sdk" +version = "22.0.0-rc.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b715e15357dbdda2fe0626005b75c2253bb3786deec3001d4077462a9dadd3" +dependencies = [ + "bytes-lit", + "rand", + "serde", + "serde_json", + "soroban-env-guest 22.0.0-rc.1.1", + "soroban-env-host 22.0.0-rc.1.1", + "soroban-ledger-snapshot 22.0.0-rc.1.1", + "soroban-sdk-macros 22.0.0-rc.1.1", + "stellar-strkey 0.0.9", +] + [[package]] name = "soroban-sdk-macros" -version = "21.7.2" +version = "21.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da03fa00b8ca6e392f013359c06d790d2d379f9c8d6f8a6dfe563ec64311e5d3" +checksum = "63c2173f1aacd56b4405eed71cb2a9694dff99d51ba72d4f0cbc5e4961fdabf4" dependencies = [ "crate-git-revision 0.0.6", "darling", @@ -5343,21 +4750,53 @@ dependencies = [ "quote", "rustc_version", "sha2 0.10.8", - "soroban-env-common", - "soroban-spec", - "soroban-spec-rust", - "stellar-xdr", + "soroban-env-common 21.2.1", + "soroban-spec 21.7.3", + "soroban-spec-rust 21.7.3", + "stellar-xdr 21.2.0", + "syn 2.0.77", +] + +[[package]] +name = "soroban-sdk-macros" +version = "22.0.0-rc.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d1b8d96ccf53ea9c30d86352756cace630ca5c7e1200fff32ffc793bedd593" +dependencies = [ + "crate-git-revision 0.0.6", + "darling", + "itertools 0.10.5", + "proc-macro2", + "quote", + "rustc_version", + "sha2 0.10.8", + "soroban-env-common 22.0.0-rc.1.1", + "soroban-spec 22.0.0-rc.1.1", + "soroban-spec-rust 22.0.0-rc.1.1", + "stellar-xdr 22.0.0-rc.1.1", "syn 2.0.77", ] [[package]] name = "soroban-spec" -version = "21.7.2" +version = "21.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7705bffbcc747c08e81698b87b4a787f8b268c25d88f777160091dc1ee8121cb" +dependencies = [ + "base64 0.13.1", + "stellar-xdr 21.2.0", + "thiserror", + "wasmparser 0.116.1", +] + +[[package]] +name = "soroban-spec" +version = "22.0.0-rc.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c723195463d8742bcb481520bd8b8325da66c39ea236ad46261e6af992e8a8" +checksum = "4603430fd36848da7189e758d7f3fe1d7bbfef024e8aad2230a8be8252a583c1" dependencies = [ "base64 0.13.1", - "stellar-xdr", + "stellar-xdr 22.0.0-rc.1.1", "thiserror", "wasmparser 0.116.1", ] @@ -5371,23 +4810,39 @@ dependencies = [ "serde_derive", "serde_json", "sha2 0.9.9", - "soroban-spec", - "stellar-xdr", + "soroban-spec 22.0.0-rc.1.1", + "stellar-xdr 22.0.0-rc.1.1", "thiserror", ] [[package]] name = "soroban-spec-rust" -version = "21.7.2" +version = "21.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48207ebc8616c2804a17203d1d86c53c3d3c804b682cbab011a135893db1cf78" +dependencies = [ + "prettyplease", + "proc-macro2", + "quote", + "sha2 0.10.8", + "soroban-spec 21.7.3", + "stellar-xdr 21.2.0", + "syn 2.0.77", + "thiserror", +] + +[[package]] +name = "soroban-spec-rust" +version = "22.0.0-rc.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f1b0ec2af54e38f138910f09e101b100130efe625f69ece51c76dd4f06f8b2" +checksum = "f5d5f3fe5b27e0b1c1d9ecdff04c4e31f5cd4d12cdc052d54f0e4995cf637b9c" dependencies = [ "prettyplease", "proc-macro2", "quote", "sha2 0.10.8", - "soroban-spec", - "stellar-xdr", + "soroban-spec 22.0.0-rc.1.1", + "stellar-xdr 22.0.0-rc.1.1", "syn 2.0.77", "thiserror", ] @@ -5401,10 +4856,9 @@ dependencies = [ "hex", "itertools 0.10.5", "serde_json", - "soroban-env-host", - "soroban-spec", + "soroban-spec 22.0.0-rc.1.1", "stellar-strkey 0.0.11", - "stellar-xdr", + "stellar-xdr 22.0.0-rc.1.1", "thiserror", "tokio", "wasmparser 0.90.0", @@ -5425,8 +4879,8 @@ dependencies = [ "serde_derive", "serde_json", "sha2 0.9.9", - "soroban-spec", - "stellar-xdr", + "soroban-spec 22.0.0-rc.1.1", + "stellar-xdr 22.0.0-rc.1.1", "temp-dir", "thiserror", "walkdir", @@ -5446,10 +4900,8 @@ dependencies = [ "serde_json", "sha2 0.10.8", "soroban-cli", - "soroban-env-host", - "soroban-ledger-snapshot", - "soroban-sdk", - "soroban-spec", + "soroban-ledger-snapshot 22.0.0-rc.1.1", + "soroban-spec 22.0.0-rc.1.1", "soroban-spec-tools", "stellar-rpc-client", "stellar-strkey 0.0.11", @@ -5467,7 +4919,7 @@ version = "21.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c6ede0da76646037f3ea5db9ccd37830865444bb24f137cb8f0af8282c784f5" dependencies = [ - "soroban-sdk", + "soroban-sdk 21.7.2", ] [[package]] @@ -5479,7 +4931,24 @@ dependencies = [ "smallvec", "spin", "wasmi_arena", - "wasmi_core", + "wasmi_core 0.13.0", + "wasmparser-nostd", +] + +[[package]] +name = "soroban-wasmi" +version = "0.36.1-soroban.22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7044ea0ee6ff67039df1f232f0d3d98121f69a0409e944774912fc5f043c280f" +dependencies = [ + "arrayvec", + "multi-stash", + "num-derive", + "num-traits", + "smallvec", + "spin", + "wasmi_collections", + "wasmi_core 0.36.3", "wasmparser-nostd", ] @@ -5539,11 +5008,10 @@ dependencies = [ "serial_test", "sha2 0.9.9", "slip10", - "soroban-env-host", - "soroban-spec", + "soroban-spec 22.0.0-rc.1.1", "stellar-rpc-client", "stellar-strkey 0.0.11", - "stellar-xdr", + "stellar-xdr 22.0.0-rc.1.1", "test-case", "testcontainers", "thiserror", @@ -5554,8 +5022,7 @@ dependencies = [ [[package]] name = "stellar-rpc-client" version = "21.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c735c8e456fa7c37f72dd2a6abc022a111b3bf9b0520d50eef091eb1336ad370" +source = "git+https://github.com/stellar/rs-stellar-rpc-client?branch=main#7554d4c87c026313a1f5b3c7ae66a92b5ff7e091" dependencies = [ "clap", "hex", @@ -5566,9 +5033,10 @@ dependencies = [ "serde", "serde-aux", "serde_json", + "serde_with", "sha2 0.10.8", - "stellar-strkey 0.0.8", - "stellar-xdr", + "stellar-strkey 0.0.9", + "stellar-xdr 22.0.0-rc.1.1", "termcolor", "termcolor_output", "thiserror", @@ -5587,6 +5055,17 @@ dependencies = [ "thiserror", ] +[[package]] +name = "stellar-strkey" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e3aa3ed00e70082cb43febc1c2afa5056b9bb3e348bbb43d0cd0aa88a611144" +dependencies = [ + "crate-git-revision 0.0.6", + "data-encoding", + "thiserror", +] + [[package]] name = "stellar-strkey" version = "0.0.11" @@ -5604,6 +5083,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2675a71212ed39a806e415b0dbf4702879ff288ec7f5ee996dda42a135512b50" dependencies = [ "arbitrary", + "base64 0.13.1", + "crate-git-revision 0.0.6", + "escape-bytes", + "hex", + "serde", + "serde_with", + "stellar-strkey 0.0.8", +] + +[[package]] +name = "stellar-xdr" +version = "22.0.0-rc.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c88dc0e928b9cb65ea43836b52560bb4ead3e32895f5019ca223dc7cd1966cbf" +dependencies = [ "base64 0.13.1", "clap", "crate-git-revision 0.0.6", @@ -5613,10 +5107,21 @@ dependencies = [ "serde", "serde_json", "serde_with", - "stellar-strkey 0.0.8", + "stellar-strkey 0.0.9", "thiserror", ] +[[package]] +name = "string-interner" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6a0d765f5807e98a091107bae0a56ea3799f66a5de47b2c84c94a39c09974e" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "serde", +] + [[package]] name = "string_cache" version = "0.8.7" @@ -5864,35 +5369,35 @@ dependencies = [ name = "test_custom_account" version = "21.5.0" dependencies = [ - "soroban-sdk", + "soroban-sdk 21.7.2", ] [[package]] name = "test_custom_types" version = "21.5.0" dependencies = [ - "soroban-sdk", + "soroban-sdk 21.7.2", ] [[package]] name = "test_hello_world" version = "21.5.0" dependencies = [ - "soroban-sdk", + "soroban-sdk 21.7.2", ] [[package]] name = "test_swap" version = "21.5.0" dependencies = [ - "soroban-sdk", + "soroban-sdk 21.7.2", ] [[package]] name = "test_token" version = "21.5.0" dependencies = [ - "soroban-sdk", + "soroban-sdk 21.7.2", "soroban-token-sdk", ] @@ -5900,7 +5405,7 @@ dependencies = [ name = "test_udt" version = "21.5.0" dependencies = [ - "soroban-sdk", + "soroban-sdk 21.7.2", ] [[package]] @@ -5970,9 +5475,7 @@ checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", - "libc", "num-conv", - "num_threads", "powerfmt", "serde", "time-core", @@ -6320,12 +5823,6 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" -[[package]] -name = "unicode-bom" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" - [[package]] name = "unicode-ident" version = "1.0.12" @@ -6555,9 +6052,9 @@ dependencies = [ [[package]] name = "wasm-streams" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" dependencies = [ "futures-util", "js-sys", @@ -6572,6 +6069,17 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "104a7f73be44570cac297b3035d76b169d6599637631cf37a1703326a0727073" +[[package]] +name = "wasmi_collections" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ee1cf2328e7fbb8654fda8449395c64c36ef5a30511e79fae0265a96e1a446" +dependencies = [ + "ahash", + "hashbrown 0.14.5", + "string-interner", +] + [[package]] name = "wasmi_core" version = "0.13.0" @@ -6584,6 +6092,18 @@ dependencies = [ "paste", ] +[[package]] +name = "wasmi_core" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e77c1e701d21edfd263e5c6c940861202c6b840c715040cfdca6211bf8857aa" +dependencies = [ + "downcast-rs", + "libm", + "num-traits", + "paste", +] + [[package]] name = "wasmparser" version = "0.90.0" @@ -6632,12 +6152,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "webpki-roots" version = "0.26.3" diff --git a/Cargo.toml b/Cargo.toml index 7282ff497..ef052c569 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,17 +14,10 @@ exclude = ["cmd/crates/soroban-test/tests/fixtures/hello"] version = "21.5.0" rust-version = "1.81.0" -[workspace.dependencies.soroban-env-host] -version = "=21.2.1" - -[workspace.dependencies.soroban-simulation] -version = "=21.2.1" - -[workspace.dependencies.soroban-spec] -version = "=21.7.2" - -[workspace.dependencies.soroban-spec-rust] -version = "=21.7.2" +# Dependencies located in this repo: +[workspace.dependencies.soroban-cli] +version = "=21.5.0" +path = "cmd/soroban-cli" [workspace.dependencies.soroban-spec-json] version = "=21.5.0" @@ -38,27 +31,35 @@ path = "./cmd/crates/soroban-spec-typescript" version = "21.5.0" path = "./cmd/crates/soroban-spec-tools" +# Dependencies from the rs-stellar-xdr repo: +[workspace.dependencies.stellar-xdr] +version = "=22.0.0-rc.1.1" +default-features = true + +# Dependencies from the rs-soroban-sdk repo: +[workspace.dependencies.soroban-spec] +version = "=22.0.0-rc.1.1" + +[workspace.dependencies.soroban-spec-rust] +version = "=22.0.0-rc.1.1" + [workspace.dependencies.soroban-sdk] -version = "=21.7.2" +version = "=22.0.0-rc.1.1" [workspace.dependencies.soroban-token-sdk] -version = "=21.7.2" +version = "=22.0.0-rc.1.1" [workspace.dependencies.soroban-ledger-snapshot] -version = "=21.7.2" - -[workspace.dependencies.soroban-cli] -version = "=21.5.0" -path = "cmd/soroban-cli" +version = "=22.0.0-rc.1.1" +# Dependencies from the rs-stellar-rpc-client repo: [workspace.dependencies.soroban-rpc] package = "stellar-rpc-client" version = "21.4.0" +git = "https://github.com/stellar/rs-stellar-rpc-client" +branch = "main" -[workspace.dependencies.stellar-xdr] -version = "21.2.0" -default-features = true - +# Dependencies from elsewhere shared by crates: [workspace.dependencies] stellar-strkey = "0.0.11" sep5 = "0.0.4" @@ -70,11 +71,9 @@ hex = "0.4.3" itertools = "0.10.0" async-trait = "0.1.76" bollard = "0.16.0" - serde-aux = "4.1.2" serde_json = "1.0.82" serde = "1.0.82" - clap = { version = "4.1.8", features = [ "derive", "env", @@ -92,8 +91,7 @@ ulid = "1.1" termcolor = "1.1.3" termcolor_output = "1.0.1" ed25519-dalek = ">= 2.1.1" - -# networking +http = "1.0.0" jsonrpsee-http-client = "0.20.1" jsonrpsee-core = "0.20.1" tokio = "1.28.1" diff --git a/FULL_HELP_DOCS.md b/FULL_HELP_DOCS.md index 5128ce396..41575aea0 100644 --- a/FULL_HELP_DOCS.md +++ b/FULL_HELP_DOCS.md @@ -84,7 +84,7 @@ Tools for smart contract developers * `fetch` — Fetch a contract's Wasm binary * `id` — Generate the contract id for a given contract or asset * `info` — Access info about contracts -* `init` — Initialize a Soroban project with an example contract +* `init` — Initialize a Soroban contract project * `inspect` — (Deprecated in favor of `contract info` subcommands) Inspect a WASM file listing contract functions, meta, etc * `install` — Install a WASM file to the ledger without creating a contract instance * `invoke` — Invoke a contract function @@ -117,6 +117,7 @@ Get Id of builtin Soroban Asset Contract. Deprecated, use `stellar contract id a * `--asset ` — ID of the Stellar classic asset to wrap, e.g. "USDC:G...5" * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--global` — Use global config @@ -134,6 +135,7 @@ Deploy builtin Soroban Asset Contract * `--asset ` — ID of the Stellar classic asset to wrap, e.g. "USDC:G...5" * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -146,7 +148,7 @@ Deploy builtin Soroban Asset Contract * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout @@ -180,6 +182,7 @@ Remove contract alias * `--global` — Use global config * `--config-dir ` — Location of config directory, default is "." * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config @@ -200,6 +203,7 @@ Add contract alias * `--global` — Use global config * `--config-dir ` — Location of config directory, default is "." * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--overwrite` — Overwrite the contract alias if it already exists @@ -222,6 +226,7 @@ Show the contract id associated with a given alias * `--global` — Use global config * `--config-dir ` — Location of config directory, default is "." * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config @@ -293,6 +298,7 @@ Generate a TypeScript / JavaScript package * `--global` — Use global config * `--config-dir ` — Location of config directory, default is "." * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config @@ -359,6 +365,7 @@ If no keys are specified the contract itself is extended. Temporary * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -371,7 +378,7 @@ If no keys are specified the contract itself is extended. * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout @@ -387,6 +394,7 @@ Deploy a wasm contract * `--wasm-hash ` — Hash of the already installed/deployed WASM file * `--salt ` — Custom salt 32-byte salt for the token id * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -399,7 +407,7 @@ Deploy a wasm contract * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout * `-i`, `--ignore-checks` — Whether to ignore safety checks when deploying contracts Default value: `false` @@ -420,6 +428,7 @@ Fetch a contract's Wasm binary * `--global` — Use global config * `--config-dir ` — Location of config directory, default is "." * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config @@ -448,6 +457,7 @@ Deploy builtin Soroban Asset Contract * `--asset ` — ID of the Stellar classic asset to wrap, e.g. "USDC:G...5" * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--global` — Use global config @@ -465,6 +475,7 @@ Deploy normal Wasm Contract * `--salt ` — ID of the Soroban contract * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -506,6 +517,7 @@ Outputs no data when no data is present in the contract. * `--wasm-hash ` — Wasm hash to get the data for * `--id ` — Contract id to get the data for * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--global` — Use global config @@ -545,6 +557,7 @@ Outputs no data when no data is present in the contract. * `--wasm-hash ` — Wasm hash to get the data for * `--id ` — Contract id to get the data for * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--global` — Use global config @@ -584,6 +597,7 @@ Outputs no data when no data is present in the contract. * `--wasm-hash ` — Wasm hash to get the data for * `--id ` — Contract id to get the data for * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--global` — Use global config @@ -607,7 +621,9 @@ Outputs no data when no data is present in the contract. ## `stellar contract init` -Initialize a Soroban project with an example contract +Initialize a Soroban contract project. + +This command will create a Cargo workspace project and add a sample Stellar contract. The name of the contract can be specified by `--name`. It can be run multiple times with different names in order to generate multiple contracts, and files won't be overwritten unless `--overwrite` is passed. **Usage:** `stellar contract init [OPTIONS] ` @@ -617,13 +633,9 @@ Initialize a Soroban project with an example contract ###### **Options:** -* `-w`, `--with-example ` — An optional flag to specify Soroban example contracts to include. A hello-world contract will be included by default. - - Possible values: `account`, `alloc`, `atomic_multiswap`, `atomic_swap`, `auth`, `cross_contract`, `custom_types`, `deep_contract_auth`, `deployer`, `errors`, `eth_abi`, `events`, `fuzzing`, `increment`, `liquidity_pool`, `logging`, `mint-lock`, `other_custom_types`, `simple_account`, `single_offer`, `timelock`, `token`, `ttl`, `upgradeable_contract`, `workspace` +* `--name ` — An optional flag to specify a new contract's name. -* `--frontend-template ` — An optional flag to pass in a url for a frontend template repository. - - Default value: `` + Default value: `hello-world` * `--overwrite` — Overwrite all existing files. @@ -663,6 +675,7 @@ Install a WASM file to the ledger without creating a contract instance ###### **Options:** * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -675,7 +688,7 @@ Install a WASM file to the ledger without creating a contract instance * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout * `--wasm ` — Path to wasm binary * `-i`, `--ignore-checks` — Whether to ignore safety checks when deploying contracts @@ -702,6 +715,7 @@ stellar contract invoke ... -- --help * `--id ` — Contract ID to invoke * `--is-view` — View the result simulating and do not sign and submit transaction. Deprecated use `--send=no` * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -714,7 +728,7 @@ stellar contract invoke ... -- --help * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout * `--send ` — Whether or not to send a transaction Default value: `default` @@ -747,7 +761,7 @@ Optimize a WASM file Print the current value of a contract-data ledger entry -**Usage:** `stellar contract read [OPTIONS] --source-account ` +**Usage:** `stellar contract read [OPTIONS]` ###### **Options:** @@ -779,10 +793,9 @@ Print the current value of a contract-data ledger entry Temporary * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config -* `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail -* `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config * `--config-dir ` — Location of config directory, default is "." @@ -816,6 +829,7 @@ If no keys are specificed the contract itself is restored. * `--ledgers-to-extend ` — Number of ledgers to extend the entry * `--ttl-ledger-only` — Only print the new Time To Live ledger * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -828,7 +842,7 @@ If no keys are specificed the contract itself is restored. * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout @@ -876,6 +890,7 @@ Watch the network for contract events * `--global` — Use global config * `--config-dir ` — Location of config directory, default is "." * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config @@ -949,6 +964,7 @@ Fund an identity on a test network ###### **Options:** * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--hd-path ` — If identity is a seed phrase use this hd path, default is 0 @@ -977,8 +993,12 @@ Generate a new identity with a seed phrase, currently 12 words * `--hd-path ` — When generating a secret key, which `hd_path` should be used from the original `seed_phrase` * `-d`, `--default-seed` — Generate the default seed phrase. Useful for testing. Equivalent to --seed 0000000000000000 * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config +* `--fund` — Fund generated key pair + + Default value: `false` @@ -1061,6 +1081,7 @@ Add a new network ###### **Options:** * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — Optional header (e.g. API Key) to include in requests to the RPC * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--global` — Use global config * `--config-dir ` — Location of config directory, default is "." @@ -1248,18 +1269,20 @@ Create a ledger snapshot using a history archive. Filters (address, wasm-hash) specify what ledger entries to include. -Account addresses include the account, and trust lines. +Account addresses include the account, and trustlines. Contract addresses include the related wasm, contract data. If a contract is a Stellar asset contract, it includes the asset issuer's account and trust lines, but does not include all the trust lines of other accounts holding the asset. To include them specify the addresses of relevant accounts. +Any invalid contract id passed as `--address` will be ignored. + **Usage:** `stellar snapshot create [OPTIONS] --output ` ###### **Options:** * `--ledger ` — The ledger sequence number to snapshot. Defaults to latest history archived ledger -* `--address
` — Account or contract address to include in the snapshot +* `--address
` — Account or contract address/alias to include in the snapshot * `--wasm-hash ` — WASM hashes to include in the snapshot * `--output ` — Format of the out file @@ -1271,6 +1294,7 @@ If a contract is a Stellar asset contract, it includes the asset issuer's accoun * `--global` — Use global config * `--config-dir ` — Location of config directory, default is "." * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--archive-url ` — Archive URL @@ -1302,6 +1326,7 @@ Simulate a transaction envelope from stdin ###### **Options:** * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -1320,6 +1345,7 @@ Calculate the hash of a transaction envelope from stdin ###### **Options:** * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config @@ -1337,6 +1363,7 @@ Sign a transaction envelope appending the signature to the envelope * `--hd-path ` — If using a seed phrase to sign, sets which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--sign-with-lab` — Sign with https://lab.stellar.org * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--global` — Use global config @@ -1353,6 +1380,7 @@ Send a transaction envelope to the network ###### **Options:** * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--global` — Use global config @@ -1393,8 +1421,9 @@ Transfers the XLM balance of an account to another account and removes the sourc * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -1419,8 +1448,9 @@ Bumps forward the sequence number of the source account to the given sequence nu * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -1445,8 +1475,9 @@ Creates, updates, or deletes a trustline Learn more about trustlines https://dev * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -1474,8 +1505,9 @@ Creates and funds a new account with the specified starting balance * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -1503,8 +1535,9 @@ Sets, modifies, or deletes a data entry (name/value pair) that is attached to an * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -1530,8 +1563,9 @@ Sends an amount in a specific asset to a destination account * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -1560,8 +1594,9 @@ Set option for an account such as flags, inflation destination, signers, home do * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -1601,8 +1636,9 @@ Allows issuing account to configure authorization and trustline flags to an asse * `--cost` — Output the cost execution to stderr * `--instructions ` — Number of instructions to simulate * `--build-only` — Build the transaction and only write the base64 xdr to stdout -* `--sim-only` — Simulate the transaction and only write the base64 xdr to stdout +* `--sim-only` — (Deprecated) simulate the transaction and only write the base64 xdr to stdout * `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config * `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail @@ -1632,6 +1668,7 @@ Decode and encode XDR * `guess` — Guess the XDR type * `decode` — Decode XDR * `encode` — Encode XDR +* `compare` — Compare two XDR values with each other * `version` — Print version information ###### **Arguments:** @@ -1770,6 +1807,31 @@ Encode XDR Default value: `single-base64` + Possible values: `single`, `single-base64`, `stream` + + + + +## `stellar xdr compare` + +Compare two XDR values with each other + +Outputs: `-1` when the left XDR value is less than the right XDR value, `0` when the left XDR value is equal to the right XDR value, `1` when the left XDR value is greater than the right XDR value + +**Usage:** `stellar xdr compare [OPTIONS] --type ` + +###### **Arguments:** + +* `` — XDR file to decode and compare with the right value +* `` — XDR file to decode and compare with the left value + +###### **Options:** + +* `--type ` — XDR type of both inputs +* `--input ` + + Default value: `single-base64` + Possible values: `single`, `single-base64` diff --git a/Makefile b/Makefile index 6d55aacc4..4db0946ce 100644 --- a/Makefile +++ b/Makefile @@ -46,11 +46,6 @@ build-test: build-test-wasms install generate-full-help-doc: cargo run --bin doc-gen --features clap-markdown -generate-examples-list: - curl -sSL https://api.github.com/repos/stellar/soroban-examples/git/trees/main \ - | jq -r '.tree[] | select(.type != "blob" and .path != "hello_world" and (.path | startswith(".") | not)) | .path' \ - > cmd/soroban-cli/example_contracts.list - test: build-test cargo test diff --git a/README.md b/README.md index c39d883c2..8fadb6740 100644 --- a/README.md +++ b/README.md @@ -10,16 +10,13 @@ This repo is home to the Stellar CLI, the command-line multi-tool for running an - [Documentation](#documentation) - [Cookbook](#cookbook) -- [Installation](#installation) -- [Installation with Experimental Features](#installation-with-experimental-features) +- [Install](#install) - [Autocomplete](#autocomplete) - [Latest Release](#latest-release) - [Upcoming Features](#upcoming-features) - [To Contribute](#to-contribute) - [Additional Developer Resources](#additional-developer-resources) - - ## Documentation For installation options see below, for usage instructions [see the full help docs](FULL_HELP_DOCS.md). @@ -27,28 +24,17 @@ For installation options see below, for usage instructions [see the full help do ## Cookbook To understand how to get the most of the Stellar CLI, see the [Stellar CLI Cookbook](https://github.com/stellar/stellar-cli/tree/main/cookbook) for recipes and a collection of resources to teach you how to use the CLI. Examples of recipes included in the CLI cookbook include: send payments, manage contract lifecycle, extend contract instance/storage/wasm, and more. -## Installation -Install the latest version from source: -``` -cargo install --locked stellar-cli --features opt -``` +## Install -Install with `cargo-binstall`: -``` -cargo install --locked cargo-binstall -cargo binstall -y stellar-cli -``` - -Install with Homebrew: +Install with Homebrew (macOS, Linux): ``` brew install stellar-cli ``` -## Installation with Experimental Features -To use the potentially unreleased bleeding edge CLI functionalities, install from git: +Install the latest version from source: ``` -cargo install --locked stellar-cli --features opt --git https://github.com/stellar/stellar-cli.git +cargo install --locked stellar-cli --features opt ``` ## Autocomplete diff --git a/action.yml b/action.yml new file mode 100644 index 000000000..9b1426d94 --- /dev/null +++ b/action.yml @@ -0,0 +1,64 @@ +name: 'Install stellar-cli' +description: 'Install the stellar-cli' +inputs: + version: + description: | + Recommended for use only in testing new versions of the action prior to + release. For regular use, use the version of the action corresponding to + the version of the stellar-cli that should be installed. + required: false +runs: + using: "composite" + steps: + - name: Setup install path + shell: bash + run: | + mkdir -p $HOME/.local/bin + echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: Determine version to install + id: version + shell: bash + run: | + echo "version=${{ inputs.version || github.action_ref }}" >> "$GITHUB_OUTPUT" + - name: Copy binary to install location + shell: bash + run: | + version="${{ steps.version.outputs.version }}" + case "${{ runner.os }}-${{ runner.arch }}" in + 'Linux-X64') + os_arch=x86_64-unknown-linux-gnu + ;; + 'Linux-ARM64') + os_arch=aarch64-unknown-linux-gnu + ;; + 'macOS-X64') + os_arch=x86_64-apple-darwin + ;; + 'macOS-ARM64') + os_arch=aarch64-apple-darwin + ;; + 'Windows-X64') + os_arch=x86_64-pc-windows-msvc + ;; + *) + echo "Unsupported OS / Arch pair: ${{ runner.os }} ${{ runner.arch }}" >&2 + exit 1 + esac + file="stellar-cli-$version-$os_arch.tar.gz" + url="https://github.com/stellar/stellar-cli/releases/download/v$version/$file" + echo "$url" + curl -fL "$url" | tar xvz -C $HOME/.local/bin + - name: Verify binary against attestation + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + version="${{ steps.version.outputs.version }}" + subject="$(gh attestation verify ~/.local/bin/stellar --repo stellar/stellar-cli --format json -q '.[].verificationResult.signature.certificate.subjectAlternativeName')" + echo "Found subject: $subject" >&2 + expected_subject="https://github.com/stellar/stellar-cli/.github/workflows/binaries.yml@refs/tags/v$version" + echo "Expected subject: $expected_subject" >&2 + if [[ "$subject" != "$expected_subject" ]]; then + echo "Attestation verification found unexpected subject" >&2 + exit 1 + fi diff --git a/cmd/crates/soroban-spec-tools/Cargo.toml b/cmd/crates/soroban-spec-tools/Cargo.toml index 514b82924..a17a5d31f 100644 --- a/cmd/crates/soroban-spec-tools/Cargo.toml +++ b/cmd/crates/soroban-spec-tools/Cargo.toml @@ -19,9 +19,7 @@ crate-type = ["rlib"] [dependencies] soroban-spec = { workspace = true } stellar-strkey = { workspace = true } -stellar-xdr = { workspace = true, features = ["curr", "std", "serde"] } -soroban-env-host = { workspace = true } - +stellar-xdr = { workspace = true, features = ["curr", "std", "serde", "base64"] } serde_json = { workspace = true } itertools = { workspace = true } ethnum = { workspace = true } @@ -29,9 +27,6 @@ hex = { workspace = true } wasmparser = { workspace = true } base64 = { workspace = true } thiserror = "1.0.31" -# soroban-ledger-snapshot = { workspace = true } -# soroban-sdk = { workspace = true } -# sep5 = { workspace = true } [dev-dependencies] diff --git a/cmd/crates/soroban-spec-tools/src/contract.rs b/cmd/crates/soroban-spec-tools/src/contract.rs index 334b2425f..9984a19d1 100644 --- a/cmd/crates/soroban-spec-tools/src/contract.rs +++ b/cmd/crates/soroban-spec-tools/src/contract.rs @@ -4,10 +4,10 @@ use std::{ io::{self, Cursor}, }; -use soroban_env_host::xdr::{ - self, Limited, Limits, ReadXdr, ScEnvMetaEntry, ScMetaEntry, ScMetaV0, ScSpecEntry, - ScSpecFunctionV0, ScSpecUdtEnumV0, ScSpecUdtErrorEnumV0, ScSpecUdtStructV0, ScSpecUdtUnionV0, - StringM, WriteXdr, +use stellar_xdr::curr::{ + self as xdr, Limited, Limits, ReadXdr, ScEnvMetaEntry, ScEnvMetaEntryInterfaceVersion, + ScMetaEntry, ScMetaV0, ScSpecEntry, ScSpecFunctionV0, ScSpecUdtEnumV0, ScSpecUdtErrorEnumV0, + ScSpecUdtStructV0, ScSpecUdtUnionV0, StringM, WriteXdr, }; pub struct Spec { @@ -121,10 +121,16 @@ impl Display for Spec { writeln!(f, "Env Meta: {env_meta}")?; for env_meta_entry in &self.env_meta { match env_meta_entry { - ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(v) => { - let protocol = v >> 32; - let interface = v & 0xffff_ffff; - writeln!(f, " • Interface Version: {v} (protocol: {protocol}, interface: {interface})")?; + ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion( + ScEnvMetaEntryInterfaceVersion { + protocol, + pre_release, + }, + ) => { + writeln!(f, " • Protocol Version: {protocol}")?; + if pre_release != &0 { + writeln!(f, " • Pre-release Version: {pre_release})")?; + } } } } diff --git a/cmd/crates/soroban-test/Cargo.toml b/cmd/crates/soroban-test/Cargo.toml index a34b7c65c..b240494e4 100644 --- a/cmd/crates/soroban-test/Cargo.toml +++ b/cmd/crates/soroban-test/Cargo.toml @@ -17,12 +17,10 @@ crate-type = ["rlib", "cdylib"] [dependencies] -soroban-env-host = { workspace = true } soroban-spec = { workspace = true } soroban-spec-tools = { workspace = true } soroban-ledger-snapshot = { workspace = true } stellar-strkey = { workspace = true } -soroban-sdk = { workspace = true } sep5 = { workspace = true } soroban-cli = { workspace = true } soroban-rpc = { workspace = true } diff --git a/cmd/crates/soroban-test/src/lib.rs b/cmd/crates/soroban-test/src/lib.rs index 849b78796..2c62578ef 100644 --- a/cmd/crates/soroban-test/src/lib.rs +++ b/cmd/crates/soroban-test/src/lib.rs @@ -235,6 +235,7 @@ impl TestEnv { config::Args { network: network::Args { rpc_url: Some(self.rpc_url.clone()), + rpc_headers: [].to_vec(), network_passphrase: Some(LOCAL_NETWORK_PASSPHRASE.to_string()), network: None, }, diff --git a/cmd/crates/soroban-test/src/wasm.rs b/cmd/crates/soroban-test/src/wasm.rs index d03114b93..3e473ed46 100644 --- a/cmd/crates/soroban-test/src/wasm.rs +++ b/cmd/crates/soroban-test/src/wasm.rs @@ -1,7 +1,7 @@ use std::{fmt::Display, fs, path::PathBuf}; use sha2::{Digest, Sha256}; -use soroban_env_host::xdr; +use soroban_cli::xdr; #[derive(thiserror::Error, Debug)] pub enum Error { diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_account/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_account/Cargo.toml index d4405c512..792925edb 100644 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_account/Cargo.toml +++ b/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_account/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["cdylib"] doctest = false [dependencies] -soroban-sdk = { workspace = true } +soroban-sdk = { version = "=21.7.2" } [dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"]} +soroban-sdk = { version = "=21.7.2", features = ["testutils"]} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/Cargo.toml index 17e618805..398520104 100644 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/Cargo.toml +++ b/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] doctest = false [dependencies] -soroban-sdk = { workspace = true } +soroban-sdk = { version = "=21.7.2" } [dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"]} +soroban-sdk = { version = "=21.7.2", features = ["testutils"]} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/Cargo.toml index 9ad83fd1c..5f8b1256f 100644 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/Cargo.toml +++ b/cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] doctest = false [dependencies] -soroban-sdk = { workspace = true } +soroban-sdk = { version = "=21.7.2" } [dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"]} +soroban-sdk = { version = "=21.7.2", features = ["testutils"]} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/Cargo.toml index f74201a31..509483408 100644 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/Cargo.toml +++ b/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["cdylib"] doctest = false [dependencies] -soroban-sdk = { workspace = true } +soroban-sdk = { version = "=21.7.2" } [dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"] } +soroban-sdk = { version = "=21.7.2", features = ["testutils"] } diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/Cargo.toml index 880c39d52..03055f2b7 100644 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/Cargo.toml +++ b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/Cargo.toml @@ -12,8 +12,8 @@ rust-version.workspace = true crate-type = ["cdylib"] [dependencies] -soroban-sdk = { workspace = true } -soroban-token-sdk = { workspace = true } +soroban-sdk = { version = "=21.7.2" } +soroban-token-sdk = { version = "=21.7.2" } [dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"] } +soroban-sdk = { version = "=21.7.2", features = ["testutils"] } diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/Cargo.toml index 206284802..aea356447 100644 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/Cargo.toml +++ b/cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["cdylib"] doctest = false [dependencies] -soroban-sdk = { workspace = true } +soroban-sdk = { version = "=21.7.2" } [dev-dependencies] -soroban-sdk = { workspace = true , features = ["testutils"]} +soroban-sdk = { version = "=21.7.2" , features = ["testutils"]} diff --git a/cmd/crates/soroban-test/tests/fixtures/workspace-with-default-members/contracts/add/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/workspace-with-default-members/contracts/add/Cargo.toml index 660b7eb11..ca38cca49 100644 --- a/cmd/crates/soroban-test/tests/fixtures/workspace-with-default-members/contracts/add/Cargo.toml +++ b/cmd/crates/soroban-test/tests/fixtures/workspace-with-default-members/contracts/add/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] doctest = false [dependencies] -soroban-sdk = { workspace = true } +soroban-sdk = { version = "=21.7.2" } [dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"] } +soroban-sdk = { version = "=21.7.2", features = ["testutils"] } diff --git a/cmd/crates/soroban-test/tests/fixtures/workspace-with-default-members/contracts/call/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/workspace-with-default-members/contracts/call/Cargo.toml index 48e32b14d..a1ba4ed43 100644 --- a/cmd/crates/soroban-test/tests/fixtures/workspace-with-default-members/contracts/call/Cargo.toml +++ b/cmd/crates/soroban-test/tests/fixtures/workspace-with-default-members/contracts/call/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] doctest = false [dependencies] -soroban-sdk = { workspace = true } +soroban-sdk = { version = "=21.7.2" } [dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"] } +soroban-sdk = { version = "=21.7.2", features = ["testutils"] } diff --git a/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/add/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/add/Cargo.toml index 660b7eb11..ca38cca49 100644 --- a/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/add/Cargo.toml +++ b/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/add/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] doctest = false [dependencies] -soroban-sdk = { workspace = true } +soroban-sdk = { version = "=21.7.2" } [dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"] } +soroban-sdk = { version = "=21.7.2", features = ["testutils"] } diff --git a/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/add/add2/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/add/add2/Cargo.toml index bae834e02..b6b570327 100644 --- a/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/add/add2/Cargo.toml +++ b/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/add/add2/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] doctest = false [dependencies] -soroban-sdk = { workspace = true } +soroban-sdk = { version = "=21.7.2" } [dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"] } +soroban-sdk = { version = "=21.7.2", features = ["testutils"] } diff --git a/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/call/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/call/Cargo.toml index 48e32b14d..a1ba4ed43 100644 --- a/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/call/Cargo.toml +++ b/cmd/crates/soroban-test/tests/fixtures/workspace/contracts/call/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] doctest = false [dependencies] -soroban-sdk = { workspace = true } +soroban-sdk = { version = "=21.7.2" } [dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"] } +soroban-sdk = { version = "=21.7.2", features = ["testutils"] } diff --git a/cmd/crates/soroban-test/tests/it/arg_parsing.rs b/cmd/crates/soroban-test/tests/it/arg_parsing.rs index c245fd8c9..d25d22354 100644 --- a/cmd/crates/soroban-test/tests/it/arg_parsing.rs +++ b/cmd/crates/soroban-test/tests/it/arg_parsing.rs @@ -1,6 +1,6 @@ use crate::util::CUSTOM_TYPES; use serde_json::json; -use soroban_env_host::xdr::{ +use soroban_cli::xdr::{ ScBytes, ScSpecTypeBytesN, ScSpecTypeDef, ScSpecTypeOption, ScSpecTypeUdt, ScVal, }; use soroban_spec_tools::{from_string_primitive, Spec}; diff --git a/cmd/crates/soroban-test/tests/it/init.rs b/cmd/crates/soroban-test/tests/it/init.rs index 6eada4ce6..c3cc9b694 100644 --- a/cmd/crates/soroban-test/tests/it/init.rs +++ b/cmd/crates/soroban-test/tests/it/init.rs @@ -1,6 +1,6 @@ use assert_fs::prelude::*; use predicates::prelude::predicate; -use soroban_test::TestEnv; +use soroban_test::{AssertExt, TestEnv}; #[test] fn init() { @@ -24,3 +24,64 @@ fn init() { == Some(&format!("{major}.0.0")) })); } + +#[test] +fn init_and_deploy() { + let name = "hello_world"; + let sandbox = TestEnv::default(); + + sandbox + .new_assert_cmd("contract") + .arg("init") + .arg("--name") + .arg(name) + .arg("project") + .assert() + .success(); + + let manifest_path = sandbox + .dir() + .join(format!("project/contracts/{name}/Cargo.toml")); + assert!(manifest_path.exists()); + + sandbox + .new_assert_cmd("contract") + .arg("build") + .arg("--manifest-path") + .arg(manifest_path) + .assert() + .success(); + + let target_dir = sandbox + .dir() + .join("project/target/wasm32-unknown-unknown/release"); + assert!(target_dir.exists()); + + let assert = sandbox + .new_assert_cmd("contract") + .arg("deploy") + .arg("--wasm") + .arg(target_dir.join(format!("{name}.wasm"))) + .assert(); + + let contract = assert.stdout_as_str(); + + assert.success(); + + let assert = sandbox + .new_assert_cmd("contract") + .arg("invoke") + .arg("--id") + .arg(contract) + .arg("--") + .arg("hello") + .arg("--to") + .arg("bar") + .assert(); + + let output = assert.stdout_as_str(); + + assert_eq!(output, r#"["Hello","bar"]"#); + + assert.success(); +} diff --git a/cmd/crates/soroban-test/tests/it/integration/cookbook.rs b/cmd/crates/soroban-test/tests/it/integration/cookbook.rs index 82b9c5f43..5e9a30eb2 100644 --- a/cmd/crates/soroban-test/tests/it/integration/cookbook.rs +++ b/cmd/crates/soroban-test/tests/it/integration/cookbook.rs @@ -252,8 +252,6 @@ mod tests { .arg("xdr") .arg("--key") .arg("COUNTER") - .arg("--source-account") - .arg(source) .assert() .stdout_as_str(); let key_xdr = read_xdr.split(',').next().unwrap_or("").trim(); diff --git a/cmd/crates/soroban-test/tests/it/integration/tx.rs b/cmd/crates/soroban-test/tests/it/integration/tx.rs index 5cc6bdb9b..c3cd2693b 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx.rs @@ -1,5 +1,5 @@ use soroban_cli::assembled::simulate_and_assemble_transaction; -use soroban_sdk::xdr::{Limits, ReadXdr, TransactionEnvelope, WriteXdr}; +use soroban_cli::xdr::{Limits, ReadXdr, TransactionEnvelope, WriteXdr}; use soroban_test::{AssertExt, TestEnv}; use crate::integration::util::{deploy_contract, DeployKind, HELLO_WORLD}; diff --git a/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs b/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs index 9df808b34..0a0a103e8 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs @@ -1,8 +1,8 @@ use soroban_cli::{ tx::{builder, ONE_XLM}, utils::contract_id_hash_from_asset, + xdr::{self, ReadXdr, SequenceNumber}, }; -use soroban_sdk::xdr::{self, ReadXdr, SequenceNumber}; use soroban_test::{AssertExt, TestEnv}; use crate::integration::{ diff --git a/cmd/crates/soroban-test/tests/it/integration/util.rs b/cmd/crates/soroban-test/tests/it/integration/util.rs index 6feae7860..438428e38 100644 --- a/cmd/crates/soroban-test/tests/it/integration/util.rs +++ b/cmd/crates/soroban-test/tests/it/integration/util.rs @@ -1,5 +1,7 @@ -use soroban_cli::commands; -use soroban_sdk::xdr::{Limits, WriteXdr}; +use soroban_cli::{ + commands, + xdr::{Limits, WriteXdr}, +}; use soroban_test::{TestEnv, Wasm}; use std::fmt::Display; diff --git a/cmd/crates/stellar-ledger/Cargo.toml b/cmd/crates/stellar-ledger/Cargo.toml index b8894b71d..abf73c375 100644 --- a/cmd/crates/stellar-ledger/Cargo.toml +++ b/cmd/crates/stellar-ledger/Cargo.toml @@ -17,7 +17,6 @@ serde = "1.0.82" serde_derive = "1.0.82" serde_json = "1.0.82" sha2 = "0.9.9" -soroban-env-host = { workspace = true } ed25519-dalek = { workspace = true } stellar-strkey = { workspace = true } ledger-transport-hid = "0.10.0" diff --git a/cmd/crates/stellar-ledger/src/lib.rs b/cmd/crates/stellar-ledger/src/lib.rs index c74365af2..e90c31bb9 100644 --- a/cmd/crates/stellar-ledger/src/lib.rs +++ b/cmd/crates/stellar-ledger/src/lib.rs @@ -5,12 +5,11 @@ use ledger_transport_hid::{ LedgerHIDError, TransportNativeHID, }; -use soroban_env_host::xdr::{Hash, Transaction}; use std::vec; use stellar_strkey::DecodeError; use stellar_xdr::curr::{ - self as xdr, Limits, TransactionSignaturePayload, TransactionSignaturePayloadTaggedTransaction, - WriteXdr, + self as xdr, Hash, Limits, Transaction, TransactionSignaturePayload, + TransactionSignaturePayloadTaggedTransaction, WriteXdr, }; pub use crate::signer::Blob; @@ -312,10 +311,9 @@ mod test { use crate::Blob; use test_helpers::test::emulator_http_transport::EmulatorHttpTransport; - use soroban_env_host::xdr::Transaction; use std::vec; - use soroban_env_host::xdr::{self, Operation, OperationBody, Uint256}; + use super::xdr::{self, Operation, OperationBody, Transaction, Uint256}; use crate::{test_network_hash, Error, LedgerSigner}; diff --git a/cmd/crates/stellar-ledger/tests/test/emulator_tests.rs b/cmd/crates/stellar-ledger/tests/test/emulator_tests.rs index d45981eef..1b0c09bab 100644 --- a/cmd/crates/stellar-ledger/tests/test/emulator_tests.rs +++ b/cmd/crates/stellar-ledger/tests/test/emulator_tests.rs @@ -1,8 +1,6 @@ use ledger_transport::Exchange; use once_cell::sync::Lazy; use serde::Deserialize; -use soroban_env_host::xdr::{self, Operation, OperationBody, Uint256}; -use soroban_env_host::xdr::{Hash, Transaction}; use std::ops::Range; use std::sync::Mutex; use std::vec; @@ -15,8 +13,10 @@ use std::sync::Arc; use std::{collections::HashMap, time::Duration}; use stellar_xdr::curr::{ - Memo, MuxedAccount, PaymentOp, Preconditions, SequenceNumber, TransactionExt, + self as xdr, Hash, Memo, MuxedAccount, Operation, OperationBody, PaymentOp, Preconditions, + SequenceNumber, Transaction, TransactionExt, Uint256, }; + use testcontainers::{core::ContainerPort, runners::AsyncRunner, ContainerAsync, ImageExt}; use tokio::time::sleep; diff --git a/cmd/soroban-cli/Cargo.toml b/cmd/soroban-cli/Cargo.toml index 646e8a92e..0cc12e74f 100644 --- a/cmd/soroban-cli/Cargo.toml +++ b/cmd/soroban-cli/Cargo.toml @@ -40,7 +40,6 @@ opt = ["dep:wasm-opt"] [dependencies] stellar-xdr = { workspace = true, features = ["cli"] } -soroban-env-host = { workspace = true } soroban-spec = { workspace = true } soroban-spec-json = { workspace = true } soroban-spec-rust = { workspace = true } @@ -107,10 +106,6 @@ directories = { workspace = true } ulid = { workspace = true, features = ["serde"] } strum = "0.17.1" strum_macros = "0.17.1" -gix = { version = "0.58.0", default-features = false, features = [ - "blocking-http-transport-reqwest-rust-tls", - "worktree-mutation", -] } async-compression = { version = "0.4.12", features = ["tokio", "gzip"] } tempfile = "3.8.1" diff --git a/cmd/soroban-cli/example_contracts.list b/cmd/soroban-cli/example_contracts.list deleted file mode 100644 index 2ad5f2c6e..000000000 --- a/cmd/soroban-cli/example_contracts.list +++ /dev/null @@ -1,25 +0,0 @@ -account -alloc -atomic_multiswap -atomic_swap -auth -cross_contract -custom_types -deep_contract_auth -deployer -errors -eth_abi -events -fuzzing -increment -liquidity_pool -logging -mint-lock -other_custom_types -simple_account -single_offer -timelock -token -ttl -upgradeable_contract -workspace diff --git a/cmd/soroban-cli/src/commands/contract/arg_parsing.rs b/cmd/soroban-cli/src/commands/contract/arg_parsing.rs index 4a8af47e2..2eb3c2696 100644 --- a/cmd/soroban-cli/src/commands/contract/arg_parsing.rs +++ b/cmd/soroban-cli/src/commands/contract/arg_parsing.rs @@ -8,7 +8,7 @@ use clap::value_parser; use ed25519_dalek::SigningKey; use heck::ToKebabCase; -use soroban_env_host::xdr::{ +use crate::xdr::{ self, Hash, InvokeContractArgs, ScAddress, ScSpecEntry, ScSpecFunctionV0, ScSpecTypeDef, ScVal, ScVec, }; diff --git a/cmd/soroban-cli/src/commands/contract/deploy/asset.rs b/cmd/soroban-cli/src/commands/contract/deploy/asset.rs index 8ff8e08b3..263908521 100644 --- a/cmd/soroban-cli/src/commands/contract/deploy/asset.rs +++ b/cmd/soroban-cli/src/commands/contract/deploy/asset.rs @@ -1,13 +1,10 @@ -use clap::{arg, command, Parser}; -use soroban_env_host::{ - xdr::{ - Asset, ContractDataDurability, ContractExecutable, ContractIdPreimage, CreateContractArgs, - Error as XdrError, Hash, HostFunction, InvokeHostFunctionOp, LedgerKey::ContractData, - LedgerKeyContractData, Limits, Memo, MuxedAccount, Operation, OperationBody, Preconditions, - ScAddress, ScVal, SequenceNumber, Transaction, TransactionExt, VecM, WriteXdr, - }, - HostError, +use crate::xdr::{ + Asset, ContractDataDurability, ContractExecutable, ContractIdPreimage, CreateContractArgs, + Error as XdrError, Hash, HostFunction, InvokeHostFunctionOp, LedgerKey::ContractData, + LedgerKeyContractData, Limits, Memo, MuxedAccount, Operation, OperationBody, Preconditions, + ScAddress, ScVal, SequenceNumber, Transaction, TransactionExt, VecM, WriteXdr, }; +use clap::{arg, command, Parser}; use std::convert::Infallible; use std::{array::TryFromSliceError, fmt::Debug, num::ParseIntError}; @@ -19,17 +16,13 @@ use crate::{ NetworkRunnable, }, config::{self, data, network}, - rpc::{Client, Error as SorobanRpcError}, + rpc::Error as SorobanRpcError, tx::builder, utils::contract_id_hash_from_asset, }; #[derive(thiserror::Error, Debug)] pub enum Error { - #[error(transparent)] - // TODO: the Display impl of host errors is pretty user-unfriendly - // (it just calls Debug). I think we can do better than that - Host(#[from] HostError), #[error("error parsing int: {0}")] ParseIntError(#[from] ParseIntError), #[error(transparent)] @@ -95,7 +88,7 @@ impl NetworkRunnable for Cmd { let asset = &self.asset; let network = config.get_network()?; - let client = Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; client .verify_network_passphrase(Some(&network.network_passphrase)) .await?; diff --git a/cmd/soroban-cli/src/commands/contract/deploy/wasm.rs b/cmd/soroban-cli/src/commands/contract/deploy/wasm.rs index 36ce2e9f7..21c685b93 100644 --- a/cmd/soroban-cli/src/commands/contract/deploy/wasm.rs +++ b/cmd/soroban-cli/src/commands/contract/deploy/wasm.rs @@ -2,25 +2,21 @@ use std::array::TryFromSliceError; use std::fmt::Debug; use std::num::ParseIntError; +use crate::xdr::{ + AccountId, ContractExecutable, ContractIdPreimage, ContractIdPreimageFromAddress, + CreateContractArgs, Error as XdrError, Hash, HostFunction, InvokeHostFunctionOp, Limits, Memo, + MuxedAccount, Operation, OperationBody, Preconditions, PublicKey, ScAddress, SequenceNumber, + Transaction, TransactionExt, Uint256, VecM, WriteXdr, +}; use clap::{arg, command, Parser}; use rand::Rng; use regex::Regex; -use soroban_env_host::{ - xdr::{ - AccountId, ContractExecutable, ContractIdPreimage, ContractIdPreimageFromAddress, - CreateContractArgs, Error as XdrError, Hash, HostFunction, InvokeHostFunctionOp, Limits, - Memo, MuxedAccount, Operation, OperationBody, Preconditions, PublicKey, ScAddress, - SequenceNumber, Transaction, TransactionExt, Uint256, VecM, WriteXdr, - }, - HostError, -}; use crate::{ assembled::simulate_and_assemble_transaction, commands::{contract::install, HEADING_RPC}, config::{self, data, locator, network}, - rpc::{self, Client}, - utils, wasm, + rpc, utils, wasm, }; use crate::{ commands::{ @@ -70,8 +66,6 @@ pub struct Cmd { pub enum Error { #[error(transparent)] Install(#[from] install::Error), - #[error(transparent)] - Host(#[from] HostError), #[error("error parsing int: {0}")] ParseIntError(#[from] ParseIntError), #[error("internal conversion error: {0}")] @@ -213,7 +207,7 @@ impl NetworkRunnable for Cmd { None => rand::thread_rng().gen::<[u8; 32]>(), }; - let client = Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; client .verify_network_passphrase(Some(&network.network_passphrase)) .await?; diff --git a/cmd/soroban-cli/src/commands/contract/extend.rs b/cmd/soroban-cli/src/commands/contract/extend.rs index 3f7477254..24aac54c5 100644 --- a/cmd/soroban-cli/src/commands/contract/extend.rs +++ b/cmd/soroban-cli/src/commands/contract/extend.rs @@ -1,12 +1,12 @@ use std::{fmt::Debug, path::Path, str::FromStr}; -use clap::{command, Parser}; -use soroban_env_host::xdr::{ +use crate::xdr::{ Error as XdrError, ExtendFootprintTtlOp, ExtensionPoint, LedgerEntry, LedgerEntryChange, LedgerEntryData, LedgerFootprint, Limits, Memo, Operation, OperationBody, Preconditions, SequenceNumber, SorobanResources, SorobanTransactionData, Transaction, TransactionExt, TransactionMeta, TransactionMetaV3, TtlEntry, WriteXdr, }; +use clap::{command, Parser}; use crate::{ assembled::simulate_and_assemble_transaction, @@ -16,9 +16,7 @@ use crate::{ NetworkRunnable, }, config::{self, data, locator, network}, - key, - rpc::{self, Client}, - wasm, Pwd, + key, rpc, wasm, Pwd, }; const MAX_LEDGERS_TO_EXTEND: u32 = 535_679; @@ -132,7 +130,7 @@ impl NetworkRunnable for Cmd { let network = config.get_network()?; tracing::trace!(?network); let keys = self.key.parse_keys(&config.locator, &network)?; - let client = Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; let source_account = config.source_account()?; let extend_to = self.ledgers_to_extend(); diff --git a/cmd/soroban-cli/src/commands/contract/fetch.rs b/cmd/soroban-cli/src/commands/contract/fetch.rs index fd8070898..2714b1f07 100644 --- a/cmd/soroban-cli/src/commands/contract/fetch.rs +++ b/cmd/soroban-cli/src/commands/contract/fetch.rs @@ -7,12 +7,14 @@ use std::{fmt::Debug, fs, io}; use clap::{arg, command, Parser}; -use crate::commands::{global, NetworkRunnable}; -use crate::config::{ - self, locator, - network::{self, Network}, +use crate::{ + commands::{global, NetworkRunnable}, + config::{ + self, locator, + network::{self, Network}, + }, + wasm, Pwd, }; -use crate::{wasm, Pwd}; #[derive(Parser, Debug, Default, Clone)] #[allow(clippy::struct_excessive_bools)] diff --git a/cmd/soroban-cli/src/commands/contract/id/asset.rs b/cmd/soroban-cli/src/commands/contract/id/asset.rs index cdf826015..921592cf8 100644 --- a/cmd/soroban-cli/src/commands/contract/id/asset.rs +++ b/cmd/soroban-cli/src/commands/contract/id/asset.rs @@ -20,7 +20,7 @@ pub enum Error { #[error(transparent)] ConfigError(#[from] config::Error), #[error(transparent)] - Xdr(#[from] soroban_env_host::xdr::Error), + Xdr(#[from] crate::xdr::Error), } impl Cmd { pub fn run(&self) -> Result<(), Error> { diff --git a/cmd/soroban-cli/src/commands/contract/id/wasm.rs b/cmd/soroban-cli/src/commands/contract/id/wasm.rs index c020e94b2..349dd167b 100644 --- a/cmd/soroban-cli/src/commands/contract/id/wasm.rs +++ b/cmd/soroban-cli/src/commands/contract/id/wasm.rs @@ -1,9 +1,9 @@ -use clap::{arg, command, Parser}; -use sha2::{Digest, Sha256}; -use soroban_env_host::xdr::{ +use crate::xdr::{ self, AccountId, ContractIdPreimage, ContractIdPreimageFromAddress, Hash, HashIdPreimage, HashIdPreimageContractId, Limits, PublicKey, ScAddress, Uint256, WriteXdr, }; +use clap::{arg, command, Parser}; +use sha2::{Digest, Sha256}; use crate::config; diff --git a/cmd/soroban-cli/src/commands/contract/info/env_meta.rs b/cmd/soroban-cli/src/commands/contract/info/env_meta.rs index 03225c328..bc2d03bc6 100644 --- a/cmd/soroban-cli/src/commands/contract/info/env_meta.rs +++ b/cmd/soroban-cli/src/commands/contract/info/env_meta.rs @@ -1,14 +1,17 @@ use std::fmt::Debug; use clap::{command, Parser}; -use stellar_xdr::curr::ScEnvMetaEntry; use soroban_spec_tools::contract; use soroban_spec_tools::contract::Spec; -use crate::commands::contract::info::env_meta::Error::{NoEnvMetaPresent, NoSACEnvMeta}; -use crate::commands::contract::info::shared; -use crate::commands::contract::info::shared::{fetch_wasm, MetasInfoOutput}; +use crate::{ + commands::contract::info::{ + env_meta::Error::{NoEnvMetaPresent, NoSACEnvMeta}, + shared::{self, fetch_wasm, MetasInfoOutput}, + }, + xdr::{ScEnvMetaEntry, ScEnvMetaEntryInterfaceVersion}, +}; #[derive(Parser, Debug, Clone)] pub struct Cmd { @@ -54,12 +57,16 @@ impl Cmd { let mut meta_str = "Contract env-meta:\n".to_string(); for env_meta_entry in &spec.env_meta { match env_meta_entry { - ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(v) => { - let protocol = v >> 32; - let interface = v & 0xffff_ffff; + ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion( + ScEnvMetaEntryInterfaceVersion { + protocol, + pre_release, + }, + ) => { meta_str.push_str(&format!(" • Protocol: v{protocol}\n")); - meta_str.push_str(&format!(" • Interface: v{interface}\n")); - meta_str.push_str(&format!(" • Interface Version: {v}\n")); + if pre_release != &0 { + meta_str.push_str(&format!(" • Pre-release: v{pre_release}\n")); + } } } } diff --git a/cmd/soroban-cli/src/commands/contract/info/shared.rs b/cmd/soroban-cli/src/commands/contract/info/shared.rs index 25cbc9258..0974632ae 100644 --- a/cmd/soroban-cli/src/commands/contract/info/shared.rs +++ b/cmd/soroban-cli/src/commands/contract/info/shared.rs @@ -1,14 +1,14 @@ use std::path::PathBuf; +use crate::xdr; use clap::arg; -use soroban_env_host::xdr; -use soroban_rpc::Client; -use crate::commands::contract::info::shared::Error::InvalidWasmHash; -use crate::config::{locator, network}; -use crate::utils::rpc::get_remote_wasm_from_hash; -use crate::wasm; -use crate::wasm::Error::ContractIsStellarAsset; +use crate::{ + commands::contract::info::shared::Error::InvalidWasmHash, + config::{locator, network}, + utils::rpc::get_remote_wasm_from_hash, + wasm::{self, Error::ContractIsStellarAsset}, +}; #[derive(Debug, clap::Args, Clone, Default)] #[command(group( @@ -71,7 +71,8 @@ pub async fn fetch_wasm(args: &Args) -> Result>, Error> { let hash = xdr::Hash(hash); - let client = Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; + client .verify_network_passphrase(Some(&network.network_passphrase)) .await?; diff --git a/cmd/soroban-cli/src/commands/contract/init.rs b/cmd/soroban-cli/src/commands/contract/init.rs index fd4cf483a..96f28c64e 100644 --- a/cmd/soroban-cli/src/commands/contract/init.rs +++ b/cmd/soroban-cli/src/commands/contract/init.rs @@ -1,85 +1,77 @@ -use clap::{ - builder::{PossibleValue, PossibleValuesParser, ValueParser}, - Parser, -}; -use gix::{clone, create, open, progress, remote}; -use rust_embed::RustEmbed; -use serde_json::{from_str, json, to_string_pretty, Error as JsonError, Value as JsonValue}; +use std::borrow::Cow; use std::{ - env, - ffi::OsStr, - fs::{ - copy, create_dir_all, metadata, read_dir, read_to_string, write, File, Metadata, - OpenOptions, - }, - io::{self, Read, Write}, - num::NonZeroU32, + fs::{create_dir_all, metadata, write, Metadata}, + io, path::{Path, PathBuf}, str, - sync::atomic::AtomicBool, }; -use toml_edit::{Document, TomlError}; -use crate::utils::http; -use crate::{commands::global, print}; +use clap::Parser; +use rust_embed::RustEmbed; -const SOROBAN_EXAMPLES_URL: &str = "https://github.com/stellar/soroban-examples.git"; -const GITHUB_URL: &str = "https://github.com"; -const WITH_EXAMPLE_LONG_HELP_TEXT: &str = - "An optional flag to specify Soroban example contracts to include. A hello-world contract will be included by default."; +use crate::{commands::global, error_on_use_of_removed_arg, print, utils}; + +const EXAMPLE_REMOVAL_NOTICE: &str = "Adding examples via cli is no longer supported. \ +You can still clone examples from the repo https://github.com/stellar/soroban-examples"; +const FRONTEND_EXAMPLE_REMOVAL_NOTICE: &str = "Using frontend template via cli is no longer \ +supported. You can search for frontend templates using github tags, \ +such as `soroban-template` or `soroban-frontend-template`"; #[derive(Parser, Debug, Clone)] #[group(skip)] pub struct Cmd { pub project_path: String, - #[arg(short, long, num_args = 1.., value_parser=possible_example_values(), long_help=WITH_EXAMPLE_LONG_HELP_TEXT)] - pub with_example: Vec, + #[arg( + long, + default_value = "hello-world", + long_help = "An optional flag to specify a new contract's name." + )] + pub name: String, + // TODO: remove in future version (23+) https://github.com/stellar/stellar-cli/issues/1586 #[arg( + short, long, - default_value = "", - long_help = "An optional flag to pass in a url for a frontend template repository." + hide = true, + display_order = 100, + value_parser = error_on_use_of_removed_arg!(String, EXAMPLE_REMOVAL_NOTICE) )] - pub frontend_template: String, + pub with_example: Option, + + // TODO: remove in future version (23+) https://github.com/stellar/stellar-cli/issues/1586 + #[arg( + long, + hide = true, + display_order = 100, + value_parser = error_on_use_of_removed_arg!(String, FRONTEND_EXAMPLE_REMOVAL_NOTICE), + )] + pub frontend_template: Option, #[arg(long, long_help = "Overwrite all existing files.")] pub overwrite: bool, } -fn possible_example_values() -> ValueParser { - let example_contracts = include_str!("../../../example_contracts.list") - .lines() - .collect::>(); - let parser = PossibleValuesParser::new(example_contracts.iter().map(PossibleValue::new)); - parser.into() -} - #[derive(thiserror::Error, Debug)] pub enum Error { #[error("{0}: {1}")] Io(String, io::Error), - #[error("io error:")] - StdIo(#[from] io::Error), - - #[error("{0}: {1}")] - Json(String, JsonError), - - #[error("failed to parse toml file: {0}")] - TomlParse(#[from] TomlError), + #[error(transparent)] + Std(#[from] std::io::Error), #[error("failed to convert bytes to string: {0}")] ConvertBytesToString(#[from] str::Utf8Error), - #[error("preparing fetch repository: {0}")] - PrepareFetch(Box), + #[error("contract package already exists: {0}")] + AlreadyExists(String), - #[error("failed to fetch repository: {0}")] - Fetch(Box), + #[error("provided project path exists and is not a directory")] + PathExistsNotDir, - #[error("failed to checkout main worktree: {0}")] - Checkout(#[from] clone::checkout::main_worktree::Error), + #[error("provided project path exists and is not a cargo workspace root directory. Hint: run init on an empty or non-existing directory" + )] + PathExistsNotCargoProject, } impl Cmd { @@ -95,8 +87,13 @@ impl Cmd { } #[derive(RustEmbed)] -#[folder = "src/utils/contract-init-template"] -struct TemplateFiles; +#[folder = "src/utils/contract-workspace-template"] +struct WorkspaceTemplateFiles; + +#[derive(RustEmbed)] +#[folder = "src/utils/contract-template"] +struct ContractTemplateFiles; + struct Runner { args: Cmd, print: print::Print, @@ -106,53 +103,49 @@ impl Runner { fn run(&self) -> Result<(), Error> { let project_path = PathBuf::from(&self.args.project_path); self.print - .infoln(format!("Initializing project at {project_path:?}")); + .infoln(format!("Initializing workspace at {project_path:?}")); // create a project dir, and copy the contents of the base template (contract-init-template) into it Self::create_dir_all(&project_path)?; - self.copy_template_files()?; - - if !Self::check_internet_connection() { - self.print.warnln("It doesn't look like you're connected to the internet. We're still able to initialize a new project, but additional examples and the frontend template will not be included."); - return Ok(()); - } - - if !self.args.frontend_template.is_empty() { - // create a temp dir for the template repo - let fe_template_dir = tempfile::tempdir() - .map_err(|e| Error::Io("creating temp dir for frontend template".to_string(), e))?; + self.copy_template_files( + project_path.as_path(), + &mut WorkspaceTemplateFiles::iter(), + WorkspaceTemplateFiles::get, + )?; - // clone the template repo into the temp dir - Self::clone_repo(&self.args.frontend_template, fe_template_dir.path())?; - - // copy the frontend template files into the project - self.copy_frontend_files(fe_template_dir.path(), &project_path)?; - } + let contract_path = project_path.join("contracts").join(&self.args.name); + self.print + .infoln(format!("Initializing contract at {contract_path:?}")); - // if there are --with-example flags, include the example contracts - if self.include_example_contracts() { - // create an examples temp dir - let examples_dir = tempfile::tempdir() - .map_err(|e| Error::Io("creating temp dir for soroban-examples".to_string(), e))?; - - // clone the soroban-examples repo into the temp dir - Self::clone_repo(SOROBAN_EXAMPLES_URL, examples_dir.path())?; - - // copy the example contracts into the project - self.copy_example_contracts( - examples_dir.path(), - &project_path, - &self.args.with_example, - )?; - } + Self::create_dir_all(contract_path.as_path())?; + self.copy_template_files( + contract_path.as_path(), + &mut ContractTemplateFiles::iter(), + ContractTemplateFiles::get, + )?; Ok(()) } - fn copy_template_files(&self) -> Result<(), Error> { - let project_path = Path::new(&self.args.project_path); - for item in TemplateFiles::iter() { - let mut to = project_path.join(item.as_ref()); + fn copy_template_files( + &self, + root_path: &Path, + files: &mut dyn Iterator>, + getter: fn(&str) -> Option, + ) -> Result<(), Error> { + for item in &mut *files { + let mut to = root_path.join(item.as_ref()); + // We need to include the Cargo.toml file as Cargo.toml.removeextension in the template + // so that it will be included the package. This is making sure that the Cargo file is + // written as Cargo.toml in the new project. This is a workaround for this issue: + // https://github.com/rust-lang/cargo/issues/8597. + let item_path = Path::new(item.as_ref()); + let is_toml = item_path.file_name().unwrap() == "Cargo.toml.removeextension"; + if is_toml { + let item_parent_path = item_path.parent().unwrap(); + to = root_path.join(item_parent_path).join("Cargo.toml"); + } + let exists = Self::file_exists(&to); if exists && !self.args.overwrite { self.print @@ -162,20 +155,19 @@ impl Runner { Self::create_dir_all(to.parent().unwrap())?; - let Some(file) = TemplateFiles::get(item.as_ref()) else { + let Some(file) = getter(item.as_ref()) else { self.print .warnln(format!("Failed to read file: {}", item.as_ref())); continue; }; - let file_contents = - std::str::from_utf8(file.data.as_ref()).map_err(Error::ConvertBytesToString)?; + let mut file_contents = str::from_utf8(file.data.as_ref()) + .map_err(Error::ConvertBytesToString)? + .to_string(); - // We need to include the Cargo.toml file as Cargo.toml.removeextension in the template so that it will be included the package. This is making sure that the Cargo file is written as Cargo.toml in the new project. This is a workaround for this issue: https://github.com/rust-lang/cargo/issues/8597. - let item_path = Path::new(item.as_ref()); - if item_path.file_name().unwrap() == "Cargo.toml.removeextension" { - let item_parent_path = item_path.parent().unwrap(); - to = project_path.join(item_parent_path).join("Cargo.toml"); + if is_toml { + let new_content = file_contents.replace("%contract-template%", &self.args.name); + file_contents = new_content; } if exists { @@ -184,70 +176,7 @@ impl Runner { } else { self.print.plusln(format!("Writing {to:?}")); } - Self::write(&to, file_contents)?; - } - Ok(()) - } - - fn copy_contents(&self, from: &Path, to: &Path) -> Result<(), Error> { - let contents_to_exclude_from_copy = [ - ".git", - ".github", - "Makefile", - ".vscode", - "target", - "Cargo.lock", - ]; - for entry in - read_dir(from).map_err(|e| Error::Io(format!("reading directory: {from:?}"), e))? - { - let entry = - entry.map_err(|e| Error::Io(format!("reading entry in directory {from:?}",), e))?; - let path = entry.path(); - let entry_name = entry.file_name().to_string_lossy().to_string(); - let new_path = to.join(&entry_name); - - if contents_to_exclude_from_copy.contains(&entry_name.as_str()) { - continue; - } - - if path.is_dir() { - Self::create_dir_all(&new_path)?; - self.copy_contents(&path, &new_path)?; - } else { - let exists = Self::file_exists(&new_path); - let new_path_str = new_path.to_string_lossy(); - if exists { - let append = - new_path_str.contains(".gitignore") || new_path_str.contains("README.md"); - if append { - self.append_contents(&path, &new_path)?; - } - - if self.args.overwrite && !append { - self.print.plusln(format!( - "Writing {new_path_str} (overwriting existing file)" - )); - } else { - self.print.infoln(format!( - "Skipped creating {new_path_str} as it already exists" - )); - continue; - } - } else { - self.print.plus(format!("Writing {new_path_str}")); - } - copy(&path, &new_path).map_err(|e| { - Error::Io( - format!( - "copying from {:?} to {:?}", - path.to_string_lossy(), - new_path - ), - e, - ) - })?; - } + Self::write(&to, &file_contents)?; } Ok(()) @@ -260,172 +189,6 @@ impl Runner { .unwrap_or(false) } - fn check_internet_connection() -> bool { - if let Ok(_req) = http::blocking_client().get(GITHUB_URL).send() { - return true; - } - - false - } - - fn include_example_contracts(&self) -> bool { - !self.args.with_example.is_empty() - } - - fn clone_repo(from_url: &str, to_path: &Path) -> Result<(), Error> { - let mut prepare = clone::PrepareFetch::new( - from_url, - to_path, - create::Kind::WithWorktree, - create::Options { - destination_must_be_empty: false, - fs_capabilities: None, - }, - open::Options::isolated(), - ) - .map_err(|e| Error::PrepareFetch(Box::new(e)))? - .with_shallow(remote::fetch::Shallow::DepthAtRemote( - NonZeroU32::new(1).unwrap(), - )); - - let (mut checkout, _outcome) = prepare - .fetch_then_checkout(progress::Discard, &AtomicBool::new(false)) - .map_err(|e| Error::Fetch(Box::new(e)))?; - let (_repo, _outcome) = checkout - .main_worktree(progress::Discard, &AtomicBool::new(false)) - .map_err(Error::Checkout)?; - - Ok(()) - } - - fn copy_example_contracts( - &self, - from: &Path, - to: &Path, - contracts: &[String], - ) -> Result<(), Error> { - let project_contracts_path = to.join("contracts"); - for contract in contracts { - self.print - .infoln(format!("Initializing example contract: {contract}")); - let contract_as_string = contract.to_string(); - let contract_path = Path::new(&contract_as_string); - let from_contract_path = from.join(contract_path); - let to_contract_path = project_contracts_path.join(contract_path); - Self::create_dir_all(&to_contract_path)?; - - self.copy_contents(&from_contract_path, &to_contract_path)?; - Self::edit_contract_cargo_file(&to_contract_path)?; - } - - Ok(()) - } - - fn edit_contract_cargo_file(contract_path: &Path) -> Result<(), Error> { - let cargo_path = contract_path.join("Cargo.toml"); - - let cargo_toml_str = Self::read_to_string(&cargo_path)?; - let cargo_toml_str = regex::Regex::new(r#"soroban-sdk = "[^\"]+""#) - .unwrap() - .replace_all( - cargo_toml_str.as_str(), - "soroban-sdk = { workspace = true }", - ); - - let cargo_toml_str = regex::Regex::new(r#"soroban-sdk = \{(.*) version = "[^"]+"(.+)}"#) - .unwrap() - .replace_all(&cargo_toml_str, "soroban-sdk = {$1 workspace = true$2}"); - - let mut doc = cargo_toml_str - .parse::() - .map_err(Error::TomlParse)?; - doc.remove("profile"); - - Self::write(&cargo_path, &doc.to_string())?; - - Ok(()) - } - - fn copy_frontend_files(&self, from: &Path, to: &Path) -> Result<(), Error> { - self.print.infoln("Initializing with frontend template"); - self.copy_contents(from, to)?; - Self::edit_package_json_files(to) - } - - fn edit_package_json_files(project_path: &Path) -> Result<(), Error> { - let package_name = if let Some(name) = project_path.file_name() { - name.to_owned() - } else { - let current_dir = env::current_dir() - .map_err(|e| Error::Io("getting current dir from env".to_string(), e))?; - let file_name = current_dir - .file_name() - .unwrap_or(OsStr::new("soroban-astro-template")) - .to_os_string(); - file_name - }; - - Self::edit_package_name(project_path, &package_name, "package.json")?; - Self::edit_package_name(project_path, &package_name, "package-lock.json") - } - - fn edit_package_name( - project_path: &Path, - package_name: &OsStr, - file_name: &str, - ) -> Result<(), Error> { - let file_path = project_path.join(file_name); - let file_contents = Self::read_to_string(&file_path)?; - - let mut doc: JsonValue = from_str(&file_contents).map_err(|e| { - Error::Json(format!("parsing {file_name} file in: {project_path:?}"), e) - })?; - - doc["name"] = json!(package_name.to_string_lossy()); - - let formatted_json = to_string_pretty(&doc) - .map_err(|e| Error::Json("calling to_string_pretty for package.json".to_string(), e))?; - - Self::write(&file_path, &formatted_json)?; - - Ok(()) - } - - // Appends the contents of a file to another file, separated by a delimiter - fn append_contents(&self, from: &Path, to: &Path) -> Result<(), Error> { - let mut from_file = File::open(from)?; - let mut from_content = String::new(); - from_file.read_to_string(&mut from_content)?; - - let mut to_file = OpenOptions::new().read(true).append(true).open(to)?; - let mut to_content = String::new(); - to_file.read_to_string(&mut to_content)?; - - let delimiter = Self::get_merged_file_delimiter(to); - // if the to file already contains the delimiter, we don't need to append the contents again - if to_content.contains(&delimiter) { - return Ok(()); - } - - to_file.write_all(delimiter.as_bytes())?; - to_file.write_all(from_content.as_bytes())?; - - self.print.infoln(format!("Merging {to:?} contents")); - Ok(()) - } - - fn get_merged_file_delimiter(file_path: &Path) -> String { - let comment = if file_path.to_string_lossy().contains("README.md") { - "---\n".to_string() - } else if file_path.to_string_lossy().contains("gitignore") { - "# The following is from the Frontend Template's .gitignore".to_string() - } else { - String::new() - }; - - format!("\n\n{comment}\n\n").to_string() - } - fn create_dir_all(path: &Path) -> Result<(), Error> { create_dir_all(path).map_err(|e| Error::Io(format!("creating directory: {path:?}"), e)) } @@ -433,22 +196,14 @@ impl Runner { fn write(path: &Path, contents: &str) -> Result<(), Error> { write(path, contents).map_err(|e| Error::Io(format!("writing file: {path:?}"), e)) } - - fn read_to_string(path: &Path) -> Result { - read_to_string(path).map_err(|e| Error::Io(format!("reading file: {path:?}"), e)) - } } #[cfg(test)] mod tests { + use std::fs; + use std::fs::read_to_string; + use itertools::Itertools; - use std::{ - collections::HashMap, - fs::{self, read_to_string}, - path::PathBuf, - time::SystemTime, - }; - use walkdir::WalkDir; use super::*; @@ -461,115 +216,9 @@ mod tests { let runner = Runner { args: Cmd { project_path: project_dir.to_string_lossy().to_string(), - with_example: vec![], - frontend_template: String::new(), - overwrite: false, - }, - print: print::Print::new(false), - }; - runner.run().unwrap(); - - assert_base_template_files_exist(&project_dir); - assert_default_hello_world_contract_files_exist(&project_dir); - assert_excluded_paths_do_not_exist(&project_dir); - - assert_contract_cargo_file_is_well_formed(&project_dir, "hello_world"); - - assert_excluded_paths_do_not_exist(&project_dir); - - temp_dir.close().unwrap(); - } - - #[test] - fn test_init_including_example_contract() { - let temp_dir = tempfile::tempdir().unwrap(); - let project_dir = temp_dir.path().join(TEST_PROJECT_NAME); - let runner = Runner { - args: Cmd { - project_path: project_dir.to_string_lossy().to_string(), - with_example: ["alloc".to_owned()].to_vec(), - frontend_template: String::new(), - overwrite: false, - }, - print: print::Print::new(false), - }; - runner.run().unwrap(); - - assert_base_template_files_exist(&project_dir); - assert_default_hello_world_contract_files_exist(&project_dir); - assert_excluded_paths_do_not_exist(&project_dir); - - // check that alloc contract files exist - assert_contract_files_exist(&project_dir, "alloc"); - - // check that expected files are excluded from the alloc contract dir - assert_example_contract_excluded_files_do_not_exist(&project_dir, "alloc"); - - // check that the alloc contract's Cargo.toml file uses the workspace for dependencies - assert_contract_cargo_file_is_well_formed(&project_dir, "alloc"); - - temp_dir.close().unwrap(); - } - - #[test] - fn test_init_including_multiple_example_contracts() { - let temp_dir = tempfile::tempdir().unwrap(); - let project_dir = temp_dir.path().join("project"); - let runner = Runner { - args: Cmd { - project_path: project_dir.to_string_lossy().to_string(), - with_example: ["account".to_owned(), "atomic_swap".to_owned()].to_vec(), - frontend_template: String::new(), - overwrite: false, - }, - print: print::Print::new(false), - }; - runner.run().unwrap(); - - assert_base_template_files_exist(&project_dir); - assert_default_hello_world_contract_files_exist(&project_dir); - assert_excluded_paths_do_not_exist(&project_dir); - - // check that account contract files exist and that expected files are excluded - assert_contract_files_exist(&project_dir, "account"); - assert_example_contract_excluded_files_do_not_exist(&project_dir, "account"); - assert_contract_cargo_file_is_well_formed(&project_dir, "account"); - - // check that atomic_swap contract files exist and that expected files are excluded - assert_contract_files_exist(&project_dir, "atomic_swap"); - assert_example_contract_excluded_files_do_not_exist(&project_dir, "atomic_swap"); - assert_contract_cargo_file_is_well_formed(&project_dir, "atomic_swap"); - - temp_dir.close().unwrap(); - } - - #[test] - fn test_init_with_invalid_example_contract() { - let temp_dir = tempfile::tempdir().unwrap(); - let project_dir = temp_dir.path().join("project"); - let runner = Runner { - args: Cmd { - project_path: project_dir.to_string_lossy().to_string(), - with_example: ["invalid_example".to_owned(), "atomic_swap".to_owned()].to_vec(), - frontend_template: String::new(), - overwrite: false, - }, - print: print::Print::new(false), - }; - assert!(runner.run().is_err()); - - temp_dir.close().unwrap(); - } - - #[test] - fn test_init_with_frontend_template() { - let temp_dir = tempfile::tempdir().unwrap(); - let project_dir = temp_dir.path().join(TEST_PROJECT_NAME); - let runner = Runner { - args: Cmd { - project_path: project_dir.to_string_lossy().to_string(), - with_example: vec![], - frontend_template: "https://github.com/stellar/soroban-astro-template".to_owned(), + name: "hello_world".to_string(), + with_example: None, + frontend_template: None, overwrite: false, }, print: print::Print::new(false), @@ -577,158 +226,31 @@ mod tests { runner.run().unwrap(); assert_base_template_files_exist(&project_dir); - assert_default_hello_world_contract_files_exist(&project_dir); - assert_excluded_paths_do_not_exist(&project_dir); - // check that the contract's Cargo.toml file uses the workspace for dependencies - assert_contract_cargo_file_is_well_formed(&project_dir, "hello_world"); + assert_contract_files_exist(&project_dir, "hello_world"); assert_excluded_paths_do_not_exist(&project_dir); - assert_astro_files_exist(&project_dir); - assert_gitignore_includes_astro_paths(&project_dir); - assert_package_json_files_have_correct_name(&project_dir, TEST_PROJECT_NAME); - assert_readme_includes_frontend_readme_appended(&project_dir); - - temp_dir.close().unwrap(); - } - - #[test] - fn test_init_with_overwrite() { - let temp_dir = tempfile::tempdir().unwrap(); - let project_dir = temp_dir.path().join(TEST_PROJECT_NAME); - - // First initialization - let runner = Runner { - args: Cmd { - project_path: project_dir.to_string_lossy().to_string(), - with_example: vec![], - frontend_template: "https://github.com/stellar/soroban-astro-template".to_owned(), - overwrite: false, - }, - print: print::Print::new(false), - }; - runner.run().unwrap(); - - // Get initial modification times - let initial_mod_times = get_mod_times(&project_dir); - - // Second initialization with overwrite - let runner = Runner { - args: Cmd { - project_path: project_dir.to_string_lossy().to_string(), - with_example: vec![], - frontend_template: "https://github.com/stellar/soroban-astro-template".to_owned(), - overwrite: true, - }, - print: print::Print::new(false), - }; - runner.run().unwrap(); - - // Get new modification times - let new_mod_times = get_mod_times(&project_dir); - - // Compare modification times - for (path, initial_time) in initial_mod_times { - let new_time = new_mod_times.get(&path).expect("File should still exist"); - assert!( - new_time > &initial_time, - "File {} should have a later modification time", - path.display() - ); - } - - temp_dir.close().unwrap(); - } - - fn get_mod_times(dir: &Path) -> HashMap { - let mut mod_times = HashMap::new(); - for entry in WalkDir::new(dir) { - let entry = entry.unwrap(); - if entry.file_type().is_file() { - let path = entry.path().to_owned(); - let metadata = fs::metadata(&path).unwrap(); - mod_times.insert(path, metadata.modified().unwrap()); - } - } - mod_times - } - - #[test] - fn test_init_from_within_an_existing_project() { - let temp_dir = tempfile::tempdir().unwrap(); - let project_dir = temp_dir.path().join("./"); - let runner = Runner { - args: Cmd { - project_path: project_dir.to_string_lossy().to_string(), - with_example: vec![], - frontend_template: "https://github.com/stellar/soroban-astro-template".to_owned(), - overwrite: false, - }, - print: print::Print::new(false), - }; - runner.run().unwrap(); - - assert_base_template_files_exist(&project_dir); - assert_default_hello_world_contract_files_exist(&project_dir); - assert_excluded_paths_do_not_exist(&project_dir); - - // check that the contract's Cargo.toml file uses the workspace for dependencies assert_contract_cargo_file_is_well_formed(&project_dir, "hello_world"); assert_excluded_paths_do_not_exist(&project_dir); - assert_astro_files_exist(&project_dir); - assert_gitignore_includes_astro_paths(&project_dir); - assert_package_json_files_have_correct_name( - &project_dir, - &project_dir.file_name().unwrap().to_string_lossy(), - ); - - temp_dir.close().unwrap(); - } - - #[test] - fn test_init_does_not_duplicate_frontend_readme_contents_when_run_more_than_once() { - let temp_dir = tempfile::tempdir().unwrap(); - let project_dir = temp_dir.path().join(TEST_PROJECT_NAME); - let runner = Runner { - args: Cmd { - project_path: project_dir.to_string_lossy().to_string(), - with_example: vec![], - frontend_template: "https://github.com/stellar/soroban-astro-template".to_owned(), - overwrite: false, - }, - print: print::Print::new(false), - }; - runner.run().unwrap(); - - // call init again to make sure the README.md's contents are not duplicated let runner = Runner { args: Cmd { project_path: project_dir.to_string_lossy().to_string(), - with_example: vec![], - frontend_template: "https://github.com/stellar/soroban-astro-template".to_owned(), + name: "contract2".to_string(), + with_example: None, + frontend_template: None, overwrite: false, }, print: print::Print::new(false), }; runner.run().unwrap(); - assert_base_template_files_exist(&project_dir); - assert_default_hello_world_contract_files_exist(&project_dir); + assert_contract_files_exist(&project_dir, "contract2"); assert_excluded_paths_do_not_exist(&project_dir); - // check that the contract's Cargo.toml file uses the workspace for dependencies - assert_contract_cargo_file_is_well_formed(&project_dir, "hello_world"); + assert_contract_cargo_file_is_well_formed(&project_dir, "contract2"); assert_excluded_paths_do_not_exist(&project_dir); - assert_astro_files_exist(&project_dir); - assert_gitignore_includes_astro_paths(&project_dir); - assert_package_json_files_have_correct_name( - &project_dir, - &project_dir.file_name().unwrap().to_string_lossy(), - ); - assert_readme_includes_frontend_readme_appended(&project_dir); - temp_dir.close().unwrap(); } @@ -740,10 +262,6 @@ mod tests { } } - fn assert_default_hello_world_contract_files_exist(project_dir: &Path) { - assert_contract_files_exist(project_dir, "hello_world"); - } - fn assert_contract_files_exist(project_dir: &Path, contract_name: &str) { let contract_dir = project_dir.join("contracts").join(contract_name); @@ -813,21 +331,13 @@ mod tests { ); } - fn assert_example_contract_excluded_files_do_not_exist( - project_dir: &Path, - contract_name: &str, - ) { - let contract_dir = project_dir.join("contracts").join(contract_name); - assert!(!contract_dir.as_path().join("Makefile").exists()); - } - fn assert_excluded_paths_do_not_exist(project_dir: &Path) { let base_excluded_paths = [".git", ".github", "Makefile", ".vscode", "target"]; for path in &base_excluded_paths { let filepath = project_dir.join(path); assert!(!filepath.exists(), "{filepath:?} should not exist"); } - let contract_excluded_paths = ["Makefile", "target", "Cargo.lock"]; + let contract_excluded_paths = ["target", "Cargo.lock"]; let contract_dirs = fs::read_dir(project_dir.join("contracts")) .unwrap() .map(|entry| entry.unwrap().path()); @@ -838,50 +348,4 @@ mod tests { assert!(!filepath.exists(), "{filepath:?} should not exist"); }); } - - fn assert_gitignore_includes_astro_paths(project_dir: &Path) { - let gitignore_path = project_dir.join(".gitignore"); - let gitignore_str = read_to_string(gitignore_path).unwrap(); - assert!(gitignore_str.contains(".astro/")); - assert!(gitignore_str.contains("node_modules")); - assert!(gitignore_str.contains("npm-debug.log*")); - } - - fn assert_astro_files_exist(project_dir: &Path) { - assert!(project_dir.join("public").exists()); - assert!(project_dir.join("src").exists()); - assert!(project_dir.join("src").join("components").exists()); - assert!(project_dir.join("src").join("layouts").exists()); - assert!(project_dir.join("src").join("pages").exists()); - assert!(project_dir.join("astro.config.mjs").exists()); - assert!(project_dir.join("tsconfig.json").exists()); - } - - fn assert_package_json_files_have_correct_name( - project_dir: &Path, - expected_package_name: &str, - ) { - let package_json_path = project_dir.join("package.json"); - let package_json_str = read_to_string(package_json_path).unwrap(); - assert!(package_json_str.contains(&format!("\"name\": \"{expected_package_name}\""))); - - let package_lock_json_path = project_dir.join("package-lock.json"); - let package_lock_json_str = read_to_string(package_lock_json_path).unwrap(); - assert!(package_lock_json_str.contains(&format!("\"name\": \"{expected_package_name}\""))); - } - - fn assert_readme_includes_frontend_readme_appended(project_dir: &Path) { - let readme_path = project_dir.join("README.md"); - let readme_str = read_to_string(readme_path).unwrap(); - assert!(readme_str.contains("Soroban Frontend in Astro")); - let expected = "The following is the Frontend Template's README.md"; - assert!(readme_str.contains(expected)); - - let readme_path = project_dir.join("README.md"); - let readme_str = read_to_string(readme_path).unwrap(); - let readme_frontend_merge_delimiter = "The following is the Frontend Template's README.md"; - let count = readme_str.matches(readme_frontend_merge_delimiter).count(); - // making sure it is in there just once so that it isn't duplicated if `contract init` is run again - assert!(count == 1); - } } diff --git a/cmd/soroban-cli/src/commands/contract/inspect.rs b/cmd/soroban-cli/src/commands/contract/inspect.rs index 46fdc33a7..86559641b 100644 --- a/cmd/soroban-cli/src/commands/contract/inspect.rs +++ b/cmd/soroban-cli/src/commands/contract/inspect.rs @@ -1,5 +1,5 @@ +use crate::xdr; use clap::{command, Parser}; -use soroban_env_host::xdr; use soroban_spec_tools::contract; use std::{fmt::Debug, path::PathBuf}; use tracing::debug; diff --git a/cmd/soroban-cli/src/commands/contract/install.rs b/cmd/soroban-cli/src/commands/contract/install.rs index b70cadb78..cd6e93b24 100644 --- a/cmd/soroban-cli/src/commands/contract/install.rs +++ b/cmd/soroban-cli/src/commands/contract/install.rs @@ -2,23 +2,28 @@ use std::array::TryFromSliceError; use std::fmt::Debug; use std::num::ParseIntError; -use clap::{command, Parser}; -use soroban_env_host::xdr::{ +use crate::xdr::{ self, ContractCodeEntryExt, Error as XdrError, Hash, HostFunction, InvokeHostFunctionOp, LedgerEntryData, Limits, OperationBody, ReadXdr, ScMetaEntry, ScMetaV0, Transaction, TransactionResult, TransactionResultResult, VecM, WriteXdr, }; +use clap::{command, Parser}; use super::restore; -use crate::assembled::simulate_and_assemble_transaction; -use crate::commands::txn_result::{TxnEnvelopeResult, TxnResult}; -use crate::commands::{global, NetworkRunnable}; -use crate::config::{self, data, network}; -use crate::key; -use crate::print::Print; -use crate::rpc::{self, Client}; -use crate::tx::builder::{self, TxExt}; -use crate::{utils, wasm}; +use crate::{ + assembled::simulate_and_assemble_transaction, + commands::{ + global, + txn_result::{TxnEnvelopeResult, TxnResult}, + NetworkRunnable, + }, + config::{self, data, network}, + key, + print::Print, + rpc, + tx::builder::{self, TxExt}, + utils, wasm, +}; const CONTRACT_META_SDK_KEY: &str = "rssdkver"; const PUBLIC_NETWORK_PASSPHRASE: &str = "Public Global Stellar Network ; September 2015"; @@ -103,7 +108,7 @@ impl NetworkRunnable for Cmd { let config = config.unwrap_or(&self.config); let contract = self.wasm.read()?; let network = config.get_network()?; - let client = Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; client .verify_network_passphrase(Some(&network.network_passphrase)) .await?; diff --git a/cmd/soroban-cli/src/commands/contract/invoke.rs b/cmd/soroban-cli/src/commands/contract/invoke.rs index 55e2554bf..5d43f9bfa 100644 --- a/cmd/soroban-cli/src/commands/contract/invoke.rs +++ b/cmd/soroban-cli/src/commands/contract/invoke.rs @@ -7,32 +7,30 @@ use std::{fmt::Debug, fs, io}; use clap::{arg, command, Parser, ValueEnum}; -use soroban_env_host::{ - xdr::{ - self, AccountEntry, AccountEntryExt, AccountId, ContractEvent, ContractEventType, - DiagnosticEvent, HostFunction, InvokeContractArgs, InvokeHostFunctionOp, LedgerEntryData, - Limits, Memo, MuxedAccount, Operation, OperationBody, Preconditions, PublicKey, - ScSpecEntry, SequenceNumber, String32, StringM, Thresholds, Transaction, TransactionExt, - Uint256, VecM, WriteXdr, - }, - HostError, -}; - use soroban_rpc::{SimulateHostFunctionResult, SimulateTransactionResponse}; use soroban_spec::read::FromWasmError; use super::super::events; use super::arg_parsing; -use crate::assembled::simulate_and_assemble_transaction; -use crate::commands::contract::arg_parsing::{build_host_function_parameters, output_to_string}; -use crate::commands::txn_result::{TxnEnvelopeResult, TxnResult}; -use crate::commands::NetworkRunnable; -use crate::get_spec::{self, get_remote_contract_spec}; -use crate::print; use crate::{ - commands::global, + assembled::simulate_and_assemble_transaction, + commands::{ + contract::arg_parsing::{build_host_function_parameters, output_to_string}, + global, + txn_result::{TxnEnvelopeResult, TxnResult}, + NetworkRunnable, + }, config::{self, data, locator, network}, - rpc, Pwd, + get_spec::{self, get_remote_contract_spec}, + print, rpc, + xdr::{ + self, AccountEntry, AccountEntryExt, AccountId, ContractEvent, ContractEventType, + DiagnosticEvent, HostFunction, InvokeContractArgs, InvokeHostFunctionOp, LedgerEntryData, + Limits, Memo, MuxedAccount, Operation, OperationBody, Preconditions, PublicKey, + ScSpecEntry, SequenceNumber, String32, StringM, Thresholds, Transaction, TransactionExt, + Uint256, VecM, WriteXdr, + }, + Pwd, }; use soroban_spec_tools::contract; @@ -80,10 +78,6 @@ impl Pwd for Cmd { pub enum Error { #[error("cannot add contract to ledger entries: {0}")] CannotAddContractToLedgerEntries(xdr::Error), - #[error(transparent)] - // TODO: the Display impl of host errors is pretty user-unfriendly - // (it just calls Debug). I think we can do better than that - Host(#[from] HostError), #[error("reading file {0:?}: {1}")] CannotReadContractFile(PathBuf, io::Error), #[error("committing file {filepath}: {error}")] @@ -210,7 +204,7 @@ impl NetworkRunnable for Cmd { // For testing wasm arg parsing let _ = build_host_function_parameters(&contract_id, &self.slop, spec_entries, config)?; } - let client = rpc::Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; let account_details = if self.is_view { default_account_entry() } else { diff --git a/cmd/soroban-cli/src/commands/contract/mod.rs b/cmd/soroban-cli/src/commands/contract/mod.rs index 9ac6b8527..d0524e82b 100644 --- a/cmd/soroban-cli/src/commands/contract/mod.rs +++ b/cmd/soroban-cli/src/commands/contract/mod.rs @@ -53,7 +53,12 @@ pub enum Cmd { #[command(subcommand)] Info(info::Cmd), - /// Initialize a Soroban project with an example contract + /// Initialize a Soroban contract project. + /// + /// This command will create a Cargo workspace project and add a sample Stellar contract. + /// The name of the contract can be specified by `--name`. It can be run multiple times + /// with different names in order to generate multiple contracts, and files won't + /// be overwritten unless `--overwrite` is passed. Init(init::Cmd), /// (Deprecated in favor of `contract info` subcommands) Inspect a WASM file listing contract functions, meta, etc @@ -168,11 +173,11 @@ pub enum Durability { Temporary, } -impl From<&Durability> for soroban_env_host::xdr::ContractDataDurability { +impl From<&Durability> for crate::xdr::ContractDataDurability { fn from(d: &Durability) -> Self { match d { - Durability::Persistent => soroban_env_host::xdr::ContractDataDurability::Persistent, - Durability::Temporary => soroban_env_host::xdr::ContractDataDurability::Temporary, + Durability::Persistent => crate::xdr::ContractDataDurability::Persistent, + Durability::Temporary => crate::xdr::ContractDataDurability::Temporary, } } } diff --git a/cmd/soroban-cli/src/commands/contract/read.rs b/cmd/soroban-cli/src/commands/contract/read.rs index 3cb253bb1..58efc93b7 100644 --- a/cmd/soroban-cli/src/commands/contract/read.rs +++ b/cmd/soroban-cli/src/commands/contract/read.rs @@ -3,20 +3,17 @@ use std::{ io::{self, stdout}, }; -use clap::{command, Parser, ValueEnum}; -use soroban_env_host::{ - xdr::{ - ContractDataEntry, Error as XdrError, LedgerEntryData, LedgerKey, LedgerKeyContractData, - Limits, ScVal, WriteXdr, - }, - HostError, +use crate::xdr::{ + ContractDataEntry, Error as XdrError, LedgerEntryData, LedgerKey, LedgerKeyContractData, + Limits, ScVal, WriteXdr, }; +use clap::{command, Parser, ValueEnum}; use crate::{ commands::{global, NetworkRunnable}, config::{self, locator}, key, - rpc::{self, Client, FullLedgerEntries, FullLedgerEntry}, + rpc::{self, FullLedgerEntries, FullLedgerEntry}, }; #[derive(Parser, Debug, Clone)] @@ -28,7 +25,7 @@ pub struct Cmd { #[command(flatten)] pub key: key::Args, #[command(flatten)] - config: config::Args, + config: config::ArgsLocatorAndNetwork, } #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, ValueEnum)] @@ -77,10 +74,6 @@ pub enum Error { Rpc(#[from] rpc::Error), #[error(transparent)] Xdr(#[from] XdrError), - #[error(transparent)] - // TODO: the Display impl of host errors is pretty user-unfriendly - // (it just calls Debug). I think we can do better than that - Host(#[from] HostError), #[error("no matching contract data entries were found for the specified contract id")] NoContractDataEntryFoundForContractID, #[error(transparent)] @@ -89,6 +82,8 @@ pub enum Error { OnlyDataAllowed, #[error(transparent)] Locator(#[from] locator::Error), + #[error(transparent)] + Network(#[from] config::network::Error), } impl Cmd { @@ -179,14 +174,15 @@ impl NetworkRunnable for Cmd { async fn run_against_rpc_server( &self, - _: Option<&global::Args>, - config: Option<&config::Args>, + _global_args: Option<&global::Args>, + _config: Option<&config::Args>, ) -> Result { - let config = config.unwrap_or(&self.config); - let network = config.get_network()?; + let locator = self.config.locator.clone(); + let network = self.config.network.get(&locator)?; + tracing::trace!(?network); - let client = Client::new(&network.rpc_url)?; - let keys = self.key.parse_keys(&config.locator, &network)?; + let client = network.rpc_client()?; + let keys = self.key.parse_keys(&locator, &network)?; Ok(client.get_full_ledger_entries(&keys).await?) } } diff --git a/cmd/soroban-cli/src/commands/contract/restore.rs b/cmd/soroban-cli/src/commands/contract/restore.rs index 05fa90695..87a52a9f6 100644 --- a/cmd/soroban-cli/src/commands/contract/restore.rs +++ b/cmd/soroban-cli/src/commands/contract/restore.rs @@ -1,12 +1,12 @@ use std::{fmt::Debug, path::Path, str::FromStr}; -use clap::{command, Parser}; -use soroban_env_host::xdr::{ +use crate::xdr::{ Error as XdrError, ExtensionPoint, LedgerEntry, LedgerEntryChange, LedgerEntryData, LedgerFootprint, Limits, Memo, Operation, OperationBody, OperationMeta, Preconditions, RestoreFootprintOp, SequenceNumber, SorobanResources, SorobanTransactionData, Transaction, TransactionExt, TransactionMeta, TransactionMetaV3, TtlEntry, WriteXdr, }; +use clap::{command, Parser}; use stellar_strkey::DecodeError; use crate::{ @@ -17,9 +17,7 @@ use crate::{ NetworkRunnable, }, config::{self, data, locator, network}, - key, - rpc::{self, Client}, - wasm, Pwd, + key, rpc, wasm, Pwd, }; #[derive(Parser, Debug, Clone)] @@ -134,7 +132,7 @@ impl NetworkRunnable for Cmd { let network = config.get_network()?; tracing::trace!(?network); let entry_keys = self.key.parse_keys(&config.locator, &network)?; - let client = Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; let source_account = config.source_account()?; // Get the account sequence number diff --git a/cmd/soroban-cli/src/commands/events.rs b/cmd/soroban-cli/src/commands/events.rs index 5e2bda66f..a1f5de921 100644 --- a/cmd/soroban-cli/src/commands/events.rs +++ b/cmd/soroban-cli/src/commands/events.rs @@ -1,11 +1,13 @@ use clap::{arg, command, Parser}; use std::io; -use soroban_env_host::xdr::{self, Limits, ReadXdr}; +use crate::xdr::{self, Limits, ReadXdr}; use super::{global, NetworkRunnable}; -use crate::config::{self, locator, network}; -use crate::rpc; +use crate::{ + config::{self, locator, network}, + rpc, +}; #[derive(Parser, Debug, Clone)] #[group(skip)] @@ -207,7 +209,7 @@ impl NetworkRunnable for Cmd { self.network.get(&self.locator) }?; - let client = rpc::Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; client .verify_network_passphrase(Some(&network.network_passphrase)) .await?; diff --git a/cmd/soroban-cli/src/commands/keys/generate.rs b/cmd/soroban-cli/src/commands/keys/generate.rs index 16e6a7fdb..b59e227fc 100644 --- a/cmd/soroban-cli/src/commands/keys/generate.rs +++ b/cmd/soroban-cli/src/commands/keys/generate.rs @@ -4,6 +4,7 @@ use super::super::config::{ locator, network, secret::{self, Secret}, }; +use crate::{commands::global, print::Print}; #[derive(thiserror::Error, Debug)] pub enum Error { @@ -17,6 +18,7 @@ pub enum Error { #[derive(Debug, clap::Parser, Clone)] #[group(skip)] +#[allow(clippy::struct_excessive_bools)] pub struct Cmd { /// Name of identity pub name: String, @@ -46,10 +48,22 @@ pub struct Cmd { #[command(flatten)] pub network: network::Args, + + /// Fund generated key pair + #[arg(long, default_value = "false")] + pub fund: bool, } impl Cmd { - pub async fn run(&self) -> Result<(), Error> { + pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> { + if !self.fund { + Print::new(global_args.quiet).warnln( + "Behavior of `generate` will change in the \ + future, and it will no longer fund by default. If you want to fund please \ + provide `--fund` flag. If you don't need to fund your keys in the future, ignore this \ + warning. It can be suppressed with -q flag.", + ); + } let seed_phrase = if self.default_seed { Secret::test_seed_phrase() } else { diff --git a/cmd/soroban-cli/src/commands/keys/mod.rs b/cmd/soroban-cli/src/commands/keys/mod.rs index 42814092f..30df5ccee 100644 --- a/cmd/soroban-cli/src/commands/keys/mod.rs +++ b/cmd/soroban-cli/src/commands/keys/mod.rs @@ -1,3 +1,4 @@ +use crate::commands::global; use clap::Parser; pub mod add; @@ -48,12 +49,12 @@ pub enum Error { } impl Cmd { - pub async fn run(&self) -> Result<(), Error> { + pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> { match self { Cmd::Add(cmd) => cmd.run()?, Cmd::Address(cmd) => cmd.run()?, Cmd::Fund(cmd) => cmd.run().await?, - Cmd::Generate(cmd) => cmd.run().await?, + Cmd::Generate(cmd) => cmd.run(global_args).await?, Cmd::Ls(cmd) => cmd.run()?, Cmd::Rm(cmd) => cmd.run()?, Cmd::Show(cmd) => cmd.run()?, diff --git a/cmd/soroban-cli/src/commands/mod.rs b/cmd/soroban-cli/src/commands/mod.rs index b2e431e6e..0a1d4629b 100644 --- a/cmd/soroban-cli/src/commands/mod.rs +++ b/cmd/soroban-cli/src/commands/mod.rs @@ -113,7 +113,7 @@ impl Root { Cmd::Network(network) => network.run(&self.global_args).await?, Cmd::Snapshot(snapshot) => snapshot.run(&self.global_args).await?, Cmd::Version(version) => version.run(), - Cmd::Keys(id) => id.run().await?, + Cmd::Keys(id) => id.run(&self.global_args).await?, Cmd::Tx(tx) => tx.run(&self.global_args).await?, Cmd::Cache(data) => data.run()?, }; diff --git a/cmd/soroban-cli/src/commands/snapshot/create.rs b/cmd/soroban-cli/src/commands/snapshot/create.rs index 13bef9465..6ce48d3f2 100644 --- a/cmd/soroban-cli/src/commands/snapshot/create.rs +++ b/cmd/soroban-cli/src/commands/snapshot/create.rs @@ -27,7 +27,6 @@ use tokio::io::BufReader; use tokio_util::io::StreamReader; use url::Url; -use crate::utils::http; use crate::{ commands::{config::data, global, HEADING_RPC}, config::{self, locator, network::passphrase}, @@ -35,6 +34,7 @@ use crate::{ tx::builder, utils::get_name_from_stellar_asset_contract_storage, }; +use crate::{config::address::Address, utils::http}; #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, ValueEnum)] pub enum Output { @@ -55,7 +55,7 @@ fn default_out_path() -> PathBuf { /// /// Filters (address, wasm-hash) specify what ledger entries to include. /// -/// Account addresses include the account, and trust lines. +/// Account addresses include the account, and trustlines. /// /// Contract addresses include the related wasm, contract data. /// @@ -63,6 +63,9 @@ fn default_out_path() -> PathBuf { /// account and trust lines, but does not include all the trust lines of other /// accounts holding the asset. To include them specify the addresses of /// relevant accounts. +/// +/// Any invalid contract id passed as `--address` will be ignored. +/// #[derive(Parser, Debug, Clone)] #[group(skip)] #[command(arg_required_else_help = true)] @@ -70,9 +73,9 @@ pub struct Cmd { /// The ledger sequence number to snapshot. Defaults to latest history archived ledger. #[arg(long)] ledger: Option, - /// Account or contract address to include in the snapshot. + /// Account or contract address/alias to include in the snapshot. #[arg(long = "address", help_heading = "Filter Options")] - address: Vec, + address: Vec, /// WASM hashes to include in the snapshot. #[arg(long = "wasm-hash", help_heading = "Filter Options")] wasm_hashes: Vec, @@ -213,11 +216,13 @@ impl Cmd { } // Search the buckets using the user inputs as the starting inputs. - let (account_ids, contract_ids): (HashSet, HashSet) = - self.address.iter().cloned().partition_map(|a| match a { - ScAddress::Account(account_id) => Either::Left(account_id), - ScAddress::Contract(_) => Either::Right(a), - }); + let (account_ids, contract_ids): (HashSet, HashSet) = self + .address + .iter() + .cloned() + .filter_map(|a| self.resolve_address(&a, network_passphrase)) + .partition_map(|a| a); + let mut current = SearchInputs { account_ids, contract_ids, @@ -388,6 +393,44 @@ impl Cmd { }) .ok_or(Error::ArchiveUrlNotConfigured) } + + fn resolve_address( + &self, + address: &str, + network_passphrase: &str, + ) -> Option> { + self.resolve_contract(address, network_passphrase) + .map(Either::Right) + .or_else(|| self.resolve_account(address).map(Either::Left)) + } + + // Resolve an account address to an account id. The address can be a + // G-address or a key name (as in `stellar keys address NAME`). + fn resolve_account(&self, address: &str) -> Option { + let address: Address = address.parse().ok()?; + + Some(AccountId(xdr::PublicKey::PublicKeyTypeEd25519( + match address.resolve_muxed_account(&self.locator, None).ok()? { + xdr::MuxedAccount::Ed25519(uint256) => uint256, + xdr::MuxedAccount::MuxedEd25519(xdr::MuxedAccountMed25519 { ed25519, .. }) => { + ed25519 + } + }, + ))) + } + // Resolve a contract address to a contract id. The contract can be a + // C-address or a contract alias. + fn resolve_contract(&self, address: &str, network_passphrase: &str) -> Option { + address.parse().ok().or_else(|| { + Some(ScAddress::Contract( + self.locator + .resolve_contract_id(address, network_passphrase) + .ok()? + .0 + .into(), + )) + }) + } } async fn get_history( diff --git a/cmd/soroban-cli/src/commands/tx/hash.rs b/cmd/soroban-cli/src/commands/tx/hash.rs index 8d8ec6d82..c422302f6 100644 --- a/cmd/soroban-cli/src/commands/tx/hash.rs +++ b/cmd/soroban-cli/src/commands/tx/hash.rs @@ -7,7 +7,7 @@ pub enum Error { #[error(transparent)] TxEnvelopeFromStdin(#[from] super::xdr::Error), #[error(transparent)] - XdrToBase64(#[from] soroban_env_host::xdr::Error), + XdrToBase64(#[from] crate::xdr::Error), #[error(transparent)] Config(#[from] network::Error), } diff --git a/cmd/soroban-cli/src/commands/tx/new/set_trustline_flags.rs b/cmd/soroban-cli/src/commands/tx/new/set_trustline_flags.rs index 2955fe5b0..d9b70ecbd 100644 --- a/cmd/soroban-cli/src/commands/tx/new/set_trustline_flags.rs +++ b/cmd/soroban-cli/src/commands/tx/new/set_trustline_flags.rs @@ -1,8 +1,6 @@ use clap::{command, Parser}; -use soroban_sdk::xdr::{self}; - -use crate::{commands::tx, tx::builder}; +use crate::{commands::tx, tx::builder, xdr}; #[allow(clippy::struct_excessive_bools, clippy::doc_markdown)] #[derive(Parser, Debug, Clone)] diff --git a/cmd/soroban-cli/src/commands/tx/send.rs b/cmd/soroban-cli/src/commands/tx/send.rs index c3856114d..22fbc860a 100644 --- a/cmd/soroban-cli/src/commands/tx/send.rs +++ b/cmd/soroban-cli/src/commands/tx/send.rs @@ -1,8 +1,10 @@ use async_trait::async_trait; use soroban_rpc::GetTransactionResponse; -use crate::commands::{global, NetworkRunnable}; -use crate::config::{self, locator, network}; +use crate::{ + commands::{global, NetworkRunnable}, + config::{self, locator, network}, +}; #[derive(thiserror::Error, Debug)] pub enum Error { @@ -52,7 +54,7 @@ impl NetworkRunnable for Cmd { } else { self.network.get(&self.locator)? }; - let client = crate::rpc::Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; let tx_env = super::xdr::tx_envelope_from_stdin()?; Ok(client.send_transaction_polling(&tx_env).await?) } diff --git a/cmd/soroban-cli/src/commands/tx/simulate.rs b/cmd/soroban-cli/src/commands/tx/simulate.rs index 1f534884d..cb2ed7c69 100644 --- a/cmd/soroban-cli/src/commands/tx/simulate.rs +++ b/cmd/soroban-cli/src/commands/tx/simulate.rs @@ -16,6 +16,8 @@ pub enum Error { Rpc(#[from] crate::rpc::Error), #[error(transparent)] Xdr(#[from] xdr::Error), + #[error(transparent)] + Network(#[from] config::network::Error), } /// Command to simulate a transaction envelope via rpc @@ -50,7 +52,7 @@ impl NetworkRunnable for Cmd { ) -> Result { let config = config.unwrap_or(&self.config); let network = config.get_network()?; - let client = crate::rpc::Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; let tx = super::xdr::unwrap_envelope_v1(super::xdr::tx_envelope_from_stdin()?)?; let tx = simulate_and_assemble_transaction(&client, &tx).await?; Ok(tx) diff --git a/cmd/soroban-cli/src/commands/tx/xdr.rs b/cmd/soroban-cli/src/commands/tx/xdr.rs index 71bd59af6..fcacce9ac 100644 --- a/cmd/soroban-cli/src/commands/tx/xdr.rs +++ b/cmd/soroban-cli/src/commands/tx/xdr.rs @@ -3,8 +3,7 @@ use std::{ path::PathBuf, }; -use soroban_env_host::xdr::ReadXdr; -use soroban_sdk::xdr::{Limits, Transaction, TransactionEnvelope, TransactionV1Envelope}; +use crate::xdr::{Limits, ReadXdr, Transaction, TransactionEnvelope, TransactionV1Envelope}; #[derive(Debug, thiserror::Error)] pub enum Error { diff --git a/cmd/soroban-cli/src/commands/txn_result.rs b/cmd/soroban-cli/src/commands/txn_result.rs index 08482e94f..d6b308b3a 100644 --- a/cmd/soroban-cli/src/commands/txn_result.rs +++ b/cmd/soroban-cli/src/commands/txn_result.rs @@ -1,4 +1,4 @@ -use soroban_env_host::xdr::{Transaction, TransactionEnvelope, TransactionV1Envelope, VecM}; +use crate::xdr::{Transaction, TransactionEnvelope, TransactionV1Envelope, VecM}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum TxnResult { diff --git a/cmd/soroban-cli/src/commands/version.rs b/cmd/soroban-cli/src/commands/version.rs index 5e6d0e4dd..f785399e9 100644 --- a/cmd/soroban-cli/src/commands/version.rs +++ b/cmd/soroban-cli/src/commands/version.rs @@ -1,5 +1,4 @@ use clap::Parser; -use soroban_env_host::meta; use std::fmt::Debug; #[derive(Parser, Debug, Clone)] @@ -22,12 +21,9 @@ pub fn git() -> &'static str { } pub fn long() -> String { - let env = soroban_env_host::VERSION; - let xdr = soroban_env_host::VERSION.xdr; + let xdr = stellar_xdr::VERSION; [ format!("{} ({})", pkg(), git()), - format!("soroban-env {} ({})", env.pkg, env.rev), - format!("soroban-env interface version {}", meta::INTERFACE_VERSION), format!( "stellar-xdr {} ({}) xdr curr ({})", diff --git a/cmd/soroban-cli/src/config/mod.rs b/cmd/soroban-cli/src/config/mod.rs index 12f571a50..b961f0f67 100644 --- a/cmd/soroban-cli/src/config/mod.rs +++ b/cmd/soroban-cli/src/config/mod.rs @@ -2,8 +2,6 @@ use address::Address; use clap::{arg, command}; use serde::{Deserialize, Serialize}; -use soroban_rpc::Client; - use crate::{ print::Print, signer::{self, LocalKey, Signer, SignerKind}, @@ -98,7 +96,7 @@ impl Args { ) -> Result, Error> { let network = self.get_network()?; let source_key = self.key_pair()?; - let client = Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; let latest_ledger = client.get_latest_ledger().await?.sequence; let seq_num = latest_ledger + 60; // ~ 5 min Ok(signer::sign_soroban_authorizations( @@ -116,7 +114,7 @@ impl Args { pub async fn next_sequence_number(&self, account_str: &str) -> Result { let network = self.get_network()?; - let client = Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; Ok((client.get_account(account_str).await?.seq_num.0 + 1).into()) } } diff --git a/cmd/soroban-cli/src/config/network.rs b/cmd/soroban-cli/src/config/network.rs index b6f6d8c1d..ac7dc04bc 100644 --- a/cmd/soroban-cli/src/config/network.rs +++ b/cmd/soroban-cli/src/config/network.rs @@ -1,7 +1,11 @@ use clap::arg; +use itertools::Itertools; +use jsonrpsee_http_client::HeaderMap; use phf::phf_map; +use reqwest::header::{HeaderName, HeaderValue, InvalidHeaderName, InvalidHeaderValue}; use serde::{Deserialize, Serialize}; use serde_json::Value; +use std::collections::HashMap; use std::str::FromStr; use stellar_strkey::ed25519::PublicKey; use url::Url; @@ -30,6 +34,12 @@ pub enum Error { InvalidUrl(String), #[error("funding failed: {0}")] FundingFailed(String), + #[error(transparent)] + InvalidHeaderName(#[from] InvalidHeaderName), + #[error(transparent)] + InvalidHeaderValue(#[from] InvalidHeaderValue), + #[error("invalid HTTP header: must be in the form 'key:value'")] + InvalidHeader, } #[derive(Debug, clap::Args, Clone, Default)] @@ -44,6 +54,17 @@ pub struct Args { help_heading = HEADING_RPC, )] pub rpc_url: Option, + /// RPC Header(s) to include in requests to the RPC provider + #[arg( + long = "rpc-header", + env = "STELLAR_RPC_HEADERS", + help_heading = HEADING_RPC, + num_args = 1, + action = clap::ArgAction::Append, + value_delimiter = '\n', + value_parser = parse_http_header, + )] + pub rpc_headers: Vec<(String, String)>, /// Network passphrase to sign the transaction sent to the rpc server #[arg( long = "network-passphrase", @@ -76,6 +97,7 @@ impl Args { { Ok(Network { rpc_url, + rpc_headers: self.rpc_headers.clone(), network_passphrase, }) } else { @@ -94,6 +116,17 @@ pub struct Network { help_heading = HEADING_RPC, )] pub rpc_url: String, + /// Optional header (e.g. API Key) to include in requests to the RPC + #[arg( + long = "rpc-header", + env = "STELLAR_RPC_HEADERS", + help_heading = HEADING_RPC, + num_args = 1, + action = clap::ArgAction::Append, + value_delimiter = '\n', + value_parser = parse_http_header, + )] + pub rpc_headers: Vec<(String, String)>, /// Network passphrase to sign the transaction sent to the rpc server #[arg( long, @@ -103,6 +136,21 @@ pub struct Network { pub network_passphrase: String, } +fn parse_http_header(header: &str) -> Result<(String, String), Error> { + let header_components = header.splitn(2, ':'); + + let (key, value) = header_components + .map(str::trim) + .next_tuple() + .ok_or_else(|| Error::InvalidHeader)?; + + // Check that the headers are properly formatted + HeaderName::from_str(key)?; + HeaderValue::from_str(value)?; + + Ok((key.to_string(), value.to_string())) +} + impl Network { pub async fn helper_url(&self, addr: &str) -> Result { tracing::debug!("address {addr:?}"); @@ -160,6 +208,19 @@ impl Network { pub fn rpc_uri(&self) -> Result { Url::from_str(&self.rpc_url).map_err(|_| Error::InvalidUrl(self.rpc_url.to_string())) } + + pub fn rpc_client(&self) -> Result { + let mut header_hash_map = HashMap::new(); + for (header_name, header_value) in &self.rpc_headers { + header_hash_map.insert(header_name.to_string(), header_value.to_string()); + } + + let header_map: HeaderMap = (&header_hash_map) + .try_into() + .map_err(|_| Error::InvalidHeader)?; + + Ok(rpc::Client::new_with_headers(&self.rpc_url, header_map)?) + } } pub static DEFAULTS: phf::Map<&'static str, (&'static str, &'static str)> = phf_map! { @@ -186,6 +247,7 @@ impl From<&(&str, &str)> for Network { fn from(n: &(&str, &str)) -> Self { Self { rpc_url: n.0.to_string(), + rpc_headers: Vec::new(), network_passphrase: n.1.to_string(), } } @@ -197,11 +259,15 @@ mod tests { use mockito::Server; use serde_json::json; + const INVALID_HEADER_NAME: &str = "api key"; + const INVALID_HEADER_VALUE: &str = "cannot include a carriage return \r in the value"; + #[tokio::test] async fn test_helper_url_local_network() { let network = Network { rpc_url: "http://localhost:8000".to_string(), network_passphrase: passphrase::LOCAL.to_string(), + rpc_headers: Vec::new(), }; let result = network @@ -239,6 +305,7 @@ mod tests { let network = Network { rpc_url: server.url(), network_passphrase: passphrase::TESTNET.to_string(), + rpc_headers: Vec::new(), }; let url = network .helper_url("GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI") @@ -269,6 +336,7 @@ mod tests { let network = Network { rpc_url: server.url(), network_passphrase: passphrase::TESTNET.to_string(), + rpc_headers: Vec::new(), }; let url = network .helper_url("GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI") @@ -276,4 +344,107 @@ mod tests { .unwrap(); assert_eq!(url.as_str(), "https://friendbot.stellar.org/secret?api_key=123456&user=demo&addr=GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI"); } + + // testing parse_header function + #[tokio::test] + async fn test_parse_http_header_ok() { + let result = parse_http_header("Authorization: Bearer 1234"); + assert!(result.is_ok()); + } + + #[tokio::test] + async fn test_parse_http_header_error_with_invalid_name() { + let invalid_header = format!("{INVALID_HEADER_NAME}: Bearer 1234"); + let result = parse_http_header(&invalid_header); + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().to_string(), + format!("invalid HTTP header name") + ); + } + + #[tokio::test] + async fn test_parse_http_header_error_with_invalid_value() { + let invalid_header = format!("Authorization: {INVALID_HEADER_VALUE}"); + let result = parse_http_header(&invalid_header); + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().to_string(), + format!("failed to parse header value") + ); + } + + // testing rpc_client function - we're testing this and the parse_http_header function separately because when a user has their network already configured in a toml file, the parse_http_header function is not called and we want to make sure that if the toml file is correctly formatted, the rpc_client function will work as expected + + #[tokio::test] + async fn test_rpc_client_is_ok_when_there_are_no_headers() { + let network = Network { + rpc_url: "http://localhost:1234".to_string(), + network_passphrase: "Network passphrase".to_string(), + rpc_headers: [].to_vec(), + }; + + let result = network.rpc_client(); + assert!(result.is_ok()); + } + + #[tokio::test] + async fn test_rpc_client_is_ok_with_correctly_formatted_headers() { + let network = Network { + rpc_url: "http://localhost:1234".to_string(), + network_passphrase: "Network passphrase".to_string(), + rpc_headers: [("Authorization".to_string(), "Bearer 1234".to_string())].to_vec(), + }; + + let result = network.rpc_client(); + assert!(result.is_ok()); + } + + #[tokio::test] + async fn test_rpc_client_is_ok_with_multiple_headers() { + let network = Network { + rpc_url: "http://localhost:1234".to_string(), + network_passphrase: "Network passphrase".to_string(), + rpc_headers: [ + ("Authorization".to_string(), "Bearer 1234".to_string()), + ("api-key".to_string(), "5678".to_string()), + ] + .to_vec(), + }; + + let result = network.rpc_client(); + assert!(result.is_ok()); + } + + #[tokio::test] + async fn test_rpc_client_returns_err_with_invalid_header_name() { + let network = Network { + rpc_url: "http://localhost:8000".to_string(), + network_passphrase: passphrase::LOCAL.to_string(), + rpc_headers: [(INVALID_HEADER_NAME.to_string(), "Bearer".to_string())].to_vec(), + }; + + let result = network.rpc_client(); + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().to_string(), + format!("invalid HTTP header: must be in the form 'key:value'") + ); + } + + #[tokio::test] + async fn test_rpc_client_returns_err_with_invalid_header_value() { + let network = Network { + rpc_url: "http://localhost:8000".to_string(), + network_passphrase: passphrase::LOCAL.to_string(), + rpc_headers: [("api-key".to_string(), INVALID_HEADER_VALUE.to_string())].to_vec(), + }; + + let result = network.rpc_client(); + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().to_string(), + format!("invalid HTTP header: must be in the form 'key:value'") + ); + } } diff --git a/cmd/soroban-cli/src/fee.rs b/cmd/soroban-cli/src/fee.rs index c2bc32bdb..ea968870f 100644 --- a/cmd/soroban-cli/src/fee.rs +++ b/cmd/soroban-cli/src/fee.rs @@ -1,9 +1,13 @@ use clap::arg; use crate::assembled::Assembled; -use soroban_env_host::xdr; +use crate::xdr; -use crate::commands::HEADING_RPC; +use crate::{commands::HEADING_RPC, deprecated_arg}; + +const DEPRECATION_MESSAGE: &str = "--sim-only is deprecated and will be removed \ +in the future versions of CLI. The same functionality is offered by `tx simulate` command. To \ +replicate the behaviour, run `stellar --build only | stellar tx simulate`"; #[derive(Debug, clap::Args, Clone)] #[group(skip)] @@ -20,8 +24,14 @@ pub struct Args { /// Build the transaction and only write the base64 xdr to stdout #[arg(long, help_heading = HEADING_RPC)] pub build_only: bool, - /// Simulate the transaction and only write the base64 xdr to stdout - #[arg(long, help_heading = HEADING_RPC, conflicts_with = "build_only")] + /// (Deprecated) simulate the transaction and only write the base64 xdr to stdout + #[arg( + long, + help_heading = HEADING_RPC, + conflicts_with = "build_only", + display_order = 100, + value_parser = deprecated_arg!(bool, DEPRECATION_MESSAGE)) + ] pub sim_only: bool, } diff --git a/cmd/soroban-cli/src/get_spec.rs b/cmd/soroban-cli/src/get_spec.rs index 125fa984c..26e609543 100644 --- a/cmd/soroban-cli/src/get_spec.rs +++ b/cmd/soroban-cli/src/get_spec.rs @@ -1,8 +1,6 @@ -use soroban_env_host::xdr; +use crate::xdr; -use soroban_env_host::xdr::{ - ContractDataEntry, ContractExecutable, ScContractInstance, ScSpecEntry, ScVal, -}; +use crate::xdr::{ContractDataEntry, ContractExecutable, ScContractInstance, ScSpecEntry, ScVal}; use soroban_spec::read::FromWasmError; pub use soroban_spec_tools::contract as contract_spec; diff --git a/cmd/soroban-cli/src/key.rs b/cmd/soroban-cli/src/key.rs index b4fd358aa..3f4dcaf7c 100644 --- a/cmd/soroban-cli/src/key.rs +++ b/cmd/soroban-cli/src/key.rs @@ -1,13 +1,13 @@ +use crate::xdr::{ + self, LedgerKey, LedgerKeyContractCode, LedgerKeyContractData, Limits, ReadXdr, ScAddress, + ScVal, +}; use crate::{ commands::contract::Durability, config::{locator, network::Network}, wasm, }; use clap::arg; -use soroban_env_host::xdr::{ - self, LedgerKey, LedgerKeyContractCode, LedgerKeyContractData, Limits, ReadXdr, ScAddress, - ScVal, -}; use std::path::PathBuf; #[derive(thiserror::Error, Debug)] diff --git a/cmd/soroban-cli/src/lib.rs b/cmd/soroban-cli/src/lib.rs index 4c904855c..302ecab00 100644 --- a/cmd/soroban-cli/src/lib.rs +++ b/cmd/soroban-cli/src/lib.rs @@ -5,8 +5,8 @@ )] use std::path::Path; -pub(crate) use soroban_env_host::xdr; pub(crate) use soroban_rpc as rpc; +pub use stellar_xdr::curr as xdr; mod cli; pub use cli::main; diff --git a/cmd/soroban-cli/src/log.rs b/cmd/soroban-cli/src/log.rs index 28ed4041b..1a1c27035 100644 --- a/cmd/soroban-cli/src/log.rs +++ b/cmd/soroban-cli/src/log.rs @@ -1,17 +1,14 @@ use crate::xdr; + pub mod auth; -pub mod budget; pub mod cost; pub mod event; pub mod footprint; -pub mod host_event; pub use auth::*; -pub use budget::*; pub use cost::*; pub use event::*; pub use footprint::*; -pub use host_event::*; pub fn extract_events(tx_meta: &xdr::TransactionMeta) -> Vec { match tx_meta { diff --git a/cmd/soroban-cli/src/log/auth.rs b/cmd/soroban-cli/src/log/auth.rs index c37e7ed3e..4a6b4bea8 100644 --- a/cmd/soroban-cli/src/log/auth.rs +++ b/cmd/soroban-cli/src/log/auth.rs @@ -1,4 +1,4 @@ -use soroban_env_host::xdr::{SorobanAuthorizationEntry, VecM}; +use crate::xdr::{SorobanAuthorizationEntry, VecM}; pub fn auth(auth: &[VecM]) { if !auth.is_empty() { diff --git a/cmd/soroban-cli/src/log/budget.rs b/cmd/soroban-cli/src/log/budget.rs deleted file mode 100644 index 59ff4aad4..000000000 --- a/cmd/soroban-cli/src/log/budget.rs +++ /dev/null @@ -1,5 +0,0 @@ -use soroban_env_host::budget::Budget; - -pub fn budget(budget: &Budget) { - tracing::debug!("{budget:#?}"); -} diff --git a/cmd/soroban-cli/src/log/cost.rs b/cmd/soroban-cli/src/log/cost.rs index 3e049a6cd..8dfc18df6 100644 --- a/cmd/soroban-cli/src/log/cost.rs +++ b/cmd/soroban-cli/src/log/cost.rs @@ -1,4 +1,4 @@ -use soroban_env_host::xdr::SorobanResources; +use crate::xdr::SorobanResources; use std::fmt::{Debug, Display}; struct Cost<'a>(&'a SorobanResources); diff --git a/cmd/soroban-cli/src/log/footprint.rs b/cmd/soroban-cli/src/log/footprint.rs index bfbc9f7a3..7c351de1d 100644 --- a/cmd/soroban-cli/src/log/footprint.rs +++ b/cmd/soroban-cli/src/log/footprint.rs @@ -1,4 +1,4 @@ -use soroban_env_host::xdr::LedgerFootprint; +use crate::xdr::LedgerFootprint; pub fn footprint(footprint: &LedgerFootprint) { tracing::debug!("{footprint:#?}"); diff --git a/cmd/soroban-cli/src/log/host_event.rs b/cmd/soroban-cli/src/log/host_event.rs deleted file mode 100644 index 4238a74c3..000000000 --- a/cmd/soroban-cli/src/log/host_event.rs +++ /dev/null @@ -1,7 +0,0 @@ -use soroban_env_host::events::HostEvent; - -pub fn host_events(events: &[HostEvent]) { - for (i, event) in events.iter().enumerate() { - tracing::info!("{i}: {event:#?}"); - } -} diff --git a/cmd/soroban-cli/src/print.rs b/cmd/soroban-cli/src/print.rs index 5b98687bd..5b8ca2bd2 100644 --- a/cmd/soroban-cli/src/print.rs +++ b/cmd/soroban-cli/src/print.rs @@ -1,6 +1,6 @@ use std::{env, fmt::Display}; -use soroban_env_host::xdr::{Error as XdrError, Transaction}; +use crate::xdr::{Error as XdrError, Transaction}; use crate::{ config::network::Network, utils::explorer_url_for_transaction, utils::transaction_hash, diff --git a/cmd/soroban-cli/src/signer.rs b/cmd/soroban-cli/src/signer.rs index bf02fdb17..5bf22499c 100644 --- a/cmd/soroban-cli/src/signer.rs +++ b/cmd/soroban-cli/src/signer.rs @@ -1,7 +1,7 @@ use ed25519_dalek::ed25519::signature::Signer as _; use sha2::{Digest, Sha256}; -use soroban_env_host::xdr::{ +use crate::xdr::{ self, AccountId, DecoratedSignature, Hash, HashIdPreimage, HashIdPreimageSorobanAuthorization, InvokeHostFunctionOp, Limits, Operation, OperationBody, PublicKey, ScAddress, ScMap, ScSymbol, ScVal, Signature, SignatureHint, SorobanAddressCredentials, SorobanAuthorizationEntry, diff --git a/cmd/soroban-cli/src/tx/builder/transaction.rs b/cmd/soroban-cli/src/tx/builder/transaction.rs index 51232d5c5..7cd922679 100644 --- a/cmd/soroban-cli/src/tx/builder/transaction.rs +++ b/cmd/soroban-cli/src/tx/builder/transaction.rs @@ -28,7 +28,7 @@ impl TxExt for xdr::Transaction { source_account, fee, seq_num: seq_num.into(), - cond: soroban_env_host::xdr::Preconditions::None, + cond: crate::xdr::Preconditions::None, memo: Memo::None, operations: [operation].try_into().unwrap(), ext: TransactionExt::V0, diff --git a/cmd/soroban-cli/src/upgrade_check.rs b/cmd/soroban-cli/src/upgrade_check.rs index 294056dd1..81ad7a0ee 100644 --- a/cmd/soroban-cli/src/upgrade_check.rs +++ b/cmd/soroban-cli/src/upgrade_check.rs @@ -56,7 +56,7 @@ pub async fn upgrade_check(quiet: bool) { let current_version = crate::commands::version::pkg(); let mut stats = UpgradeCheck::load().unwrap_or_else(|e| { - tracing::error!("Failed to load upgrade check data: {e}"); + tracing::debug!("Failed to load upgrade check data: {e}"); UpgradeCheck::default() }); @@ -72,7 +72,7 @@ pub async fn upgrade_check(quiet: bool) { }; } Err(e) => { - tracing::error!("Failed to fetch stellar-cli info from crates.io: {e}"); + tracing::debug!("Failed to fetch stellar-cli info from crates.io: {e}"); // Only update the latest check time if the fetch failed // This way we don't spam the user with errors stats.latest_check_time = now; @@ -80,7 +80,7 @@ pub async fn upgrade_check(quiet: bool) { } if let Err(e) = stats.save() { - tracing::error!("Failed to save upgrade check data: {e}"); + tracing::debug!("Failed to save upgrade check data: {e}"); } } diff --git a/cmd/soroban-cli/src/utils.rs b/cmd/soroban-cli/src/utils.rs index ee8bb1ece..6e87d15a6 100644 --- a/cmd/soroban-cli/src/utils.rs +++ b/cmd/soroban-cli/src/utils.rs @@ -2,7 +2,7 @@ use phf::phf_map; use sha2::{Digest, Sha256}; use stellar_strkey::ed25519::PrivateKey; -use soroban_env_host::xdr::{ +use crate::xdr::{ self, Asset, ContractIdPreimage, Hash, HashIdPreimage, HashIdPreimageContractId, Limits, ScMap, ScMapEntry, ScVal, Transaction, TransactionSignaturePayload, TransactionSignaturePayloadTaggedTransaction, WriteXdr, @@ -196,8 +196,45 @@ pub mod http { } } +pub mod args { + #[derive(thiserror::Error, Debug)] + pub enum DeprecatedError<'a> { + #[error("This argument has been removed and will be not be recognized by the future versions of CLI: {0}" + )] + RemovedArgument(&'a str), + } + + #[macro_export] + /// Mark argument as removed with an error to be printed when it's used. + macro_rules! error_on_use_of_removed_arg { + ($_type:ident, $message: expr) => { + |a: &str| { + Err::<$_type, utils::args::DeprecatedError>( + utils::args::DeprecatedError::RemovedArgument($message), + ) + } + }; + } + + /// Mark argument as deprecated with warning to be printed when it's used. + #[macro_export] + macro_rules! deprecated_arg { + (bool, $message: expr) => { + <_ as clap::builder::TypedValueParser>::map( + clap::builder::BoolValueParser::new(), + |x| { + if (x) { + $crate::print::Print::new(false).warnln($message); + } + x + }, + ) + }; + } +} + pub mod rpc { - use soroban_env_host::xdr; + use crate::xdr; use soroban_rpc::{Client, Error}; use stellar_xdr::curr::{Hash, LedgerEntryData, LedgerKey, Limits, ReadXdr}; diff --git a/cmd/soroban-cli/src/utils/contract-init-template/contracts/hello_world/Cargo.toml.removeextension b/cmd/soroban-cli/src/utils/contract-template/Cargo.toml.removeextension similarity index 89% rename from cmd/soroban-cli/src/utils/contract-init-template/contracts/hello_world/Cargo.toml.removeextension rename to cmd/soroban-cli/src/utils/contract-template/Cargo.toml.removeextension index 2d8b3ac4e..8da1aed87 100644 --- a/cmd/soroban-cli/src/utils/contract-init-template/contracts/hello_world/Cargo.toml.removeextension +++ b/cmd/soroban-cli/src/utils/contract-template/Cargo.toml.removeextension @@ -1,5 +1,5 @@ [package] -name = "hello-world" +name = "%contract-template%" version = "0.0.0" edition = "2021" publish = false diff --git a/cmd/soroban-cli/src/utils/contract-template/Makefile b/cmd/soroban-cli/src/utils/contract-template/Makefile new file mode 100644 index 000000000..7f774ad12 --- /dev/null +++ b/cmd/soroban-cli/src/utils/contract-template/Makefile @@ -0,0 +1,16 @@ +default: build + +all: test + +test: build + cargo test + +build: + stellar contract build + @ls -l target/wasm32-unknown-unknown/release/*.wasm + +fmt: + cargo fmt --all + +clean: + cargo clean diff --git a/cmd/soroban-cli/src/utils/contract-init-template/contracts/hello_world/src/lib.rs b/cmd/soroban-cli/src/utils/contract-template/src/lib.rs similarity index 100% rename from cmd/soroban-cli/src/utils/contract-init-template/contracts/hello_world/src/lib.rs rename to cmd/soroban-cli/src/utils/contract-template/src/lib.rs diff --git a/cmd/soroban-cli/src/utils/contract-init-template/contracts/hello_world/src/test.rs b/cmd/soroban-cli/src/utils/contract-template/src/test.rs similarity index 100% rename from cmd/soroban-cli/src/utils/contract-init-template/contracts/hello_world/src/test.rs rename to cmd/soroban-cli/src/utils/contract-template/src/test.rs diff --git a/cmd/soroban-cli/src/utils/contract-init-template/.gitignore b/cmd/soroban-cli/src/utils/contract-workspace-template/.gitignore similarity index 100% rename from cmd/soroban-cli/src/utils/contract-init-template/.gitignore rename to cmd/soroban-cli/src/utils/contract-workspace-template/.gitignore diff --git a/cmd/soroban-cli/src/utils/contract-init-template/Cargo.toml.removeextension b/cmd/soroban-cli/src/utils/contract-workspace-template/Cargo.toml.removeextension similarity index 100% rename from cmd/soroban-cli/src/utils/contract-init-template/Cargo.toml.removeextension rename to cmd/soroban-cli/src/utils/contract-workspace-template/Cargo.toml.removeextension diff --git a/cmd/soroban-cli/src/utils/contract-init-template/README.md b/cmd/soroban-cli/src/utils/contract-workspace-template/README.md similarity index 100% rename from cmd/soroban-cli/src/utils/contract-init-template/README.md rename to cmd/soroban-cli/src/utils/contract-workspace-template/README.md diff --git a/cmd/soroban-cli/src/wasm.rs b/cmd/soroban-cli/src/wasm.rs index 7ab2c243d..5f0ed3b5c 100644 --- a/cmd/soroban-cli/src/wasm.rs +++ b/cmd/soroban-cli/src/wasm.rs @@ -1,9 +1,6 @@ -use crate::config::locator; -use crate::config::network::Network; +use crate::xdr::{self, Hash, LedgerKey, LedgerKeyContractCode}; use clap::arg; use sha2::{Digest, Sha256}; -use soroban_env_host::xdr::{self, Hash, LedgerKey, LedgerKeyContractCode}; -use soroban_rpc::Client; use soroban_spec_tools::contract::{self, Spec}; use std::{ fs, io, @@ -11,10 +8,14 @@ use std::{ }; use stellar_xdr::curr::{ContractDataEntry, ContractExecutable, ScVal}; -use crate::utils::rpc::get_remote_wasm_from_hash; -use crate::utils::{self}; - -use crate::wasm::Error::{ContractIsStellarAsset, UnexpectedContractToken}; +use crate::{ + config::{ + locator, + network::{Error as NetworkError, Network}, + }, + utils::{self, rpc::get_remote_wasm_from_hash}, + wasm::Error::{ContractIsStellarAsset, UnexpectedContractToken}, +}; #[derive(thiserror::Error, Debug)] pub enum Error { @@ -47,6 +48,8 @@ pub enum Error { a network built-in asset contract that does not have a downloadable code binary" )] ContractIsStellarAsset, + #[error(transparent)] + Network(#[from] NetworkError), } #[derive(Debug, clap::Args, Clone)] @@ -128,7 +131,7 @@ pub async fn fetch_from_contract( .resolve_contract_id(contract_id, &network.network_passphrase)? .0; - let client = Client::new(&network.rpc_url)?; + let client = network.rpc_client()?; client .verify_network_passphrase(Some(&network.network_passphrase)) .await?; diff --git a/cmd/stellar-cli/README.md b/cmd/stellar-cli/README.md index 9b95e474a..48be33da7 100644 --- a/cmd/stellar-cli/README.md +++ b/cmd/stellar-cli/README.md @@ -6,12 +6,13 @@ Docs: https://developers.stellar.org ## Install +Install with Homebrew (macOS, Linux): + ``` -cargo install --locked stellar-cli +brew install stellar-cli ``` -To install with the `opt` feature, which includes a WASM optimization feature and wasm-opt built in: - +Install the latest version from source: ``` cargo install --locked stellar-cli --features opt ``` diff --git a/cookbook/contract-lifecycle.mdx b/cookbook/contract-lifecycle.mdx index b64262b34..2be63c23f 100644 --- a/cookbook/contract-lifecycle.mdx +++ b/cookbook/contract-lifecycle.mdx @@ -9,7 +9,7 @@ To manage the lifecycle of a Stellar smart contract using the CLI, follow these 1. Create an identity for Alice: ```bash -stellar keys generate alice +stellar keys generate alice -q ``` 2. Fund the identity: @@ -47,7 +47,7 @@ stellar contract invoke --id --source alice --network testnet -- f 6. View the contract's state: ```bash -stellar contract read --id --network testnet --source alice --durability --key +stellar contract read --id --network testnet --durability --key ``` Note: `` is either `persistent` or `temporary`. `KEY` provides the key of the storage entry being read. diff --git a/cookbook/payments-and-assets.mdx b/cookbook/payments-and-assets.mdx index e3be8dafc..a198973e1 100644 --- a/cookbook/payments-and-assets.mdx +++ b/cookbook/payments-and-assets.mdx @@ -17,11 +17,11 @@ By setting the `STELLAR_NETWORK` environment variable, we will not have to set t 2. Fund the accounts: ```bash -stellar keys generate alice +stellar keys generate alice -q ``` ```bash -stellar keys generate bob +stellar keys generate bob -q ``` ```bash diff --git a/flake.nix b/flake.nix index 3b826ee77..1923d75bb 100644 --- a/flake.nix +++ b/flake.nix @@ -18,25 +18,18 @@ with pkgs; { devShells.default = mkShell { + nativeBuildInputs = lib.optionals (stdenv.isDarwin) [ + pkgs.darwin.apple_sdk.frameworks.SystemConfiguration + ]; buildInputs = [ openssl pkg-config - libudev-zero jq (rust-bin.stable.latest.default.override { extensions = [ "rust-src" ]; targets = [ "wasm32-unknown-unknown" ]; }) - ]; - shellHook = - '' - echo "Using `nix --version`" - alias stellar="cargo run --bin stellar --" - [ -f ./local.sh ] && source ./local.sh - shell=$0 - shell=`basename $SHELL` - source <(stellar completion --shell $shell) - ''; + ] ++ lib.optionals (stdenv.isLinux) [libudev-zero]; }; } ); diff --git a/scripts/check-dependencies.bash b/scripts/check-dependencies.bash deleted file mode 100755 index c82d2f2b1..000000000 --- a/scripts/check-dependencies.bash +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -set -e - -SED=sed -if [ -z "$(sed --version 2>&1 | grep GNU)" ]; then - SED=gsed -fi - -CURL="curl -sL --fail-with-body" -if ! CARGO_OUTPUT=$(cargo tree -p soroban-env-host 2>&1); then - echo "The project depends on multiple versions of the soroban-env-host Rust library, please unify them." - echo "Make sure the soroban-sdk dependency indirectly points to the same soroban-env-host dependency imported explicitly." - echo - echo "This is soroban-env-host version imported by soroban-sdk:" - cargo tree --depth 1 -p soroban-sdk | grep env-host - echo - echo - echo - echo "Full error:" - echo $CARGO_OUTPUT - exit 1 -fi - -# revision of the https://github.com/stellar/rs-stellar-xdr library used by the Rust code -RS_STELLAR_XDR_REVISION="" - -# revision of https://github.com/stellar/stellar-xdr/ used by the Rust code -STELLAR_XDR_REVISION_FROM_RUST="" - -function stellar_xdr_version_from_rust_dep_tree { - LINE=$(grep stellar-xdr | head -n 1) - # try to obtain a commit - COMMIT=$(echo $LINE | $SED -n 's/.*rev=\(.*\)#.*/\1/p') - if [ -n "$COMMIT" ]; then - echo "$COMMIT" - return - fi - # obtain a crate version - echo $LINE | $SED -n 's/.*stellar-xdr \(v\)\{0,1\}\([^ ]*\).*/\2/p' -} - -if CARGO_OUTPUT=$(cargo tree --depth 0 -p stellar-xdr 2>&1); then - RS_STELLAR_XDR_REVISION=$(echo "$CARGO_OUTPUT" | stellar_xdr_version_from_rust_dep_tree) - if [ ${#RS_STELLAR_XDR_REVISION} -eq 40 ]; then - # revision is a git hash - STELLAR_XDR_REVISION_FROM_RUST=$($CURL https://raw.githubusercontent.com/stellar/rs-stellar-xdr/${RS_STELLAR_XDR_REVISION}/xdr/curr-version) - else - # revision is a crate version - CARGO_SRC_BASE_DIR=$(realpath ${CARGO_HOME:-$HOME/.cargo}/registry/src/index*) - STELLAR_XDR_REVISION_FROM_RUST=$(cat "${CARGO_SRC_BASE_DIR}/stellar-xdr-${RS_STELLAR_XDR_REVISION}/xdr/curr-version") - fi -else - echo "The project depends on multiple versions of the Rust rs-stellar-xdr library" - echo "Make sure a single version of stellar-xdr is used" - echo - echo - echo - echo "Full error:" - echo $CARGO_OUTPUT -fi