diff --git a/.gitattributes b/.gitattributes index 39fc29cb..012d1ba8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1 @@ Cargo.lock text -merge eol=lf -cmd/crates/soroban-spec-typescript/fixtures/**/* linguist-generated=true -diff diff --git a/.github/workflows/bindings-ts.yml b/.github/workflows/bindings-ts.yml deleted file mode 100644 index 62469fd7..00000000 --- a/.github/workflows/bindings-ts.yml +++ /dev/null @@ -1,43 +0,0 @@ - -name: bindings typescript - -on: - push: - branches: [main, release/**] - pull_request: - -jobs: - test: - name: test generated libraries - runs-on: ubuntu-22.04 - services: - rpc: - image: stellar/quickstart:soroban-dev@sha256:0ad51035cf7caba2fd99c7c1fad0945df6932be7d5c893e1520ccdef7d6a6ffe - ports: - - 8000:8000 - env: - ENABLE_LOGS: true - NETWORK: local - ENABLE_SOROBAN_RPC: true - options: >- - --health-cmd "curl --no-progress-meter --fail-with-body -X POST \"http://localhost:8000/soroban/rpc\" -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":8675309,\"method\":\"getNetwork\"}' && curl --no-progress-meter \"http://localhost:8000/friendbot\" | grep '\"invalid_field\": \"addr\"'" - --health-interval 10s - --health-timeout 5s - --health-retries 50 - steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - run: rustup update - - run: cargo build - - run: rustup target add wasm32-unknown-unknown - - run: make build-test-wasms - - run: npm ci && npm run test - working-directory: cmd/crates/soroban-spec-typescript/ts-tests diff --git a/.github/workflows/full-help-docs.yml b/.github/workflows/full-help-docs.yml deleted file mode 100644 index c8fbd9e0..00000000 --- a/.github/workflows/full-help-docs.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: CLI Help Doc - -on: [push, pull_request] - -permissions: - contents: read - # Optional: allow read access to pull request. Use with `only-new-issues` option. - pull-requests: read - -jobs: - doc_check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - 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: | - cargo md-gen - raw_diff=$(git diff docs/soroban-cli-full-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@v3 - 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 9028df78..c96167ad 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -118,7 +118,7 @@ jobs: cargo-hack-feature-options: --features opt --ignore-unknown-features uses: stellar/actions/.github/workflows/rust-publish-dry-run-v2.yml@main with: - crates: soroban-spec-tools soroban-spec-json soroban-spec-typescript soroban-test soroban-cli + crates: soroban-test soroban-cli runs-on: ${{ matrix.os }} target: ${{ matrix.target }} cargo-hack-feature-options: ${{ matrix.cargo-hack-feature-options }} diff --git a/Cargo.lock b/Cargo.lock index 451235fa..45bd18dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "628a8f9bd1e24b4e0db2b4bc2d000b001e7dd032d54afa60a68836aeec5aa54a" dependencies = [ "anstyle", "anstyle-parse", @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "arbitrary" @@ -106,14 +106,14 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88903cb14723e4d4003335bb7f8a14f27691649105346a0f0957466c096adfe6" +checksum = "00ad3f3a942eee60335ab4342358c161ee296829e0d16ff42fc1d6cb07815467" dependencies = [ "anstyle", "bstr", "doc-comment", - "predicates 3.0.4", + "predicates 3.1.0", "predicates-core", "predicates-tree", "wait-timeout", @@ -121,14 +121,14 @@ dependencies = [ [[package]] name = "assert_fs" -version = "1.0.13" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f070617a68e5c2ed5d06ee8dd620ee18fb72b99f6c094bed34cf8ab07c875b48" +checksum = "2cd762e110c8ed629b11b6cde59458cc1c71de78ebbcc30099fc8e0403a2a2ec" dependencies = [ "anstyle", "doc-comment", "globwalk", - "predicates 3.0.4", + "predicates 3.1.0", "predicates-core", "predicates-tree", "tempfile", @@ -136,9 +136,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" dependencies = [ "proc-macro2", "quote", @@ -186,9 +186,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -213,9 +213,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "block-buffer" @@ -237,9 +237,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c" +checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" dependencies = [ "memchr", "regex-automata 0.4.3", @@ -287,9 +287,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" +checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" dependencies = [ "serde", ] @@ -341,9 +341,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.11" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", @@ -360,9 +360,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -372,9 +372,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.4.4" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae" +checksum = "dfb0d4825b75ff281318c393e8e1b80c4da9fb75a6b1d98547d389d6fe1f48d2" dependencies = [ "clap", ] @@ -415,9 +415,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "core-foundation" @@ -437,9 +437,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -468,45 +468,37 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.16" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", ] [[package]] name = "crossbeam-utils" -version = "0.8.17" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crypto-bigint" @@ -614,9 +606,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.110" +version = "1.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7129e341034ecb940c9072817cd9007974ea696844fc4dd582dc1653a7fbe2e8" +checksum = "58ab30434ea0ff6aa640a08dda5284026a366d47565496fd40b6cbfbdd7e31a2" dependencies = [ "cc", "cxxbridge-flags", @@ -626,9 +618,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.110" +version = "1.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a24f3f5f8eed71936f21e570436f024f5c2e25628f7496aa7ccd03b90109d5" +checksum = "b649d7dfae8268450d53d109388b337b9352c7cba1fc10db4a1bc23c3dc189fb" dependencies = [ "cc", "codespan-reporting", @@ -641,15 +633,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.110" +version = "1.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06fdd177fc61050d63f67f5bd6351fac6ab5526694ea8e359cd9cd3b75857f44" +checksum = "42281b20eba5218c539295c667c18e2f50211bb11902419194c6ed1ae808e547" [[package]] name = "cxxbridge-macro" -version = "1.0.110" +version = "1.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "587663dd5fb3d10932c8aecfe7c844db1bcf0aee93eeab08fac13dc1212c2e7f" +checksum = "b45506e3c66512b0a65d291a6b452128b7b1dd9841e20d1e151addbd2c00ea50" dependencies = [ "proc-macro2", "quote", @@ -703,9 +695,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", "serde", @@ -722,12 +714,6 @@ dependencies = [ "syn 2.0.39", ] -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - [[package]] name = "difflib" version = "0.4.0" @@ -974,36 +960,36 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-sink", @@ -1063,11 +1049,11 @@ dependencies = [ [[package]] name = "globwalk" -version = "0.8.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "ignore", "walkdir", ] @@ -1085,9 +1071,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.22" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -1122,9 +1108,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" [[package]] name = "hex" @@ -1162,11 +1148,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1205,9 +1191,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -1220,7 +1206,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2", "tokio", "tower-service", "tracing", @@ -1258,9 +1244,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1297,9 +1283,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747ad1b4ae841a78e8aba0d63adbfbeaea26b517b63705d47856b73015d27060" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" dependencies = [ "crossbeam-deque", "globset", @@ -1394,9 +1380,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -1470,9 +1456,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -1485,9 +1471,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libm" @@ -1501,7 +1487,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libc", "redox_syscall", ] @@ -1517,9 +1503,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -1548,18 +1534,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "miniz_oxide" @@ -1668,9 +1645,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] @@ -1689,11 +1666,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.61" +version = "0.10.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" +checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if", "foreign-types", "libc", @@ -1730,9 +1707,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.97" +version = "0.9.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" dependencies = [ "cc", "libc", @@ -1841,15 +1818,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "platforms" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" [[package]] name = "powerfmt" @@ -1879,13 +1856,12 @@ dependencies = [ [[package]] name = "predicates" -version = "3.0.4" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dfc28575c2e3f19cb3c73b93af36460ae898d426eba6fc15b9bd2a5220758a0" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" dependencies = [ "anstyle", "difflib", - "itertools 0.11.0", "predicates-core", ] @@ -1909,23 +1885,13 @@ dependencies = [ name = "preflight" version = "20.2.0" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "libc", "sha2 0.10.8", "soroban-env-host", "soroban-simulation", ] -[[package]] -name = "pretty_assertions" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" -dependencies = [ - "diff", - "yansi", -] - [[package]] name = "prettyplease" version = "0.2.15" @@ -2122,11 +2088,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", "linux-raw-sys", @@ -2163,7 +2129,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", ] [[package]] @@ -2199,11 +2165,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2297,9 +2263,9 @@ dependencies = [ [[package]] name = "serde-aux" -version = "4.3.1" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "184eba62ebddb71658697c8b08822edee89970bf318c5362189f0de27f85b498" +checksum = "a86348501c129f3ad50c2f4635a01971f76974cd8a3f335988a0f1581c082765" dependencies = [ "chrono", "serde", @@ -2334,7 +2300,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "chrono", "hex", "indexmap 1.9.3", @@ -2453,19 +2419,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" - -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] +checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" [[package]] name = "socket2" @@ -2494,7 +2450,7 @@ version = "20.2.0" dependencies = [ "assert_cmd", "assert_fs", - "base64 0.21.5", + "base64 0.21.7", "cargo_metadata", "chrono", "clap", @@ -2531,7 +2487,7 @@ dependencies = [ "soroban-env-host", "soroban-ledger-snapshot", "soroban-sdk", - "soroban-spec", + "soroban-spec 20.1.0 (git+https://github.com/stellar/rs-soroban-sdk?rev=e6c2c900ab82b5f6eec48f69cb2cb519e19819cb)", "soroban-spec-json", "soroban-spec-rust", "soroban-spec-tools", @@ -2667,7 +2623,7 @@ dependencies = [ "rustc_version", "sha2 0.10.8", "soroban-env-common", - "soroban-spec", + "soroban-spec 20.1.0 (git+https://github.com/stellar/rs-soroban-sdk?rev=e6c2c900ab82b5f6eec48f69cb2cb519e19819cb)", "soroban-spec-rust", "stellar-xdr", "syn 2.0.39", @@ -2685,6 +2641,18 @@ dependencies = [ "thiserror", ] +[[package]] +name = "soroban-spec" +version = "20.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4550e1498552b464bf8583c16abd0670568285c1513091cf3c0ea82f41a229" +dependencies = [ + "base64 0.13.1", + "stellar-xdr", + "thiserror", + "wasmparser 0.88.0", +] + [[package]] name = "soroban-spec" version = "20.1.0" @@ -2699,13 +2667,14 @@ dependencies = [ [[package]] name = "soroban-spec-json" version = "20.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c200aff4d5c5307e9a4984cc759390ff0d66c32822824cab6cce2da0bb68f11" dependencies = [ - "pretty_assertions", "serde", "serde_derive", "serde_json", "sha2 0.9.9", - "soroban-spec", + "soroban-spec 20.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "stellar-xdr", "thiserror", ] @@ -2719,7 +2688,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "soroban-spec", + "soroban-spec 20.1.0 (git+https://github.com/stellar/rs-soroban-sdk?rev=e6c2c900ab82b5f6eec48f69cb2cb519e19819cb)", "stellar-xdr", "syn 2.0.39", "thiserror", @@ -2728,40 +2697,39 @@ dependencies = [ [[package]] name = "soroban-spec-tools" version = "20.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d624133bbf30971d5a5aa656328d8659c7675fbe71d1f2d95796cd13bf64f5f7" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "ethnum", "hex", "itertools 0.10.5", "serde_json", - "soroban-spec", + "soroban-spec 20.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "stellar-strkey 0.0.7", "stellar-xdr", "thiserror", - "tokio", "wasmparser 0.90.0", - "which", ] [[package]] name = "soroban-spec-typescript" version = "20.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250120ec096eb536804c0cac981e26a85f4357a9ddd28dcc8a870a2b41a82ac6" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "heck", "include_dir", "itertools 0.10.5", - "pretty_assertions", "prettyplease", "serde", "serde_derive", "serde_json", "sha2 0.9.9", - "soroban-spec", + "soroban-spec 20.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "stellar-xdr", - "temp-dir", "thiserror", - "walkdir", ] [[package]] @@ -2779,7 +2747,7 @@ dependencies = [ "soroban-env-host", "soroban-ledger-snapshot", "soroban-sdk", - "soroban-spec", + "soroban-spec 20.1.0 (git+https://github.com/stellar/rs-soroban-sdk?rev=e6c2c900ab82b5f6eec48f69cb2cb519e19819cb)", "soroban-spec-tools", "stellar-strkey 0.0.7", "thiserror", @@ -2922,30 +2890,24 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "temp-dir" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af547b166dd1ea4b472165569fc456cfb6818116f854690b0ff205e636523dab" - [[package]] name = "tempfile" -version = "3.8.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ "cfg-if", "fastrand", "redox_syscall", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -3010,18 +2972,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "6e3de26b0965292219b4287ff031fcba86837900fe9cd2b34ea8ad893c0953d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "268026685b2be38d7103e9e507c938a1fcb3d7e6eb15e87870b617bf37b6d581" dependencies = [ "proc-macro2", "quote", @@ -3040,9 +3002,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" dependencies = [ "deranged", "itoa", @@ -3060,9 +3022,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" dependencies = [ "time-core", ] @@ -3103,9 +3065,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", @@ -3115,7 +3077,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2", "tokio-macros", "windows-sys 0.48.0", ] @@ -3289,9 +3251,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -3391,9 +3353,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3401,9 +3363,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", @@ -3416,9 +3378,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3426,9 +3388,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", @@ -3439,9 +3401,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-opt" @@ -3572,11 +3534,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.51.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] @@ -3711,12 +3673,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" - [[package]] name = "zeroize" version = "1.7.0" diff --git a/Cargo.toml b/Cargo.toml index c88cd4ab..9da4ca95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,18 +38,6 @@ git = "https://github.com/stellar/rs-soroban-sdk" rev = "e6c2c900ab82b5f6eec48f69cb2cb519e19819cb" # path = "../rs-soroban-sdk/soroban-spec-rust" -[workspace.dependencies.soroban-spec-json] -version = "20.2.0" -path = "./cmd/crates/soroban-spec-json" - -[workspace.dependencies.soroban-spec-typescript] -version = "20.2.0" -path = "./cmd/crates/soroban-spec-typescript" - -[workspace.dependencies.soroban-spec-tools] -version = "20.2.0" -path = "./cmd/crates/soroban-spec-tools" - [workspace.dependencies.soroban-sdk] version = "=20.1.0" git = "https://github.com/stellar/rs-soroban-sdk" @@ -89,6 +77,9 @@ tracing-subscriber = "0.3.16" tracing-appender = "0.2.2" which = "4.4.0" wasmparser = "0.90.0" +soroban-spec-json = "20.2.0" +soroban-spec-tools = "20.2.0" +soroban-spec-typescript = "20.2.0" # [patch."https://github.com/stellar/rs-soroban-env"] diff --git a/Makefile b/Makefile index 000b2aef..23187151 100644 --- a/Makefile +++ b/Makefile @@ -14,10 +14,10 @@ ifeq ($(strip $(REPOSITORY_VERSION)),) endif REPOSITORY_BRANCH := "$(shell git rev-parse --abbrev-ref HEAD)" BUILD_TIMESTAMP ?= $(shell date '+%Y-%m-%dT%H:%M:%S') -GOLDFLAGS := -X 'github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/config.Version=${REPOSITORY_VERSION}' \ - -X 'github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/config.CommitHash=${REPOSITORY_COMMIT_HASH}' \ - -X 'github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/config.BuildTimestamp=${BUILD_TIMESTAMP}' \ - -X 'github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/config.Branch=${REPOSITORY_BRANCH}' +GOLDFLAGS := -X 'github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/config.Version=${REPOSITORY_VERSION}' \ + -X 'github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/config.CommitHash=${REPOSITORY_COMMIT_HASH}' \ + -X 'github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/config.BuildTimestamp=${BUILD_TIMESTAMP}' \ + -X 'github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/config.Branch=${REPOSITORY_BRANCH}' # The following works around incompatibility between the rust and the go linkers - @@ -53,9 +53,6 @@ build_rust: Cargo.lock build_go: build-libpreflight go build -ldflags="${GOLDFLAGS}" ${MACOS_MIN_VER} ./... -# regenerate the example lib in `cmd/crates/soroban-spec-typsecript/fixtures/ts` -build-snapshot: typescript-bindings-fixtures - build: build_rust build_go build-libpreflight: Cargo.lock @@ -100,14 +97,6 @@ lint-changes: lint: golangci-lint run ./... -typescript-bindings-fixtures: build-test-wasms - cargo run -- contract bindings typescript \ - --wasm ./target/wasm32-unknown-unknown/test-wasms/test_custom_types.wasm \ - --contract-id CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK \ - --network futurenet \ - --output-dir ./cmd/crates/soroban-spec-typescript/fixtures/test_custom_types \ - --overwrite - # PHONY lists all the targets that aren't file names, so that make would skip the timestamp based check. -.PHONY: publish clean fmt watch check e2e-test test build-test-wasms install build build-soroban-rpc build-libpreflight lint lint-changes build-snapshot typescript-bindings-fixtures +.PHONY: publish clean fmt watch check e2e-test test build-test-wasms install build build-soroban-rpc build-libpreflight lint lint-changes diff --git a/cmd/crates/soroban-spec-json/Cargo.toml b/cmd/crates/soroban-spec-json/Cargo.toml deleted file mode 100644 index 04051ea6..00000000 --- a/cmd/crates/soroban-spec-json/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "soroban-spec-json" -description = "Soroban contract spec utilities for generating JSON." -homepage = "https://github.com/stellar/soroban-tools" -repository = "https://github.com/stellar/soroban-tools" -authors = ["Stellar Development Foundation "] -readme = "README.md" -license = "Apache-2.0" -version.workspace = true -edition = "2021" -rust-version.workspace = true - -[dependencies] -soroban-spec = { workspace = true } -thiserror = "1.0.32" -serde = "1.0.82" -serde_derive = "1.0.82" -serde_json = "1.0.82" -sha2 = "0.9.9" - -[dependencies.stellar-xdr] -workspace = true -features = ["curr", "std", "serde"] - -[dev_dependencies] -pretty_assertions = "1.2.1" diff --git a/cmd/crates/soroban-spec-json/README.md b/cmd/crates/soroban-spec-json/README.md deleted file mode 100644 index cf3c38c4..00000000 --- a/cmd/crates/soroban-spec-json/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# soroban-spec-json - -Generation of JSON that describes a Soroban contract specification / interface. diff --git a/cmd/crates/soroban-spec-json/src/lib.rs b/cmd/crates/soroban-spec-json/src/lib.rs deleted file mode 100644 index cdc64665..00000000 --- a/cmd/crates/soroban-spec-json/src/lib.rs +++ /dev/null @@ -1,229 +0,0 @@ -use std::{fs, io}; - -pub mod types; - -use sha2::{Digest, Sha256}; - -use stellar_xdr::curr::ScSpecEntry; -use types::Entry; - -use soroban_spec::read::{from_wasm, FromWasmError}; - -#[derive(thiserror::Error, Debug)] -pub enum GenerateFromFileError { - #[error("reading file: {0}")] - Io(io::Error), - #[error("sha256 does not match, expected: {expected}")] - VerifySha256 { expected: String }, - #[error("parsing contract spec: {0}")] - Parse(stellar_xdr::curr::Error), - #[error("getting contract spec: {0}")] - GetSpec(FromWasmError), -} - -/// # Errors -/// -/// Will return an error if the file cannot be read, or the wasm cannot be parsed. -pub fn generate_from_file( - file: &str, - verify_sha256: Option<&str>, -) -> Result { - // Read file. - let wasm = fs::read(file).map_err(GenerateFromFileError::Io)?; - - // Produce hash for file. - let sha256 = Sha256::digest(&wasm); - let sha256 = format!("{sha256:x}"); - - if let Some(verify_sha256) = verify_sha256 { - if verify_sha256 != sha256 { - return Err(GenerateFromFileError::VerifySha256 { expected: sha256 }); - } - } - - // Generate code. - let json = generate_from_wasm(&wasm).map_err(GenerateFromFileError::GetSpec)?; - Ok(json) -} - -/// # Errors -/// -/// Will return an error if the wasm cannot be parsed. -pub fn generate_from_wasm(wasm: &[u8]) -> Result { - let spec = from_wasm(wasm)?; - let json = generate(&spec); - Ok(json) -} - -/// # Panics -/// -/// If `serde_json::to_string_pretty` fails to serialize the spec entries. -pub fn generate(spec: &[ScSpecEntry]) -> String { - let collected: Vec<_> = spec.iter().map(Entry::from).collect(); - serde_json::to_string_pretty(&collected).expect("serialization of the spec entries should not have any failure cases as all keys are strings and the serialize implementations are derived") -} - -#[allow(clippy::too_many_lines)] -#[cfg(test)] -mod test { - use pretty_assertions::assert_eq; - use soroban_spec::read::from_wasm; - - use super::generate; - - const EXAMPLE_WASM: &[u8] = - include_bytes!("../../../../target/wasm32-unknown-unknown/test-wasms/test_udt.wasm"); - - #[test] - fn example() { - let entries = from_wasm(EXAMPLE_WASM).unwrap(); - let json = generate(&entries); - assert_eq!( - json, - r#"[ - { - "type": "enum", - "doc": "", - "name": "UdtEnum2", - "cases": [ - { - "doc": "", - "name": "A", - "value": 10 - }, - { - "doc": "", - "name": "B", - "value": 15 - } - ] - }, - { - "type": "union", - "doc": "", - "name": "UdtEnum", - "cases": [ - { - "doc": "", - "name": "UdtA", - "values": [] - }, - { - "doc": "", - "name": "UdtB", - "values": [ - { - "type": "custom", - "name": "UdtStruct" - } - ] - }, - { - "doc": "", - "name": "UdtC", - "values": [ - { - "type": "custom", - "name": "UdtEnum2" - } - ] - }, - { - "doc": "", - "name": "UdtD", - "values": [ - { - "type": "custom", - "name": "UdtTuple" - } - ] - } - ] - }, - { - "type": "struct", - "doc": "", - "name": "UdtTuple", - "fields": [ - { - "doc": "", - "name": "0", - "value": { - "type": "i64" - } - }, - { - "doc": "", - "name": "1", - "value": { - "type": "vec", - "element": { - "type": "i64" - } - } - } - ] - }, - { - "type": "struct", - "doc": "", - "name": "UdtStruct", - "fields": [ - { - "doc": "", - "name": "a", - "value": { - "type": "i64" - } - }, - { - "doc": "", - "name": "b", - "value": { - "type": "i64" - } - }, - { - "doc": "", - "name": "c", - "value": { - "type": "vec", - "element": { - "type": "i64" - } - } - } - ] - }, - { - "type": "function", - "doc": "", - "name": "add", - "inputs": [ - { - "doc": "", - "name": "a", - "value": { - "type": "custom", - "name": "UdtEnum" - } - }, - { - "doc": "", - "name": "b", - "value": { - "type": "custom", - "name": "UdtEnum" - } - } - ], - "outputs": [ - { - "type": "i64" - } - ] - } -]"#, - ); - } -} diff --git a/cmd/crates/soroban-spec-json/src/types.rs b/cmd/crates/soroban-spec-json/src/types.rs deleted file mode 100644 index 8e3b2177..00000000 --- a/cmd/crates/soroban-spec-json/src/types.rs +++ /dev/null @@ -1,245 +0,0 @@ -use serde::Serialize; -use stellar_xdr::curr::{ - ScSpecEntry, ScSpecFunctionInputV0, ScSpecTypeDef, ScSpecUdtEnumCaseV0, - ScSpecUdtErrorEnumCaseV0, ScSpecUdtStructFieldV0, ScSpecUdtUnionCaseV0, -}; - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct StructField { - pub doc: String, - pub name: String, - pub value: Type, -} - -impl From<&ScSpecUdtStructFieldV0> for StructField { - fn from(f: &ScSpecUdtStructFieldV0) -> Self { - StructField { - doc: f.doc.to_utf8_string_lossy(), - name: f.name.to_utf8_string_lossy(), - value: (&f.type_).into(), - } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct FunctionInput { - pub doc: String, - pub name: String, - pub value: Type, -} - -impl From<&ScSpecFunctionInputV0> for FunctionInput { - fn from(f: &ScSpecFunctionInputV0) -> Self { - FunctionInput { - doc: f.doc.to_utf8_string_lossy(), - name: f.name.to_utf8_string_lossy(), - value: (&f.type_).into(), - } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct UnionCase { - pub doc: String, - pub name: String, - pub values: Vec, -} - -impl From<&ScSpecUdtUnionCaseV0> for UnionCase { - fn from(c: &ScSpecUdtUnionCaseV0) -> Self { - let (doc, name, values) = match c { - ScSpecUdtUnionCaseV0::VoidV0(v) => ( - v.doc.to_utf8_string_lossy(), - v.name.to_utf8_string_lossy(), - vec![], - ), - ScSpecUdtUnionCaseV0::TupleV0(t) => ( - t.doc.to_utf8_string_lossy(), - t.name.to_utf8_string_lossy(), - t.type_.iter().map(Type::from).collect(), - ), - }; - UnionCase { doc, name, values } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct EnumCase { - pub doc: String, - pub name: String, - pub value: u32, -} - -impl From<&ScSpecUdtEnumCaseV0> for EnumCase { - fn from(c: &ScSpecUdtEnumCaseV0) -> Self { - EnumCase { - doc: c.doc.to_utf8_string_lossy(), - name: c.name.to_utf8_string_lossy(), - value: c.value, - } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct ErrorEnumCase { - pub doc: String, - pub name: String, - pub value: u32, -} - -impl From<&ScSpecUdtErrorEnumCaseV0> for EnumCase { - fn from(c: &ScSpecUdtErrorEnumCaseV0) -> Self { - EnumCase { - doc: c.doc.to_utf8_string_lossy(), - name: c.name.to_utf8_string_lossy(), - value: c.value, - } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(tag = "type")] -#[serde(rename_all = "camelCase")] -pub enum Type { - Void, - Val, - U64, - I64, - U32, - I32, - U128, - I128, - U256, - I256, - Bool, - Symbol, - Error, - Bytes, - String, - Address, - Timepoint, - Duration, - Map { key: Box, value: Box }, - Option { value: Box }, - Result { value: Box, error: Box }, - Vec { element: Box }, - BytesN { n: u32 }, - Tuple { elements: Vec }, - Custom { name: String }, -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(tag = "type")] -#[serde(rename_all = "camelCase")] -pub enum Entry { - Function { - doc: String, - name: String, - inputs: Vec, - outputs: Vec, - }, - Struct { - doc: String, - name: String, - fields: Vec, - }, - Union { - doc: String, - name: String, - cases: Vec, - }, - Enum { - doc: String, - name: String, - cases: Vec, - }, - ErrorEnum { - doc: String, - name: String, - cases: Vec, - }, -} - -impl From<&ScSpecTypeDef> for Type { - fn from(spec: &ScSpecTypeDef) -> Self { - match spec { - ScSpecTypeDef::Map(map) => Type::Map { - key: Box::new(Type::from(map.key_type.as_ref())), - value: Box::new(Type::from(map.value_type.as_ref())), - }, - ScSpecTypeDef::Option(opt) => Type::Option { - value: Box::new(Type::from(opt.value_type.as_ref())), - }, - ScSpecTypeDef::Result(res) => Type::Result { - value: Box::new(Type::from(res.ok_type.as_ref())), - error: Box::new(Type::from(res.error_type.as_ref())), - }, - ScSpecTypeDef::Tuple(tuple) => Type::Tuple { - elements: tuple.value_types.iter().map(Type::from).collect(), - }, - ScSpecTypeDef::Vec(vec) => Type::Vec { - element: Box::new(Type::from(vec.element_type.as_ref())), - }, - ScSpecTypeDef::Udt(udt) => Type::Custom { - name: udt.name.to_utf8_string_lossy(), - }, - ScSpecTypeDef::BytesN(b) => Type::BytesN { n: b.n }, - ScSpecTypeDef::Val => Type::Val, - ScSpecTypeDef::U64 => Type::U64, - ScSpecTypeDef::I64 => Type::I64, - ScSpecTypeDef::U32 => Type::U32, - ScSpecTypeDef::I32 => Type::I32, - ScSpecTypeDef::U128 => Type::U128, - ScSpecTypeDef::I128 => Type::I128, - ScSpecTypeDef::U256 => Type::U256, - ScSpecTypeDef::I256 => Type::I256, - ScSpecTypeDef::Bool => Type::Bool, - ScSpecTypeDef::Symbol => Type::Symbol, - ScSpecTypeDef::Error => Type::Error, - ScSpecTypeDef::Bytes => Type::Bytes, - ScSpecTypeDef::String => Type::String, - ScSpecTypeDef::Address => Type::Address, - ScSpecTypeDef::Void => Type::Void, - ScSpecTypeDef::Timepoint => Type::Timepoint, - ScSpecTypeDef::Duration => Type::Duration, - } - } -} - -impl From<&ScSpecEntry> for Entry { - fn from(spec: &ScSpecEntry) -> Self { - match spec { - ScSpecEntry::FunctionV0(f) => Entry::Function { - doc: f.doc.to_utf8_string_lossy(), - name: f.name.to_utf8_string_lossy(), - inputs: f.inputs.iter().map(FunctionInput::from).collect(), - outputs: f.outputs.iter().map(Type::from).collect(), - }, - ScSpecEntry::UdtStructV0(s) => Entry::Struct { - doc: s.doc.to_utf8_string_lossy(), - name: s.name.to_utf8_string_lossy(), - fields: s.fields.iter().map(StructField::from).collect(), - }, - ScSpecEntry::UdtUnionV0(u) => Entry::Union { - doc: u.doc.to_utf8_string_lossy(), - name: u.name.to_utf8_string_lossy(), - cases: u.cases.iter().map(UnionCase::from).collect(), - }, - ScSpecEntry::UdtEnumV0(e) => Entry::Enum { - doc: e.doc.to_utf8_string_lossy(), - name: e.name.to_utf8_string_lossy(), - cases: e.cases.iter().map(EnumCase::from).collect(), - }, - ScSpecEntry::UdtErrorEnumV0(e) => Entry::Enum { - doc: e.doc.to_utf8_string_lossy(), - name: e.name.to_utf8_string_lossy(), - cases: e.cases.iter().map(EnumCase::from).collect(), - }, - } - } -} diff --git a/cmd/crates/soroban-spec-tools/Cargo.toml b/cmd/crates/soroban-spec-tools/Cargo.toml deleted file mode 100644 index 61a32c13..00000000 --- a/cmd/crates/soroban-spec-tools/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "soroban-spec-tools" -description = "Tools for using a contract's XDR spec" -homepage = "https://github.com/stellar/soroban-tools" -repository = "https://github.com/stellar/soroban-tools" -authors = ["Stellar Development Foundation "] -license = "Apache-2.0" -readme = "README.md" -version.workspace = true -edition = "2021" -rust-version.workspace = true -autobins = false - - -[lib] -crate-type = ["rlib"] - - -[dependencies] -soroban-spec = { workspace = true } -stellar-strkey = { workspace = true } -stellar-xdr = { workspace = true, features = ["curr", "std", "serde"] } -serde_json = { workspace = true } -itertools = { workspace = true } -ethnum = { workspace = true } -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] -which = { workspace = true } -tokio = "1.28.1" diff --git a/cmd/crates/soroban-spec-tools/README.md b/cmd/crates/soroban-spec-tools/README.md deleted file mode 100644 index d2b00654..00000000 --- a/cmd/crates/soroban-spec-tools/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# soroban-spec-tools - -Tools and utilities for soroban specification / interface. diff --git a/cmd/crates/soroban-spec-tools/src/lib.rs b/cmd/crates/soroban-spec-tools/src/lib.rs deleted file mode 100644 index 7f310fd9..00000000 --- a/cmd/crates/soroban-spec-tools/src/lib.rs +++ /dev/null @@ -1,1468 +0,0 @@ -#![allow(clippy::missing_errors_doc, clippy::must_use_candidate)] -use std::str::FromStr; - -use itertools::Itertools; -use serde_json::{json, Value}; -use stellar_xdr::curr::{ - AccountId, BytesM, ContractExecutable, Error as XdrError, Hash, Int128Parts, Int256Parts, - PublicKey, ScAddress, ScBytes, ScContractInstance, ScMap, ScMapEntry, ScNonceKey, ScSpecEntry, - ScSpecFunctionV0, ScSpecTypeDef as ScType, ScSpecTypeMap, ScSpecTypeOption, ScSpecTypeResult, - ScSpecTypeTuple, ScSpecTypeUdt, ScSpecTypeVec, ScSpecUdtEnumV0, ScSpecUdtErrorEnumCaseV0, - ScSpecUdtErrorEnumV0, ScSpecUdtStructV0, ScSpecUdtUnionCaseTupleV0, ScSpecUdtUnionCaseV0, - ScSpecUdtUnionCaseVoidV0, ScSpecUdtUnionV0, ScString, ScSymbol, ScVal, ScVec, StringM, - UInt128Parts, UInt256Parts, Uint256, VecM, -}; - -pub mod utils; - -#[derive(thiserror::Error, Debug)] -pub enum Error { - #[error("an unknown error occurred")] - Unknown, - #[error("Invalid pair {0:#?} {1:#?}")] - InvalidPair(ScVal, ScType), - #[error("value is not parseable to {0:#?}")] - InvalidValue(Option), - #[error("Unknown case {0} for {1}")] - EnumCase(String, String), - #[error("Enum {0} missing value for type {1}")] - EnumMissingSecondValue(String, String), - #[error("Enum {0} is illformed")] - IllFormedEnum(String), - #[error("Unknown const case {0}")] - EnumConst(u32), - #[error("Enum const value must be a u32 or smaller")] - EnumConstTooLarge(u64), - #[error("Missing Entry {0}")] - MissingEntry(String), - #[error("Missing Spec")] - MissingSpec, - #[error(transparent)] - Xdr(XdrError), - #[error(transparent)] - Serde(#[from] serde_json::Error), - #[error(transparent)] - Ethnum(#[from] core::num::ParseIntError), - - #[error("Missing key {0} in map")] - MissingKey(String), - #[error("Failed to convert {0} to number")] - FailedNumConversion(serde_json::Number), - #[error("First argument in an enum must be a sybmol")] - EnumFirstValueNotSymbol, - #[error("Failed to find enum case {0}")] - FailedToFindEnumCase(String), - #[error(transparent)] - FailedSilceToByte(#[from] std::array::TryFromSliceError), - #[error(transparent)] - Infallible(#[from] std::convert::Infallible), - #[error("Missing Error case {0}")] - MissingErrorCase(u32), - #[error(transparent)] - Spec(#[from] soroban_spec::read::FromWasmError), - #[error(transparent)] - Base64Spec(#[from] soroban_spec::read::ParseSpecBase64Error), -} - -#[derive(Default, Clone)] -pub struct Spec(pub Option>); - -impl TryInto for &[u8] { - type Error = soroban_spec::read::FromWasmError; - - fn try_into(self) -> Result { - let spec = soroban_spec::read::from_wasm(self)?; - Ok(Spec::new(spec)) - } -} - -impl Spec { - pub fn new(entries: Vec) -> Self { - Self(Some(entries)) - } - - pub fn from_wasm(wasm: &[u8]) -> Result { - let spec = soroban_spec::read::from_wasm(wasm)?; - Ok(Spec::new(spec)) - } - - pub fn parse_base64(base64: &str) -> Result { - let spec = soroban_spec::read::parse_base64(base64.as_bytes())?; - Ok(Spec::new(spec)) - } -} - -impl Spec { - /// # Errors - /// Could fail to find User Defined Type - pub fn doc(&self, name: &str, type_: &ScType) -> Result, Error> { - let mut str = match type_ { - ScType::Val - | ScType::U64 - | ScType::I64 - | ScType::U128 - | ScType::I128 - | ScType::U32 - | ScType::I32 - | ScType::Result(_) - | ScType::Vec(_) - | ScType::Map(_) - | ScType::Tuple(_) - | ScType::BytesN(_) - | ScType::Symbol - | ScType::Error - | ScType::Bytes - | ScType::Void - | ScType::Timepoint - | ScType::Duration - | ScType::U256 - | ScType::I256 - | ScType::String - | ScType::Bool => String::new(), - ScType::Address => String::from( - "Can be public key (G13..), a contract hash (6c45307) or an identity (alice), ", - ), - ScType::Option(type_) => return self.doc(name, &type_.value_type), - ScType::Udt(ScSpecTypeUdt { name }) => { - let spec_type = self.find(&name.to_utf8_string_lossy())?; - match spec_type { - ScSpecEntry::FunctionV0(ScSpecFunctionV0 { doc, .. }) - | ScSpecEntry::UdtStructV0(ScSpecUdtStructV0 { doc, .. }) - | ScSpecEntry::UdtUnionV0(ScSpecUdtUnionV0 { doc, .. }) - | ScSpecEntry::UdtEnumV0(ScSpecUdtEnumV0 { doc, .. }) - | ScSpecEntry::UdtErrorEnumV0(ScSpecUdtErrorEnumV0 { doc, .. }) => doc, - } - .to_utf8_string_lossy() - } - }; - if let Some(mut ex) = self.example(type_) { - if ex.contains(' ') { - ex = format!("'{ex}'"); - } else if ex.contains('"') { - ex = ex.replace('"', ""); - } - if matches!(type_, ScType::Bool) { - ex = String::new(); - } - let sep = if str.is_empty() { "" } else { "\n" }; - str = format!("{str}{sep}Example:\n --{name} {ex}"); - if ex.contains('"') {} - } - if str.is_empty() { - Ok(None) - } else { - Ok(Some(Box::leak(str.into_boxed_str()))) - } - } - - /// # Errors - /// - /// Might return errors - pub fn find(&self, name: &str) -> Result<&ScSpecEntry, Error> { - self.0 - .as_ref() - .and_then(|specs| { - specs.iter().find(|e| { - let entry_name = match e { - ScSpecEntry::FunctionV0(x) => x.name.to_utf8_string_lossy(), - ScSpecEntry::UdtStructV0(x) => x.name.to_utf8_string_lossy(), - ScSpecEntry::UdtUnionV0(x) => x.name.to_utf8_string_lossy(), - ScSpecEntry::UdtEnumV0(x) => x.name.to_utf8_string_lossy(), - ScSpecEntry::UdtErrorEnumV0(x) => x.name.to_utf8_string_lossy(), - }; - name == entry_name - }) - }) - .ok_or_else(|| Error::MissingEntry(name.to_owned())) - } - - /// # Errors - /// - /// Might return errors - pub fn find_function(&self, name: &str) -> Result<&ScSpecFunctionV0, Error> { - match self.find(name)? { - ScSpecEntry::FunctionV0(f) => Ok(f), - _ => Err(Error::MissingEntry(name.to_owned())), - } - } - // - /// # Errors - /// - pub fn find_functions(&self) -> Result, Error> { - Ok(self - .0 - .as_ref() - .ok_or(Error::MissingSpec)? - .iter() - .filter_map(|e| match e { - ScSpecEntry::FunctionV0(x) => Some(x), - _ => None, - })) - } - - /// # Errors - /// - pub fn find_error_type(&self, value: u32) -> Result<&ScSpecUdtErrorEnumCaseV0, Error> { - if let ScSpecEntry::UdtErrorEnumV0(ScSpecUdtErrorEnumV0 { cases, .. }) = - self.find("Error")? - { - if let Some(case) = cases.iter().find(|case| value == case.value) { - return Ok(case); - } - } - Err(Error::MissingErrorCase(value)) - } - - /// # Errors - /// - /// Might return errors - pub fn from_string_primitive(s: &str, t: &ScType) -> Result { - Self::default().from_string(s, t) - } - - /// # Errors - /// - /// Might return errors - #[allow(clippy::wrong_self_convention)] - pub fn from_string(&self, s: &str, t: &ScType) -> Result { - if let ScType::Option(b) = t { - if s == "null" { - return Ok(ScVal::Void); - } - let ScSpecTypeOption { value_type } = b.as_ref().clone(); - let v = value_type.as_ref().clone(); - return self.from_string(s, &v); - } - // Parse as string and for special types assume Value::String - serde_json::from_str(s) - .map_or_else( - |e| match t { - ScType::Symbol - | ScType::String - | ScType::Bytes - | ScType::BytesN(_) - | ScType::U256 - | ScType::I256 - | ScType::U128 - | ScType::I128 - | ScType::Address => Ok(Value::String(s.to_owned())), - ScType::Udt(ScSpecTypeUdt { name }) - if matches!( - self.find(&name.to_utf8_string_lossy())?, - ScSpecEntry::UdtUnionV0(_) | ScSpecEntry::UdtStructV0(_) - ) => - { - Ok(Value::String(s.to_owned())) - } - _ => Err(Error::Serde(e)), - }, - |val| match t { - ScType::U128 | ScType::I128 | ScType::U256 | ScType::I256 => { - Ok(Value::String(s.to_owned())) - } - _ => Ok(val), - }, - ) - .and_then(|raw| self.from_json(&raw, t)) - } - - /// # Errors - /// - /// Might return errors - #[allow(clippy::wrong_self_convention)] - pub fn from_json(&self, v: &Value, t: &ScType) -> Result { - let val: ScVal = match (t, v) { - ( - ScType::Bool - | ScType::U128 - | ScType::I128 - | ScType::U256 - | ScType::I256 - | ScType::I32 - | ScType::I64 - | ScType::U32 - | ScType::U64 - | ScType::String - | ScType::Symbol - | ScType::Address - | ScType::Bytes - | ScType::BytesN(_), - _, - ) => from_json_primitives(v, t)?, - - // Vec parsing - (ScType::Vec(elem), Value::Array(raw)) => { - let converted: ScVec = raw - .iter() - .map(|item| self.from_json(item, &elem.element_type)) - .collect::, Error>>()? - .try_into() - .map_err(Error::Xdr)?; - ScVal::Vec(Some(converted)) - } - - // Map parsing - (ScType::Map(map), Value::Object(raw)) => self.parse_map(map, raw)?, - - // Option parsing - (ScType::Option(_), Value::Null) => ScVal::Void, - (ScType::Option(elem), v) => self.from_json(v, &elem.value_type)?, - - // Tuple parsing - (ScType::Tuple(elem), Value::Array(raw)) => self.parse_tuple(t, elem, raw)?, - - // User defined types parsing - (ScType::Udt(ScSpecTypeUdt { name }), _) => self.parse_udt(name, v)?, - - // TODO: Implement the rest of these - (_, raw) => serde_json::from_value(raw.clone()).map_err(Error::Serde)?, - }; - Ok(val) - } - - fn parse_udt(&self, name: &StringM<60>, value: &Value) -> Result { - let name = &name.to_utf8_string_lossy(); - match (self.find(name)?, value) { - (ScSpecEntry::UdtStructV0(strukt), Value::Object(map)) => { - if strukt - .fields - .iter() - .any(|f| f.name.to_utf8_string_lossy() == "0") - { - self.parse_tuple_strukt( - strukt, - &(0..map.len()) - .map(|i| map.get(&i.to_string()).unwrap().clone()) - .collect::>(), - ) - } else { - self.parse_strukt(strukt, map) - } - } - (ScSpecEntry::UdtStructV0(strukt), Value::Array(arr)) => { - self.parse_tuple_strukt(strukt, arr) - } - ( - ScSpecEntry::UdtUnionV0(union), - val @ (Value::Array(_) | Value::String(_) | Value::Object(_)), - ) => self.parse_union(union, val), - (ScSpecEntry::UdtEnumV0(enum_), Value::Number(num)) => parse_const_enum(num, enum_), - (s, v) => todo!("Not implemented for {s:#?} {v:#?}"), - } - } - - fn parse_tuple_strukt( - &self, - strukt: &ScSpecUdtStructV0, - array: &[Value], - ) -> Result { - let items = strukt - .fields - .to_vec() - .iter() - .zip(array.iter()) - .map(|(f, v)| { - let val = self.from_json(v, &f.type_)?; - Ok(val) - }) - .collect::, Error>>()?; - Ok(ScVal::Vec(Some(items.try_into().map_err(Error::Xdr)?))) - } - - fn parse_strukt( - &self, - strukt: &ScSpecUdtStructV0, - map: &serde_json::Map, - ) -> Result { - let items = strukt - .fields - .to_vec() - .iter() - .map(|f| { - let name = &f.name.to_utf8_string_lossy(); - let v = map - .get(name) - .ok_or_else(|| Error::MissingKey(name.clone()))?; - let val = self.from_json(v, &f.type_)?; - let key = StringM::from_str(name).unwrap(); - Ok(ScMapEntry { - key: ScVal::Symbol(key.into()), - val, - }) - }) - .collect::, Error>>()?; - let map = ScMap::sorted_from(items).map_err(Error::Xdr)?; - Ok(ScVal::Map(Some(map))) - } - - fn parse_union(&self, union: &ScSpecUdtUnionV0, value: &Value) -> Result { - let (enum_case, rest) = match value { - Value::String(s) => (s, None), - Value::Object(o) if o.len() == 1 => { - let res = o.values().next().map(|v| match v { - Value::Object(obj) if obj.contains_key("0") => { - let len = obj.len(); - Value::Array( - (0..len) - .map(|i| obj.get(&i.to_string()).unwrap().clone()) - .collect::>(), - ) - } - _ => v.clone(), - }); - (o.keys().next().unwrap(), res) - } - _ => todo!(), - }; - let case = union - .cases - .iter() - .find(|c| { - let name = match c { - ScSpecUdtUnionCaseV0::VoidV0(v) => &v.name, - ScSpecUdtUnionCaseV0::TupleV0(v) => &v.name, - }; - enum_case == &name.to_utf8_string_lossy() - }) - .ok_or_else(|| { - Error::EnumCase(enum_case.to_string(), union.name.to_utf8_string_lossy()) - })?; - - let mut res = vec![ScVal::Symbol(ScSymbol( - enum_case.try_into().map_err(Error::Xdr)?, - ))]; - - match (case, rest) { - (ScSpecUdtUnionCaseV0::VoidV0(_), _) | (ScSpecUdtUnionCaseV0::TupleV0(_), None) => (), - (ScSpecUdtUnionCaseV0::TupleV0(ScSpecUdtUnionCaseTupleV0 { type_, .. }), Some(arr)) - if type_.len() == 1 => - { - res.push(self.from_json(&arr, &type_[0])?); - } - ( - ScSpecUdtUnionCaseV0::TupleV0(ScSpecUdtUnionCaseTupleV0 { type_, .. }), - Some(Value::Array(arr)), - ) => { - res.extend( - arr.iter() - .zip(type_.iter()) - .map(|(elem, ty)| self.from_json(elem, ty)) - .collect::, _>>()?, - ); - } - (ScSpecUdtUnionCaseV0::TupleV0(ScSpecUdtUnionCaseTupleV0 { .. }), Some(_)) => {} - }; - Ok(ScVal::Vec(Some(res.try_into().map_err(Error::Xdr)?))) - } - - fn parse_tuple( - &self, - t: &ScType, - tuple: &ScSpecTypeTuple, - items: &[Value], - ) -> Result { - let ScSpecTypeTuple { value_types } = tuple; - if items.len() != value_types.len() { - return Err(Error::InvalidValue(Some(t.clone()))); - }; - let parsed: Result, Error> = items - .iter() - .zip(value_types.iter()) - .map(|(item, t)| self.from_json(item, t)) - .collect(); - let converted: ScVec = parsed?.try_into().map_err(Error::Xdr)?; - Ok(ScVal::Vec(Some(converted))) - } - - fn parse_map( - &self, - map: &ScSpecTypeMap, - value_map: &serde_json::Map, - ) -> Result { - let ScSpecTypeMap { - key_type, - value_type, - } = map; - // TODO: What do we do if the expected key_type is not a string or symbol? - let parsed: Result, Error> = value_map - .iter() - .map(|(k, v)| -> Result { - let key = self.from_string(k, key_type)?; - let val = self.from_json(v, value_type)?; - Ok(ScMapEntry { key, val }) - }) - .collect(); - Ok(ScVal::Map(Some( - ScMap::sorted_from(parsed?).map_err(Error::Xdr)?, - ))) - } -} - -impl Spec { - /// # Errors - /// - /// Might return `Error::InvalidValue` - /// - /// # Panics - /// - /// May panic - pub fn xdr_to_json(&self, val: &ScVal, output: &ScType) -> Result { - Ok(match (val, output) { - (ScVal::Void, ScType::Val | ScType::Option(_) | ScType::Tuple(_)) - | (ScVal::Map(None) | ScVal::Vec(None), ScType::Option(_)) => Value::Null, - (ScVal::Bool(_), ScType::Bool) - | (ScVal::Void, ScType::Void) - | (ScVal::String(_), ScType::String) - | (ScVal::Symbol(_), ScType::Symbol) - | (ScVal::U64(_), ScType::U64) - | (ScVal::I64(_), ScType::I64) - | (ScVal::U32(_), ScType::U32) - | (ScVal::I32(_), ScType::I32) - | (ScVal::U128(_), ScType::U128) - | (ScVal::I128(_), ScType::I128) - | (ScVal::U256(_), ScType::U256) - | (ScVal::I256(_), ScType::I256) - | (ScVal::Duration(_), ScType::Duration) - | (ScVal::Timepoint(_), ScType::Timepoint) - | ( - ScVal::ContractInstance(_) - | ScVal::LedgerKeyContractInstance - | ScVal::LedgerKeyNonce(_), - _, - ) - | (ScVal::Address(_), ScType::Address) - | (ScVal::Bytes(_), ScType::Bytes | ScType::BytesN(_)) => to_json(val)?, - - (val, ScType::Result(inner)) => self.xdr_to_json(val, &inner.ok_type)?, - - (val, ScType::Option(inner)) => self.xdr_to_json(val, &inner.value_type)?, - (ScVal::Map(Some(_)) | ScVal::Vec(Some(_)) | ScVal::U32(_), type_) => { - self.sc_object_to_json(val, type_)? - } - - (ScVal::Error(_), ScType::Error) => todo!(), - (v, typed) => todo!("{v:#?} doesn't have a matching {typed:#?}"), - }) - } - - /// # Errors - /// - /// Might return an error - pub fn vec_m_to_json( - &self, - vec_m: &VecM, - type_: &ScType, - ) -> Result { - Ok(Value::Array( - vec_m - .to_vec() - .iter() - .map(|sc_val| self.xdr_to_json(sc_val, type_)) - .collect::, Error>>()?, - )) - } - - /// # Errors - /// - /// Might return an error - pub fn sc_map_to_json(&self, sc_map: &ScMap, type_: &ScSpecTypeMap) -> Result { - let v = sc_map - .iter() - .map(|ScMapEntry { key, val }| { - let key_s = self.xdr_to_json(key, &type_.key_type)?.to_string(); - let val_value = self.xdr_to_json(val, &type_.value_type)?; - Ok((key_s, val_value)) - }) - .collect::, Error>>()?; - Ok(Value::Object(v)) - } - - /// # Errors - /// - /// Might return an error - /// - /// # Panics - /// - /// May panic - pub fn udt_to_json(&self, name: &StringM<60>, sc_obj: &ScVal) -> Result { - let name = &name.to_utf8_string_lossy(); - let udt = self.find(name)?; - Ok(match (sc_obj, udt) { - (ScVal::Map(Some(map)), ScSpecEntry::UdtStructV0(strukt)) => serde_json::Value::Object( - strukt - .fields - .iter() - .zip(map.iter()) - .map(|(field, entry)| { - let val = self.xdr_to_json(&entry.val, &field.type_)?; - Ok((field.name.to_utf8_string_lossy(), val)) - }) - .collect::, Error>>()?, - ), - (ScVal::Vec(Some(vec_)), ScSpecEntry::UdtStructV0(strukt)) => Value::Array( - strukt - .fields - .iter() - .zip(vec_.iter()) - .map(|(field, entry)| self.xdr_to_json(entry, &field.type_)) - .collect::, Error>>()?, - ), - (ScVal::Vec(Some(vec_)), ScSpecEntry::UdtUnionV0(union)) => { - let v = vec_.to_vec(); - // let val = &v[0]; - let (first, rest) = match v.split_at(1) { - ([first], []) => (first, None), - ([first], rest) => (first, Some(rest)), - _ => return Err(Error::IllFormedEnum(union.name.to_utf8_string_lossy())), - }; - - let ScVal::Symbol(case_name) = first else { - return Err(Error::EnumFirstValueNotSymbol); - }; - let case = union - .cases - .iter() - .find(|case| { - let name = match case { - ScSpecUdtUnionCaseV0::VoidV0(v) => &v.name, - ScSpecUdtUnionCaseV0::TupleV0(v) => &v.name, - }; - name.as_vec() == case_name.as_vec() - }) - .ok_or_else(|| Error::FailedToFindEnumCase(case_name.to_utf8_string_lossy()))?; - - let case_name = case_name.to_utf8_string_lossy(); - match case { - ScSpecUdtUnionCaseV0::TupleV0(v) => { - let rest = rest.ok_or_else(|| { - Error::EnumMissingSecondValue( - union.name.to_utf8_string_lossy(), - case_name.clone(), - ) - })?; - let val = if v.type_.len() == 1 { - self.xdr_to_json(&rest[0], &v.type_[0])? - } else { - Value::Array( - v.type_ - .iter() - .zip(rest.iter()) - .map(|(type_, val)| self.xdr_to_json(val, type_)) - .collect::, Error>>()?, - ) - }; - - Value::Object([(case_name, val)].into_iter().collect()) - } - ScSpecUdtUnionCaseV0::VoidV0(_) => Value::String(case_name), - } - } - (ScVal::U32(v), ScSpecEntry::UdtEnumV0(_enum_)) => { - Value::Number(serde_json::Number::from(*v)) - } - (s, v) => todo!("Not implemented for {s:#?} {v:#?}"), - }) - } - - /// # Errors - /// - /// Might return an error - /// - /// # Panics - /// - /// Some types are not yet supported and will cause a panic if supplied - pub fn sc_object_to_json(&self, val: &ScVal, spec_type: &ScType) -> Result { - Ok(match (val, spec_type) { - (ScVal::Vec(Some(ScVec(vec_m))), ScType::Vec(type_)) => { - self.vec_m_to_json(vec_m, &type_.element_type)? - } - (ScVal::Vec(Some(ScVec(vec_m))), ScType::Tuple(tuple_type)) => Value::Array( - vec_m - .iter() - .zip(tuple_type.value_types.iter()) - .map(|(v, t)| self.xdr_to_json(v, t)) - .collect::, _>>()?, - ), - ( - sc_obj @ (ScVal::Vec(_) | ScVal::Map(_) | ScVal::U32(_)), - ScType::Udt(ScSpecTypeUdt { name }), - ) => self.udt_to_json(name, sc_obj)?, - - (ScVal::Map(Some(map)), ScType::Map(map_type)) => self.sc_map_to_json(map, map_type)?, - - (ScVal::U64(u64_), ScType::U64) => Value::Number(serde_json::Number::from(*u64_)), - - (ScVal::I64(i64_), ScType::I64) => Value::Number(serde_json::Number::from(*i64_)), - (int @ ScVal::U128(_), ScType::U128) => { - // Always output u128s as strings - let v: u128 = int - .clone() - .try_into() - .map_err(|()| Error::InvalidValue(Some(ScType::U128)))?; - Value::String(v.to_string()) - } - - (int @ ScVal::I128(_), ScType::I128) => { - // Always output u128s as strings - let v: i128 = int - .clone() - .try_into() - .map_err(|()| Error::InvalidValue(Some(ScType::I128)))?; - Value::String(v.to_string()) - } - - (ScVal::Bytes(v), ScType::Bytes | ScType::BytesN(_)) => { - Value::String(to_lower_hex(v.as_slice())) - } - - (ScVal::Bytes(_), ScType::Udt(_)) => todo!(), - - (ScVal::ContractInstance(_), _) => todo!(), - - (ScVal::Address(v), ScType::Address) => sc_address_to_json(v), - - (ok_val, ScType::Result(result_type)) => { - let ScSpecTypeResult { ok_type, .. } = result_type.as_ref(); - self.xdr_to_json(ok_val, ok_type)? - } - - (x, y) => return Err(Error::InvalidPair(x.clone(), y.clone())), - }) - } -} - -/// # Errors -/// -/// Might return an error -pub fn from_string_primitive(s: &str, t: &ScType) -> Result { - Spec::from_string_primitive(s, t) -} - -fn parse_const_enum(num: &serde_json::Number, enum_: &ScSpecUdtEnumV0) -> Result { - let num = num - .as_u64() - .ok_or_else(|| Error::FailedNumConversion(num.clone()))?; - let num = u32::try_from(num).map_err(|_| Error::EnumConstTooLarge(num))?; - enum_ - .cases - .iter() - .find(|c| c.value == num) - .ok_or(Error::EnumConst(num)) - .map(|c| ScVal::U32(c.value)) -} - -/// # Errors -/// -/// Might return an error -#[allow(clippy::too_many_lines)] -pub fn from_json_primitives(v: &Value, t: &ScType) -> Result { - let val: ScVal = match (t, v) { - // Boolean parsing - (ScType::Bool, Value::Bool(true)) => ScVal::Bool(true), - (ScType::Bool, Value::Bool(false)) => ScVal::Bool(false), - - // Number parsing - (ScType::U128, Value::String(s)) => { - let val: u128 = u128::from_str(s) - .map(Into::into) - .map_err(|_| Error::InvalidValue(Some(t.clone())))?; - let bytes = val.to_be_bytes(); - let (hi, lo) = bytes.split_at(8); - ScVal::U128(UInt128Parts { - hi: u64::from_be_bytes(hi.try_into()?), - lo: u64::from_be_bytes(lo.try_into()?), - }) - } - - (ScType::I128, Value::String(s)) => { - let val: i128 = i128::from_str(s) - .map(Into::into) - .map_err(|_| Error::InvalidValue(Some(t.clone())))?; - let bytes = val.to_be_bytes(); - let (hi, lo) = bytes.split_at(8); - ScVal::I128(Int128Parts { - hi: i64::from_be_bytes(hi.try_into()?), - lo: u64::from_be_bytes(lo.try_into()?), - }) - } - - // Number parsing - (ScType::U256, Value::String(s)) => { - let (hi, lo) = ethnum::U256::from_str_prefixed(s)?.into_words(); - let hi_bytes = hi.to_be_bytes(); - let (hi_hi, hi_lo) = hi_bytes.split_at(8); - let lo_bytes = lo.to_be_bytes(); - let (lo_hi, lo_lo) = lo_bytes.split_at(8); - ScVal::U256(UInt256Parts { - hi_hi: u64::from_be_bytes(hi_hi.try_into()?), - hi_lo: u64::from_be_bytes(hi_lo.try_into()?), - lo_hi: u64::from_be_bytes(lo_hi.try_into()?), - lo_lo: u64::from_be_bytes(lo_lo.try_into()?), - }) - } - (ScType::I256, Value::String(s)) => { - let (hi, lo) = ethnum::I256::from_str_prefixed(s)?.into_words(); - let hi_bytes = hi.to_be_bytes(); - let (hi_hi, hi_lo) = hi_bytes.split_at(8); - let lo_bytes = lo.to_be_bytes(); - let (lo_hi, lo_lo) = lo_bytes.split_at(8); - ScVal::I256(Int256Parts { - hi_hi: i64::from_be_bytes(hi_hi.try_into()?), - hi_lo: u64::from_be_bytes(hi_lo.try_into()?), - lo_hi: u64::from_be_bytes(lo_hi.try_into()?), - lo_lo: u64::from_be_bytes(lo_lo.try_into()?), - }) - } - - (ScType::I32, Value::Number(n)) => ScVal::I32( - n.as_i64() - .ok_or_else(|| Error::InvalidValue(Some(t.clone())))? - .try_into() - .map_err(|_| Error::InvalidValue(Some(t.clone())))?, - ), - (ScType::U32, Value::Number(n)) => ScVal::U32( - n.as_u64() - .ok_or_else(|| Error::InvalidValue(Some(t.clone())))? - .try_into() - .map_err(|_| Error::InvalidValue(Some(t.clone())))?, - ), - (ScType::I64, Value::Number(n)) => ScVal::I64( - n.as_i64() - .ok_or_else(|| Error::InvalidValue(Some(t.clone())))?, - ), - (ScType::U64 | ScType::Timepoint | ScType::Duration, Value::Number(n)) => ScVal::U64( - n.as_u64() - .ok_or_else(|| Error::InvalidValue(Some(t.clone())))?, - ), - - // Symbol parsing - (ScType::Symbol, Value::String(s)) => ScVal::Symbol(ScSymbol( - s.as_bytes() - .try_into() - .map_err(|_| Error::InvalidValue(Some(t.clone())))?, - )), - - (ScType::Address, Value::String(s)) => sc_address_from_json(s)?, - - // Bytes parsing - (bytes @ ScType::BytesN(_), Value::Number(n)) => { - from_json_primitives(&Value::String(format!("{n}")), bytes)? - } - (ScType::BytesN(bytes), Value::String(s)) => ScVal::Bytes(ScBytes({ - if bytes.n == 32 { - // Bytes might be a strkey, try parsing it as one. Contract devs should use the new - // proper Address type, but for backwards compatibility some contracts might use a - // BytesN<32> to represent an Address. - if let Ok(key) = sc_address_from_json(s) { - return Ok(key); - } - } - // Bytes are not an address, just parse as a hex string - utils::padded_hex_from_str(s, bytes.n as usize) - .map_err(|_| Error::InvalidValue(Some(t.clone())))? - .try_into() - .map_err(|_| Error::InvalidValue(Some(t.clone())))? - })), - (ScType::Bytes, Value::Number(n)) => { - from_json_primitives(&Value::String(format!("{n}")), &ScType::Bytes)? - } - (ScType::Bytes, Value::String(s)) => ScVal::Bytes( - hex::decode(s) - .map_err(|_| Error::InvalidValue(Some(t.clone())))? - .try_into() - .map_err(|_| Error::InvalidValue(Some(t.clone())))?, - ), - (ScType::Bytes | ScType::BytesN(_), Value::Array(raw)) => { - let b: Result, Error> = raw - .iter() - .map(|item| { - item.as_u64() - .ok_or_else(|| Error::InvalidValue(Some(t.clone())))? - .try_into() - .map_err(|_| Error::InvalidValue(Some(t.clone()))) - }) - .collect(); - let converted: BytesM<{ u32::MAX }> = b?.try_into().map_err(Error::Xdr)?; - ScVal::Bytes(ScBytes(converted)) - } - - (ScType::String, Value::String(s)) => ScVal::String(ScString( - s.try_into() - .map_err(|_| Error::InvalidValue(Some(t.clone())))?, - )), - // Todo make proper error Which shouldn't exist - (_, raw) => serde_json::from_value(raw.clone())?, - }; - Ok(val) -} - -/// # Errors -/// -/// Might return an error -pub fn to_string(v: &ScVal) -> Result { - #[allow(clippy::match_same_arms)] - Ok(match v { - // If symbols are a top-level thing we omit the wrapping quotes - // TODO: Decide if this is a good idea or not. - ScVal::Symbol(v) => std::str::from_utf8(v.as_slice()) - .map_err(|_| Error::InvalidValue(Some(ScType::Symbol)))? - .to_string(), - ScVal::LedgerKeyContractInstance => "LedgerKeyContractInstance".to_string(), - _ => serde_json::to_string(&to_json(v)?)?, - }) -} - -/// # Errors -/// -/// Might return an error -#[allow(clippy::too_many_lines)] -pub fn to_json(v: &ScVal) -> Result { - #[allow(clippy::match_same_arms)] - let val: Value = match v { - ScVal::Bool(b) => Value::Bool(*b), - ScVal::Void => Value::Null, - ScVal::LedgerKeyContractInstance => Value::String("LedgerKeyContractInstance".to_string()), - ScVal::U64(v) => Value::Number(serde_json::Number::from(*v)), - ScVal::Timepoint(tp) => Value::Number(serde_json::Number::from(tp.0)), - ScVal::Duration(d) => Value::Number(serde_json::Number::from(d.0)), - ScVal::I64(v) => Value::Number(serde_json::Number::from(*v)), - ScVal::U32(v) => Value::Number(serde_json::Number::from(*v)), - ScVal::I32(v) => Value::Number(serde_json::Number::from(*v)), - ScVal::Symbol(v) => Value::String( - std::str::from_utf8(v.as_slice()) - .map_err(|_| Error::InvalidValue(Some(ScType::Symbol)))? - .to_string(), - ), - ScVal::String(v) => Value::String( - std::str::from_utf8(v.as_slice()) - .map_err(|_| Error::InvalidValue(Some(ScType::Symbol)))? - .to_string(), - ), - ScVal::Vec(v) => { - let values: Result, Error> = v.as_ref().map_or_else( - || Ok(vec![]), - |v| { - v.iter() - .map(|item| -> Result { to_json(item) }) - .collect() - }, - ); - Value::Array(values?) - } - ScVal::Map(None) => Value::Object(serde_json::Map::with_capacity(0)), - ScVal::Map(Some(v)) => { - // TODO: What do we do if the key is not a string? - let mut m = serde_json::Map::::with_capacity(v.len()); - for ScMapEntry { key, val } in v.iter() { - let k: String = to_string(key)?; - let v: Value = to_json(val).map_err(|_| Error::InvalidValue(None))?; - m.insert(k, v); - } - Value::Object(m) - } - ScVal::Bytes(v) => Value::String(to_lower_hex(v.as_slice())), - ScVal::Address(v) => sc_address_to_json(v), - ScVal::U128(n) => { - let hi: [u8; 8] = n.hi.to_be_bytes(); - let lo: [u8; 8] = n.lo.to_be_bytes(); - let bytes = [hi, lo].concat(); - // Always output u128s as strings - let v = u128::from_be_bytes( - bytes - .as_slice() - .try_into() - .map_err(|_| Error::InvalidValue(Some(ScType::I128)))?, - ) - .to_string(); - Value::String(v) - } - ScVal::I128(n) => { - let hi: [u8; 8] = n.hi.to_be_bytes(); - let lo: [u8; 8] = n.lo.to_be_bytes(); - let bytes = [hi, lo].concat(); - // Always output u128s as strings - let v = i128::from_be_bytes( - bytes - .as_slice() - .try_into() - .map_err(|_| Error::InvalidValue(Some(ScType::I128)))?, - ) - .to_string(); - Value::String(v) - } - ScVal::U256(u256parts) => { - let bytes = [ - u256parts.hi_hi.to_be_bytes(), - u256parts.hi_lo.to_be_bytes(), - u256parts.lo_hi.to_be_bytes(), - u256parts.lo_lo.to_be_bytes(), - ] - .concat(); - let u256 = ethnum::U256::from_be_bytes( - bytes - .as_slice() - .try_into() - .map_err(|_| Error::InvalidValue(Some(ScType::U256)))?, - ); - Value::String(u256.to_string()) - } - ScVal::I256(i256parts) => { - let bytes = [ - i256parts.hi_hi.to_be_bytes(), - i256parts.hi_lo.to_be_bytes(), - i256parts.lo_hi.to_be_bytes(), - i256parts.lo_lo.to_be_bytes(), - ] - .concat(); - let i256 = ethnum::I256::from_be_bytes( - bytes - .as_slice() - .try_into() - .map_err(|_| Error::InvalidValue(Some(ScType::I256)))?, - ); - Value::String(i256.to_string()) - } - ScVal::ContractInstance(ScContractInstance { - executable: ContractExecutable::Wasm(hash), - .. - }) => json!({ "hash": hash }), - ScVal::ContractInstance(ScContractInstance { - executable: ContractExecutable::StellarAsset, - .. - }) => json!({"SAC": true}), - ScVal::LedgerKeyNonce(ScNonceKey { nonce }) => { - Value::Number(serde_json::Number::from(*nonce)) - } - ScVal::Error(e) => serde_json::to_value(e)?, - }; - Ok(val) -} - -fn sc_address_to_json(v: &ScAddress) -> Value { - match v { - ScAddress::Account(AccountId(PublicKey::PublicKeyTypeEd25519(Uint256(k)))) => { - Value::String(stellar_strkey::ed25519::PublicKey(*k).to_string()) - } - ScAddress::Contract(Hash(h)) => Value::String(stellar_strkey::Contract(*h).to_string()), - } -} - -fn sc_address_from_json(s: &str) -> Result { - stellar_strkey::Strkey::from_string(s) - .map_err(|_| Error::InvalidValue(Some(ScType::Address))) - .map(|parsed| match parsed { - stellar_strkey::Strkey::PublicKeyEd25519(p) => Some(ScVal::Address( - ScAddress::Account(AccountId(PublicKey::PublicKeyTypeEd25519(Uint256(p.0)))), - )), - stellar_strkey::Strkey::Contract(c) => { - Some(ScVal::Address(ScAddress::Contract(Hash(c.0)))) - } - _ => None, - })? - .ok_or(Error::InvalidValue(Some(ScType::Address))) -} - -fn to_lower_hex(bytes: &[u8]) -> String { - let mut res = String::with_capacity(bytes.len()); - for b in bytes { - res.push_str(&format!("{b:02x}")); - } - res -} - -impl Spec { - #[must_use] - pub fn arg_value_name(&self, type_: &ScType, depth: usize) -> Option { - match type_ { - ScType::U64 => Some("u64".to_string()), - ScType::I64 => Some("i64".to_string()), - ScType::U128 => Some("u128".to_string()), - ScType::I128 => Some("i128".to_string()), - ScType::U32 => Some("u32".to_string()), - ScType::I32 => Some("i32".to_string()), - ScType::Bool => Some("bool".to_string()), - ScType::Symbol => Some("Symbol".to_string()), - ScType::Error => Some("Error".to_string()), - ScType::Bytes => Some("hex_bytes".to_string()), - ScType::Address => Some("Address".to_string()), - ScType::Void => Some("Null".to_string()), - ScType::Timepoint => Some("Timepoint".to_string()), - ScType::Duration => Some("Duration".to_string()), - ScType::U256 => Some("u256".to_string()), - ScType::I256 => Some("i256".to_string()), - ScType::String => Some("String".to_string()), - ScType::Option(val) => { - let ScSpecTypeOption { value_type } = val.as_ref(); - let inner = self.arg_value_name(value_type.as_ref(), depth + 1)?; - Some(format!("Option<{inner}>")) - } - ScType::Vec(val) => { - let ScSpecTypeVec { element_type } = val.as_ref(); - let inner = self.arg_value_name(element_type.as_ref(), depth + 1)?; - Some(format!("Array<{inner}>")) - } - ScType::Result(val) => { - let ScSpecTypeResult { - ok_type, - error_type, - } = val.as_ref(); - let ok = self.arg_value_name(ok_type.as_ref(), depth + 1)?; - let error = self.arg_value_name(error_type.as_ref(), depth + 1)?; - Some(format!("Result<{ok}, {error}>")) - } - ScType::Tuple(val) => { - let ScSpecTypeTuple { value_types } = val.as_ref(); - let names = value_types - .iter() - .map(|t| self.arg_value_name(t, depth + 1)) - .collect::>>()? - .join(", "); - Some(format!("Tuple<{names}>")) - } - ScType::Map(val) => { - let ScSpecTypeMap { - key_type, - value_type, - } = val.as_ref(); - let (key, val) = ( - self.arg_value_name(key_type.as_ref(), depth + 1)?, - self.arg_value_name(value_type.as_ref(), depth + 1)?, - ); - Some(format!("Map<{key}, {val}>")) - } - ScType::BytesN(t) => Some(format!("{}_hex_bytes", t.n)), - ScType::Udt(ScSpecTypeUdt { name }) => { - match self.find(&name.to_utf8_string_lossy()).ok()? { - ScSpecEntry::UdtStructV0(ScSpecUdtStructV0 { fields, .. }) - if fields - .first() - .map(|f| f.name.to_utf8_string_lossy() == "0") - .unwrap_or_default() => - { - let fields = fields - .iter() - .map(|t| self.arg_value_name(&t.type_, depth + 1)) - .collect::>>()? - .join(", "); - Some(format!("[{fields}]")) - } - ScSpecEntry::UdtStructV0(strukt) => self.arg_value_udt(strukt, depth), - ScSpecEntry::UdtUnionV0(union) => self.arg_value_union(union, depth), - ScSpecEntry::UdtEnumV0(enum_) => Some(arg_value_enum(enum_)), - ScSpecEntry::FunctionV0(_) | ScSpecEntry::UdtErrorEnumV0(_) => None, - } - } - // No specific value name for these yet. - ScType::Val => None, - } - } - - fn arg_value_udt(&self, strukt: &ScSpecUdtStructV0, depth: usize) -> Option { - let inner = strukt - .fields - .iter() - .map(|f| (f.name.to_utf8_string_lossy(), &f.type_)) - .map(|(name, type_)| { - let type_ = self.arg_value_name(type_, depth + 1)?; - Some(format!("{name}: {type_}")) - }) - .collect::>>()? - .join(", "); - Some(format!("{{ {inner} }}")) - } - - fn arg_value_union(&self, union: &ScSpecUdtUnionV0, depth: usize) -> Option { - union - .cases - .iter() - .map(|f| { - Some(match f { - ScSpecUdtUnionCaseV0::VoidV0(ScSpecUdtUnionCaseVoidV0 { name, .. }) => { - name.to_utf8_string_lossy() - } - ScSpecUdtUnionCaseV0::TupleV0(ScSpecUdtUnionCaseTupleV0 { - name, - type_, - .. - }) => format!( - "{}({})", - name.to_utf8_string_lossy(), - type_ - .iter() - .map(|type_| self.arg_value_name(type_, depth + 1)) - .collect::>>()? - .join(",") - ), - }) - }) - .collect::>>() - .map(|v| v.join(" | ")) - } -} - -fn arg_value_enum(enum_: &ScSpecUdtEnumV0) -> String { - enum_ - .cases - .iter() - .map(|case| case.value.to_string()) - .join(" | ") -} - -// Example implementation -impl Spec { - #[must_use] - pub fn example(&self, type_: &ScType) -> Option { - match type_ { - ScType::U64 => Some("42".to_string()), - ScType::I64 => Some("-42".to_string()), - ScType::U128 => Some("\"1000\"".to_string()), - ScType::I128 => Some("\"-100\"".to_string()), - ScType::U32 => Some("1".to_string()), - ScType::I32 => Some("-1".to_string()), - ScType::Bool => Some("true".to_string()), - ScType::Symbol => Some("\"hello\"".to_string()), - ScType::Error => Some("Error".to_string()), - ScType::Bytes => Some("\"beefface123\"".to_string()), - ScType::Address => { - Some("\"GDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCR4W4\"".to_string()) - } - ScType::Void => Some("null".to_string()), - ScType::Timepoint => Some("1234".to_string()), - ScType::Duration => Some("9999".to_string()), - ScType::U256 => Some("\"2000\"".to_string()), - ScType::I256 => Some("\"-20000\"".to_string()), - ScType::String => Some("\"hello world\"".to_string()), - ScType::Option(val) => { - let ScSpecTypeOption { value_type } = val.as_ref(); - self.example(value_type.as_ref()) - } - ScType::Vec(val) => { - let ScSpecTypeVec { element_type } = val.as_ref(); - let inner = self.example(element_type.as_ref())?; - Some(format!("[ {inner} ]")) - } - ScType::Result(val) => { - let ScSpecTypeResult { - ok_type, - error_type, - } = val.as_ref(); - let ok = self.example(ok_type.as_ref())?; - let error = self.example(error_type.as_ref())?; - Some(format!("Result<{ok}, {error}>")) - } - ScType::Tuple(val) => { - let ScSpecTypeTuple { value_types } = val.as_ref(); - let names = value_types - .iter() - .map(|t| self.example(t)) - .collect::>>()? - .join(", "); - Some(format!("[{names}]")) - } - ScType::Map(map) => { - let ScSpecTypeMap { - key_type, - value_type, - } = map.as_ref(); - let (mut key, val) = ( - self.example(key_type.as_ref())?, - self.example(value_type.as_ref())?, - ); - if !matches!(key_type.as_ref(), ScType::Symbol) { - key = format!("\"{key}\""); - } - Some(format!("{{ {key}: {val} }}")) - } - ScType::BytesN(n) => { - let n = n.n as usize; - let res = if n % 2 == 0 { - "ef".repeat(n) - } else { - let mut s = "ef".repeat(n - 1); - s.push('e'); - s - }; - Some(format!("\"{res}\"")) - } - ScType::Udt(ScSpecTypeUdt { name }) => { - self.example_udts(name.to_utf8_string_lossy().as_ref()) - } - // No specific value name for these yet. - ScType::Val => None, - } - } - - fn example_udts(&self, name: &str) -> Option { - match self.find(name).ok() { - Some(ScSpecEntry::UdtStructV0(strukt)) => { - // Check if a tuple strukt - if !strukt.fields.is_empty() && strukt.fields[0].name.to_utf8_string_lossy() == "0" - { - let value_types = strukt - .fields - .iter() - .map(|f| f.type_.clone()) - .collect::>() - .try_into() - .ok()?; - return self.example(&ScType::Tuple(Box::new(ScSpecTypeTuple { value_types }))); - } - let inner = strukt - .fields - .iter() - .map(|f| (f.name.to_utf8_string_lossy(), &f.type_)) - .map(|(name, type_)| { - let type_ = self.example(type_)?; - let name = format!(r#""{name}""#); - Some(format!("{name}: {type_}")) - }) - .collect::>>()? - .join(", "); - Some(format!(r#"{{ {inner} }}"#)) - } - Some(ScSpecEntry::UdtUnionV0(union)) => self.example_union(union), - Some(ScSpecEntry::UdtEnumV0(enum_)) => { - enum_.cases.iter().next().map(|c| c.value.to_string()) - } - Some(ScSpecEntry::FunctionV0(_) | ScSpecEntry::UdtErrorEnumV0(_)) | None => None, - } - } - - fn example_union(&self, union: &ScSpecUdtUnionV0) -> Option { - let res = union - .cases - .iter() - .map(|case| match case { - ScSpecUdtUnionCaseV0::VoidV0(ScSpecUdtUnionCaseVoidV0 { name, .. }) => { - Some(format!("\"{}\"", name.to_utf8_string_lossy())) - } - ScSpecUdtUnionCaseV0::TupleV0(ScSpecUdtUnionCaseTupleV0 { - name, type_, .. - }) => { - if type_.len() == 1 { - let single = self.example(&type_[0])?; - Some(format!("{{\"{}\":{single}}}", name.to_utf8_string_lossy())) - } else { - let names = type_ - .iter() - .map(|t| self.example(t)) - .collect::>>()? - .join(", "); - Some(format!("{{\"{}\":[{names}]}}", name.to_utf8_string_lossy())) - } - } - }) - .collect::>>()?; - Some(res.join("|")) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use stellar_xdr::curr::ScSpecTypeBytesN; - - #[test] - fn from_json_primitives_bytesn() { - // TODO: Add test for parsing addresses - - // Check it parses hex-encoded bytes - let b = from_json_primitives( - &Value::String("beefface".to_string()), - &ScType::BytesN(ScSpecTypeBytesN { n: 4 }), - ) - .unwrap(); - assert_eq!( - b, - ScVal::Bytes(ScBytes(vec![0xbe, 0xef, 0xfa, 0xce].try_into().unwrap())) - ); - - // Check it parses hex-encoded bytes when they are all numbers. Normally the json would - // interpret the CLI arg as a number, so we need a special case there. - let b = from_json_primitives( - &Value::Number(4554.into()), - &ScType::BytesN(ScSpecTypeBytesN { n: 2 }), - ) - .unwrap(); - assert_eq!( - b, - ScVal::Bytes(ScBytes(vec![0x45, 0x54].try_into().unwrap())) - ); - } - - #[test] - fn from_json_primitives_bytes() { - // Check it parses hex-encoded bytes - let b = - from_json_primitives(&Value::String("beefface".to_string()), &ScType::Bytes).unwrap(); - assert_eq!( - b, - ScVal::Bytes(ScBytes(vec![0xbe, 0xef, 0xfa, 0xce].try_into().unwrap())) - ); - - // Check it parses hex-encoded bytes when they are all numbers. Normally the json would - // interpret the CLI arg as a number, so we need a special case there. - let b = from_json_primitives(&Value::Number(4554.into()), &ScType::Bytes).unwrap(); - assert_eq!( - b, - ScVal::Bytes(ScBytes(vec![0x45, 0x54].try_into().unwrap())) - ); - } - - #[test] - fn test_sc_address_from_json_strkey() { - // All zero contract address - match sc_address_from_json("CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4") { - Ok(addr) => assert_eq!(addr, ScVal::Address(ScAddress::Contract(Hash([0; 32])))), - Err(e) => panic!("Unexpected error: {e}"), - } - - // Real contract address - match sc_address_from_json("CA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAXE") { - Ok(addr) => assert_eq!( - addr, - ScVal::Address(ScAddress::Contract( - [ - 0x36, 0x3e, 0xaa, 0x38, 0x67, 0x84, 0x1f, 0xba, 0xd0, 0xf4, 0xed, 0x88, - 0xc7, 0x79, 0xe4, 0xfe, 0x66, 0xe5, 0x6a, 0x24, 0x70, 0xdc, 0x98, 0xc0, - 0xec, 0x9c, 0x07, 0x3d, 0x05, 0xc7, 0xb1, 0x03, - ] - .try_into() - .unwrap() - )) - ), - Err(e) => panic!("Unexpected error: {e}"), - } - - // All zero user account address - match sc_address_from_json("GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF") { - Ok(addr) => assert_eq!( - addr, - ScVal::Address(ScAddress::Account(AccountId( - PublicKey::PublicKeyTypeEd25519([0; 32].try_into().unwrap()) - ))) - ), - Err(e) => panic!("Unexpected error: {e}"), - } - - // Real user account address - match sc_address_from_json("GA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQHES5") { - Ok(addr) => assert_eq!( - addr, - ScVal::Address(ScAddress::Account(AccountId( - PublicKey::PublicKeyTypeEd25519( - [ - 0x36, 0x3e, 0xaa, 0x38, 0x67, 0x84, 0x1f, 0xba, 0xd0, 0xf4, 0xed, 0x88, - 0xc7, 0x79, 0xe4, 0xfe, 0x66, 0xe5, 0x6a, 0x24, 0x70, 0xdc, 0x98, 0xc0, - 0xec, 0x9c, 0x07, 0x3d, 0x05, 0xc7, 0xb1, 0x03, - ] - .try_into() - .unwrap() - ) - ))) - ), - Err(e) => panic!("Unexpected error: {e}"), - } - } -} diff --git a/cmd/crates/soroban-spec-tools/src/utils.rs b/cmd/crates/soroban-spec-tools/src/utils.rs deleted file mode 100644 index 66b153a1..00000000 --- a/cmd/crates/soroban-spec-tools/src/utils.rs +++ /dev/null @@ -1,294 +0,0 @@ -use base64::{engine::general_purpose::STANDARD as base64, Engine as _}; -use hex::FromHexError; -use std::{ - fmt::Display, - io::{self, Cursor}, -}; - -use stellar_xdr::curr::{ - Limited, Limits, ReadXdr, ScEnvMetaEntry, ScMetaEntry, ScMetaV0, ScSpecEntry, ScSpecFunctionV0, - ScSpecUdtEnumV0, ScSpecUdtErrorEnumV0, ScSpecUdtStructV0, ScSpecUdtUnionV0, StringM, -}; - -pub struct ContractSpec { - pub env_meta_base64: Option, - pub env_meta: Vec, - pub meta_base64: Option, - pub meta: Vec, - pub spec_base64: Option, - pub spec: Vec, -} - -#[derive(thiserror::Error, Debug)] -pub enum Error { - #[error("reading file {filepath}: {error}")] - CannotReadContractFile { - filepath: std::path::PathBuf, - error: io::Error, - }, - #[error("cannot parse wasm file {file}: {error}")] - CannotParseWasm { - file: std::path::PathBuf, - error: wasmparser::BinaryReaderError, - }, - #[error("xdr processing error: {0}")] - Xdr(#[from] stellar_xdr::curr::Error), - - #[error(transparent)] - Parser(#[from] wasmparser::BinaryReaderError), -} - -impl ContractSpec { - pub fn new(bytes: &[u8]) -> Result { - let mut env_meta: Option<&[u8]> = None; - let mut meta: Option<&[u8]> = None; - let mut spec: Option<&[u8]> = None; - for payload in wasmparser::Parser::new(0).parse_all(bytes) { - let payload = payload?; - if let wasmparser::Payload::CustomSection(section) = payload { - let out = match section.name() { - "contractenvmetav0" => &mut env_meta, - "contractmetav0" => &mut meta, - "contractspecv0" => &mut spec, - _ => continue, - }; - *out = Some(section.data()); - }; - } - - let mut env_meta_base64 = None; - let env_meta = if let Some(env_meta) = env_meta { - env_meta_base64 = Some(base64.encode(env_meta)); - let cursor = Cursor::new(env_meta); - let mut read = Limited::new(cursor, Limits::none()); - ScEnvMetaEntry::read_xdr_iter(&mut read).collect::, _>>()? - } else { - vec![] - }; - - let mut meta_base64 = None; - let meta = if let Some(meta) = meta { - meta_base64 = Some(base64.encode(meta)); - let cursor = Cursor::new(meta); - let mut read = Limited::new(cursor, Limits::none()); - ScMetaEntry::read_xdr_iter(&mut read).collect::, _>>()? - } else { - vec![] - }; - - let mut spec_base64 = None; - let spec = if let Some(spec) = spec { - spec_base64 = Some(base64.encode(spec)); - let cursor = Cursor::new(spec); - let mut read = Limited::new(cursor, Limits::none()); - ScSpecEntry::read_xdr_iter(&mut read).collect::, _>>()? - } else { - vec![] - }; - - Ok(ContractSpec { - env_meta_base64, - env_meta, - meta_base64, - meta, - spec_base64, - spec, - }) - } -} - -impl Display for ContractSpec { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if let Some(env_meta) = &self.env_meta_base64 { - writeln!(f, "Env Meta: {env_meta}")?; - for env_meta_entry in &self.env_meta { - match env_meta_entry { - ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(v) => { - writeln!(f, " • Interface Version: {v}")?; - } - } - } - writeln!(f)?; - } else { - writeln!(f, "Env Meta: None\n")?; - } - - if let Some(_meta) = &self.meta_base64 { - writeln!(f, "Contract Meta:")?; - for meta_entry in &self.meta { - match meta_entry { - ScMetaEntry::ScMetaV0(ScMetaV0 { key, val }) => { - writeln!(f, " • {key}: {val}")?; - } - } - } - writeln!(f)?; - } else { - writeln!(f, "Contract Meta: None\n")?; - } - - if let Some(_spec_base64) = &self.spec_base64 { - writeln!(f, "Contract Spec:")?; - for spec_entry in &self.spec { - match spec_entry { - ScSpecEntry::FunctionV0(func) => write_func(f, func)?, - ScSpecEntry::UdtUnionV0(udt) => write_union(f, udt)?, - ScSpecEntry::UdtStructV0(udt) => write_struct(f, udt)?, - ScSpecEntry::UdtEnumV0(udt) => write_enum(f, udt)?, - ScSpecEntry::UdtErrorEnumV0(udt) => write_error(f, udt)?, - } - } - } else { - writeln!(f, "Contract Spec: None")?; - } - Ok(()) - } -} - -fn write_func(f: &mut std::fmt::Formatter<'_>, func: &ScSpecFunctionV0) -> std::fmt::Result { - writeln!(f, " • Function: {}", func.name.to_utf8_string_lossy())?; - if func.doc.len() > 0 { - writeln!( - f, - " Docs: {}", - &indent(&func.doc.to_utf8_string_lossy(), 11).trim() - )?; - } - writeln!( - f, - " Inputs: {}", - indent(&format!("{:#?}", func.inputs), 5).trim() - )?; - writeln!( - f, - " Output: {}", - indent(&format!("{:#?}", func.outputs), 5).trim() - )?; - writeln!(f)?; - Ok(()) -} - -fn write_union(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtUnionV0) -> std::fmt::Result { - writeln!(f, " • Union: {}", format_name(&udt.lib, &udt.name))?; - if udt.doc.len() > 0 { - writeln!( - f, - " Docs: {}", - indent(&udt.doc.to_utf8_string_lossy(), 10).trim() - )?; - } - writeln!(f, " Cases:")?; - for case in udt.cases.iter() { - writeln!(f, " • {}", indent(&format!("{case:#?}"), 8).trim())?; - } - writeln!(f)?; - Ok(()) -} - -fn write_struct(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtStructV0) -> std::fmt::Result { - writeln!(f, " • Struct: {}", format_name(&udt.lib, &udt.name))?; - if udt.doc.len() > 0 { - writeln!( - f, - " Docs: {}", - indent(&udt.doc.to_utf8_string_lossy(), 10).trim() - )?; - } - writeln!(f, " Fields:")?; - for field in udt.fields.iter() { - writeln!( - f, - " • {}: {}", - field.name.to_utf8_string_lossy(), - indent(&format!("{:#?}", field.type_), 8).trim() - )?; - if field.doc.len() > 0 { - writeln!(f, "{}", indent(&format!("{:#?}", field.doc), 8))?; - } - } - writeln!(f)?; - Ok(()) -} - -fn write_enum(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtEnumV0) -> std::fmt::Result { - writeln!(f, " • Enum: {}", format_name(&udt.lib, &udt.name))?; - if udt.doc.len() > 0 { - writeln!( - f, - " Docs: {}", - indent(&udt.doc.to_utf8_string_lossy(), 10).trim() - )?; - } - writeln!(f, " Cases:")?; - for case in udt.cases.iter() { - writeln!(f, " • {}", indent(&format!("{case:#?}"), 8).trim())?; - } - writeln!(f)?; - Ok(()) -} - -fn write_error(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtErrorEnumV0) -> std::fmt::Result { - writeln!(f, " • Error: {}", format_name(&udt.lib, &udt.name))?; - if udt.doc.len() > 0 { - writeln!( - f, - " Docs: {}", - indent(&udt.doc.to_utf8_string_lossy(), 10).trim() - )?; - } - writeln!(f, " Cases:")?; - for case in udt.cases.iter() { - writeln!(f, " • {}", indent(&format!("{case:#?}"), 8).trim())?; - } - writeln!(f)?; - Ok(()) -} - -fn indent(s: &str, n: usize) -> String { - let pad = " ".repeat(n); - s.lines() - .map(|line| format!("{pad}{line}")) - .collect::>() - .join("\n") -} - -fn format_name(lib: &StringM<80>, name: &StringM<60>) -> String { - if lib.len() > 0 { - format!( - "{}::{}", - lib.to_utf8_string_lossy(), - name.to_utf8_string_lossy() - ) - } else { - name.to_utf8_string_lossy() - } -} - -/// # Errors -/// -/// Might return an error -pub fn padded_hex_from_str(s: &str, n: usize) -> Result, FromHexError> { - if s.len() > n * 2 { - return Err(FromHexError::InvalidStringLength); - } - let mut decoded = vec![0u8; n]; - let padded = format!("{s:0>width$}", width = n * 2); - hex::decode_to_slice(padded, &mut decoded)?; - Ok(decoded) -} - -/// # Errors -/// -/// Might return an error -pub fn contract_id_from_str(contract_id: &str) -> Result<[u8; 32], stellar_strkey::DecodeError> { - stellar_strkey::Contract::from_string(contract_id) - .map(|strkey| strkey.0) - .or_else(|_| { - // strkey failed, try to parse it as a hex string, for backwards compatibility. - padded_hex_from_str(contract_id, 32) - .map_err(|_| stellar_strkey::DecodeError::Invalid)? - .try_into() - .map_err(|_| stellar_strkey::DecodeError::Invalid) - }) - .map_err(|_| stellar_strkey::DecodeError::Invalid) -} diff --git a/cmd/crates/soroban-spec-typescript/Cargo.toml b/cmd/crates/soroban-spec-typescript/Cargo.toml deleted file mode 100644 index cc17073f..00000000 --- a/cmd/crates/soroban-spec-typescript/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "soroban-spec-typescript" -description = "Soroban contract spec utilities for generating JSON." -homepage = "https://github.com/stellar/soroban-tools" -repository = "https://github.com/stellar/soroban-tools" -authors = ["Stellar Development Foundation "] -readme = "README.md" -license = "Apache-2.0" -version.workspace = true -edition = "2021" -rust-version.workspace = true - -[dependencies] -soroban-spec = { workspace = true } -thiserror = "1.0.32" -serde = "1.0.82" -serde_derive = "1.0.82" -serde_json = "1.0.82" -sha2 = "0.9.9" -prettyplease = "0.2.4" -include_dir = { version = "0.7.3", features = ["glob"] } -heck = "0.4.1" -itertools = { workspace = true } -base64 = { workspace = true } - -[dependencies.stellar-xdr] -workspace = true -features = ["curr", "std", "serde", "base64"] - -[dev_dependencies] -temp-dir = "0.1.11" -pretty_assertions = "1.2.1" -walkdir = "2.3.3" diff --git a/cmd/crates/soroban-spec-typescript/README.md b/cmd/crates/soroban-spec-typescript/README.md deleted file mode 100644 index 4cc3f522..00000000 --- a/cmd/crates/soroban-spec-typescript/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# soroban-spec-json - -Generation of TypeScript client bindings from Soroban contract specification / -interface. diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/.gitignore b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/.gitignore deleted file mode 100644 index 72aae85f..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -out/ diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/README.md b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/README.md deleted file mode 100644 index 03f87f30..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# test_custom_types JS - -JS library for interacting with [Soroban](https://soroban.stellar.org/) smart contract `test_custom_types` via Soroban RPC. - -This library was automatically generated by Soroban CLI using a command similar to: - -```bash -soroban contract bindings ts \ - --rpc-url https://rpc-futurenet.stellar.org:443 \ - --network-passphrase "Test SDF Future Network ; October 2022" \ - --contract-id CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK \ - --output-dir ./path/to/test_custom_types -``` - -The network passphrase and contract ID are exported from [index.ts](./src/index.ts) in the `networks` constant. If you are the one who generated this library and you know that this contract is also deployed to other networks, feel free to update `networks` with other valid options. This will help your contract consumers use this library more easily. - -# To publish or not to publish - -This library is suitable for publishing to NPM. You can publish it to NPM using the `npm publish` command. - -But you don't need to publish this library to NPM to use it. You can add it to your project's `package.json` using a file path: - -```json -"dependencies": { - "test_custom_types": "./path/to/this/folder" -} -``` - -However, we've actually encountered [frustration](https://github.com/stellar/soroban-example-dapp/pull/117#discussion_r1232873560) using local libraries with NPM in this way. Though it seems a bit messy, we suggest generating the library directly to your `node_modules` folder automatically after each install by using a `postinstall` script. We've had the least trouble with this approach. NPM will automatically remove what it sees as erroneous directories during the `install` step, and then regenerate them when it gets to your `postinstall` step, which will keep the library up-to-date with your contract. - -```json -"scripts": { - "postinstall": "soroban contract bindings ts --rpc-url https://rpc-futurenet.stellar.org:443 --network-passphrase \"Test SDF Future Network ; October 2022\" --id CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK --name test_custom_types" -} -``` - -Obviously you need to adjust the above command based on the actual command you used to generate the library. - -# Use it - -Now that you have your library up-to-date and added to your project, you can import it in a file and see inline documentation for all of its exported methods: - -```js -import { Contract, networks } from "test_custom_types" - -const contract = new Contract({ - ...networks.futurenet, // for example; check which networks this library exports - rpcUrl: '...', // use your own, or find one for testing at https://soroban.stellar.org/docs/reference/rpc#public-rpc-providers -}) - -contract.| -``` - -As long as your editor is configured to show JavaScript/TypeScript documentation, you can pause your typing at that `|` to get a list of all exports and inline-documentation for each. It exports a separate [async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) function for each method in the smart contract, with documentation for each generated from the comments the contract's author included in the original source code. diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/assembled-tx.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/assembled-tx.d.ts deleted file mode 100644 index 1d5e6f5e..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/assembled-tx.d.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Account, Address, Operation, SorobanRpc, xdr } from "@stellar/stellar-sdk"; -import type { Memo, MemoType, Transaction } from "@stellar/stellar-sdk"; -import type { ClassOptions, MethodOptions, Wallet, XDR_BASE64 } from "./method-options.js"; -export type Tx = Transaction, Operation[]>; -export declare class ExpiredStateError extends Error { -} -export declare class NeedsMoreSignaturesError extends Error { -} -export declare class WalletDisconnectedError extends Error { -} -export declare class SendResultOnlyError extends Error { -} -export declare class SendFailedError extends Error { -} -export declare class NoUnsignedNonInvokerAuthEntriesError extends Error { -} -type SendTx = SorobanRpc.Api.SendTransactionResponse; -type GetTx = SorobanRpc.Api.GetTransactionResponse; -export type u32 = number; -export type i32 = number; -export type u64 = bigint; -export type i64 = bigint; -export type u128 = bigint; -export type i128 = bigint; -export type u256 = bigint; -export type i256 = bigint; -export type Option = T | undefined; -export type Typepoint = bigint; -export type Duration = bigint; -export { Address }; -export interface Error_ { - message: string; -} -export interface Result { - unwrap(): T; - unwrapErr(): E; - isOk(): boolean; - isErr(): boolean; -} -export declare class Ok implements Result { - readonly value: T; - constructor(value: T); - unwrapErr(): E; - unwrap(): T; - isOk(): boolean; - isErr(): boolean; -} -export declare class Err implements Result { - readonly error: E; - constructor(error: E); - unwrapErr(): E; - unwrap(): never; - isOk(): boolean; - isErr(): boolean; -} -export declare const contractErrorPattern: RegExp; -type AssembledTransactionOptions = MethodOptions & ClassOptions & { - method: string; - args?: any[]; - parseResultXdr: (xdr: string | xdr.ScVal | Err) => T; -}; -export declare const NULL_ACCOUNT = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF"; -export declare class AssembledTransaction { - options: AssembledTransactionOptions; - raw: Tx; - private simulation?; - private simulationResult?; - private simulationTransactionData?; - private server; - toJSON(): string; - static fromJSON(options: Omit, 'args'>, { tx, simulationResult, simulationTransactionData }: { - tx: XDR_BASE64; - simulationResult: { - auth: XDR_BASE64[]; - retval: XDR_BASE64; - }; - simulationTransactionData: XDR_BASE64; - }): AssembledTransaction; - private constructor(); - static fromSimulation(options: AssembledTransactionOptions): Promise>; - simulate: () => Promise; - get simulationData(): { - result: SorobanRpc.Api.SimulateHostFunctionResult; - transactionData: xdr.SorobanTransactionData; - }; - get result(): T; - parseError(errorMessage: string): Err | undefined; - getWallet: () => Promise; - getPublicKey: () => Promise; - /** - * Get account details from the Soroban network for the publicKey currently - * selected in user's wallet. If not connected to Freighter, use placeholder - * null account. - */ - getAccount: () => Promise; - /** - * Sign the transaction with the `wallet` (default Freighter), then send to - * the network and return a `SentTransaction` that keeps track of all the - * attempts to send and fetch the transaction from the network. - */ - signAndSend: ({ secondsToWait, force }?: { - /** - * Wait `secondsToWait` seconds (default: 10) for both the transaction to SEND successfully (will keep trying if the server returns `TRY_AGAIN_LATER`), as well as for the transaction to COMPLETE (will keep checking if the server returns `PENDING`). - */ - secondsToWait?: number | undefined; - /** - * If `true`, sign and send the transaction even if it is a read call. - */ - force?: boolean | undefined; - }) => Promise>; - getStorageExpiration: () => Promise; - /** - * Get a list of accounts, other than the invoker of the simulation, that - * need to sign auth entries in this transaction. - * - * Soroban allows multiple people to sign a transaction. Someone needs to - * sign the final transaction envelope; this person/account is called the - * _invoker_, or _source_. Other accounts might need to sign individual auth - * entries in the transaction, if they're not also the invoker. - * - * This function returns a list of accounts that need to sign auth entries, - * assuming that the same invoker/source account will sign the final - * transaction envelope as signed the initial simulation. - * - * One at a time, for each public key in this array, you will need to - * serialize this transaction with `toJSON`, send to the owner of that key, - * deserialize the transaction with `txFromJson`, and call - * {@link signAuthEntries}. Then re-serialize and send to the next account - * in this list. - */ - needsNonInvokerSigningBy: ({ includeAlreadySigned, }?: { - /** - * Whether or not to include auth entries that have already been signed. Default: false - */ - includeAlreadySigned?: boolean | undefined; - }) => Promise; - preImageFor(entry: xdr.SorobanAuthorizationEntry, signatureExpirationLedger: number): xdr.HashIdPreimage; - /** - * If {@link needsNonInvokerSigningBy} returns a non-empty list, you can serialize - * the transaction with `toJSON`, send it to the owner of one of the public keys - * in the map, deserialize with `txFromJSON`, and call this method on their - * machine. Internally, this will use `signAuthEntry` function from connected - * `wallet` for each. - * - * Then, re-serialize the transaction and either send to the next - * `needsNonInvokerSigningBy` owner, or send it back to the original account - * who simulated the transaction so they can {@link sign} the transaction - * envelope and {@link send} it to the network. - * - * Sending to all `needsNonInvokerSigningBy` owners in parallel is not currently - * supported! - */ - signAuthEntries: (expiration?: number | Promise) => Promise; - get isReadCall(): boolean; - hasRealInvoker: () => Promise; -} -/** - * A transaction that has been sent to the Soroban network. This happens in two steps: - * - * 1. `sendTransaction`: initial submission of the transaction to the network. - * This step can run into problems, and will be retried with exponential - * backoff if it does. See all attempts in `sendTransactionResponseAll` and the - * most recent attempt in `sendTransactionResponse`. - * 2. `getTransaction`: once the transaction has been submitted to the network - * successfully, you need to wait for it to finalize to get the results of the - * transaction. This step can also run into problems, and will be retried with - * exponential backoff if it does. See all attempts in - * `getTransactionResponseAll` and the most recent attempt in - * `getTransactionResponse`. - */ -declare class SentTransaction { - options: AssembledTransactionOptions; - assembled: AssembledTransaction; - server: SorobanRpc.Server; - signed: Tx; - sendTransactionResponse?: SendTx; - sendTransactionResponseAll?: SendTx[]; - getTransactionResponse?: GetTx; - getTransactionResponseAll?: GetTx[]; - constructor(options: AssembledTransactionOptions, assembled: AssembledTransaction); - static init: (options: AssembledTransactionOptions, assembled: AssembledTransaction, secondsToWait?: number) => Promise>; - private send; - get result(): T; -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/assembled-tx.js b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/assembled-tx.js deleted file mode 100644 index c60a6e5f..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/assembled-tx.js +++ /dev/null @@ -1,462 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.AssembledTransaction = exports.NULL_ACCOUNT = exports.contractErrorPattern = exports.Err = exports.Ok = exports.Address = exports.NoUnsignedNonInvokerAuthEntriesError = exports.SendFailedError = exports.SendResultOnlyError = exports.WalletDisconnectedError = exports.NeedsMoreSignaturesError = exports.ExpiredStateError = void 0; -const stellar_sdk_1 = require("@stellar/stellar-sdk"); -Object.defineProperty(exports, "Address", { enumerable: true, get: function () { return stellar_sdk_1.Address; } }); -const buffer_1 = require("buffer"); -class ExpiredStateError extends Error { -} -exports.ExpiredStateError = ExpiredStateError; -class NeedsMoreSignaturesError extends Error { -} -exports.NeedsMoreSignaturesError = NeedsMoreSignaturesError; -class WalletDisconnectedError extends Error { -} -exports.WalletDisconnectedError = WalletDisconnectedError; -class SendResultOnlyError extends Error { -} -exports.SendResultOnlyError = SendResultOnlyError; -class SendFailedError extends Error { -} -exports.SendFailedError = SendFailedError; -class NoUnsignedNonInvokerAuthEntriesError extends Error { -} -exports.NoUnsignedNonInvokerAuthEntriesError = NoUnsignedNonInvokerAuthEntriesError; -; -; -class Ok { - value; - constructor(value) { - this.value = value; - } - unwrapErr() { - throw new Error('No error'); - } - unwrap() { - return this.value; - } - isOk() { - return true; - } - isErr() { - return !this.isOk(); - } -} -exports.Ok = Ok; -class Err { - error; - constructor(error) { - this.error = error; - } - unwrapErr() { - return this.error; - } - unwrap() { - throw new Error(this.error.message); - } - isOk() { - return false; - } - isErr() { - return !this.isOk(); - } -} -exports.Err = Err; -exports.contractErrorPattern = /Error\(Contract, #(\d+)\)/; -exports.NULL_ACCOUNT = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF"; -class AssembledTransaction { - options; - raw; - simulation; - simulationResult; - simulationTransactionData; - server; - toJSON() { - return JSON.stringify({ - method: this.options.method, - tx: this.raw?.toXDR(), - simulationResult: { - auth: this.simulationData.result.auth.map(a => a.toXDR('base64')), - retval: this.simulationData.result.retval.toXDR('base64'), - }, - simulationTransactionData: this.simulationData.transactionData.toXDR('base64'), - }); - } - static fromJSON(options, { tx, simulationResult, simulationTransactionData }) { - const txn = new AssembledTransaction(options); - txn.raw = stellar_sdk_1.TransactionBuilder.fromXDR(tx, options.networkPassphrase); - txn.simulationResult = { - auth: simulationResult.auth.map(a => stellar_sdk_1.xdr.SorobanAuthorizationEntry.fromXDR(a, 'base64')), - retval: stellar_sdk_1.xdr.ScVal.fromXDR(simulationResult.retval, 'base64'), - }; - txn.simulationTransactionData = stellar_sdk_1.xdr.SorobanTransactionData.fromXDR(simulationTransactionData, 'base64'); - return txn; - } - constructor(options) { - this.options = options; - this.server = new stellar_sdk_1.SorobanRpc.Server(this.options.rpcUrl, { - allowHttp: this.options.rpcUrl.startsWith("http://"), - }); - } - static async fromSimulation(options) { - const tx = new AssembledTransaction(options); - const contract = new stellar_sdk_1.Contract(options.contractId); - tx.raw = new stellar_sdk_1.TransactionBuilder(await tx.getAccount(), { - fee: options.fee?.toString(10) ?? stellar_sdk_1.BASE_FEE, - networkPassphrase: options.networkPassphrase, - }) - .addOperation(contract.call(options.method, ...(options.args ?? []))) - .setTimeout(stellar_sdk_1.TimeoutInfinite) - .build(); - return await tx.simulate(); - } - simulate = async () => { - if (!this.raw) - throw new Error('Transaction has not yet been assembled'); - this.simulation = await this.server.simulateTransaction(this.raw); - if (stellar_sdk_1.SorobanRpc.Api.isSimulationSuccess(this.simulation)) { - this.raw = stellar_sdk_1.SorobanRpc.assembleTransaction(this.raw, this.simulation).build(); - } - return this; - }; - get simulationData() { - if (this.simulationResult && this.simulationTransactionData) { - return { - result: this.simulationResult, - transactionData: this.simulationTransactionData, - }; - } - // else, we know we just did the simulation on this machine - const simulation = this.simulation; - if (stellar_sdk_1.SorobanRpc.Api.isSimulationError(simulation)) { - throw new Error(`Transaction simulation failed: "${simulation.error}"`); - } - if (stellar_sdk_1.SorobanRpc.Api.isSimulationRestore(simulation)) { - throw new ExpiredStateError(`You need to restore some contract state before you can invoke this method. ${JSON.stringify(simulation, null, 2)}`); - } - if (!simulation.result) { - throw new Error(`Expected an invocation simulation, but got no 'result' field. Simulation: ${JSON.stringify(simulation, null, 2)}`); - } - // add to object for serialization & deserialization - this.simulationResult = simulation.result; - this.simulationTransactionData = simulation.transactionData.build(); - return { - result: this.simulationResult, - transactionData: this.simulationTransactionData, - }; - } - get result() { - try { - return this.options.parseResultXdr(this.simulationData.result.retval); - } - catch (e) { - let err = this.parseError(e.toString()); - if (err) - return err; - throw e; - } - } - parseError(errorMessage) { - if (!this.options.errorTypes) - return; - const match = errorMessage.match(exports.contractErrorPattern); - if (!match) - return; - let i = parseInt(match[1], 10); - let err = this.options.errorTypes[i]; - if (err) - return new Err(err); - } - getWallet = async () => { - return this.options.wallet ?? (await Promise.resolve().then(() => require("@stellar/freighter-api"))).default; - }; - getPublicKey = async () => { - const wallet = await this.getWallet(); - if (await wallet.isConnected() && await wallet.isAllowed()) { - return (await wallet.getUserInfo()).publicKey; - } - }; - /** - * Get account details from the Soroban network for the publicKey currently - * selected in user's wallet. If not connected to Freighter, use placeholder - * null account. - */ - getAccount = async () => { - const publicKey = await this.getPublicKey(); - return publicKey - ? await this.server.getAccount(publicKey) - : new stellar_sdk_1.Account(exports.NULL_ACCOUNT, "0"); - }; - /** - * Sign the transaction with the `wallet` (default Freighter), then send to - * the network and return a `SentTransaction` that keeps track of all the - * attempts to send and fetch the transaction from the network. - */ - signAndSend = async ({ secondsToWait = 10, force = false } = {}) => { - if (!this.raw) { - throw new Error('Transaction has not yet been simulated'); - } - if (!force && this.isReadCall) { - throw new Error('This is a read call. It requires no signature or sending. Use `force: true` to sign and send anyway.'); - } - if (!await this.hasRealInvoker()) { - throw new WalletDisconnectedError('Wallet is not connected'); - } - if (this.raw.source !== (await this.getAccount()).accountId()) { - throw new Error(`You must submit the transaction with the account that originally created it. Please switch to the wallet with "${this.raw.source}" as its public key.`); - } - if ((await this.needsNonInvokerSigningBy()).length) { - throw new NeedsMoreSignaturesError('Transaction requires more signatures. See `needsNonInvokerSigningBy` for details.'); - } - return await SentTransaction.init(this.options, this, secondsToWait); - }; - getStorageExpiration = async () => { - const entryRes = await this.server.getLedgerEntries(new stellar_sdk_1.Contract(this.options.contractId).getFootprint()); - if (!entryRes.entries || - !entryRes.entries.length || - !entryRes.entries[0].liveUntilLedgerSeq) - throw new Error('failed to get ledger entry'); - return entryRes.entries[0].liveUntilLedgerSeq; - }; - /** - * Get a list of accounts, other than the invoker of the simulation, that - * need to sign auth entries in this transaction. - * - * Soroban allows multiple people to sign a transaction. Someone needs to - * sign the final transaction envelope; this person/account is called the - * _invoker_, or _source_. Other accounts might need to sign individual auth - * entries in the transaction, if they're not also the invoker. - * - * This function returns a list of accounts that need to sign auth entries, - * assuming that the same invoker/source account will sign the final - * transaction envelope as signed the initial simulation. - * - * One at a time, for each public key in this array, you will need to - * serialize this transaction with `toJSON`, send to the owner of that key, - * deserialize the transaction with `txFromJson`, and call - * {@link signAuthEntries}. Then re-serialize and send to the next account - * in this list. - */ - needsNonInvokerSigningBy = async ({ includeAlreadySigned = false, } = {}) => { - if (!this.raw) { - throw new Error('Transaction has not yet been simulated'); - } - // We expect that any transaction constructed by these libraries has a - // single operation, which is an InvokeHostFunction operation. The host - // function being invoked is the contract method call. - if (!("operations" in this.raw)) { - throw new Error(`Unexpected Transaction type; no operations: ${JSON.stringify(this.raw)}`); - } - const rawInvokeHostFunctionOp = this.raw - .operations[0]; - return [...new Set((rawInvokeHostFunctionOp.auth ?? []).filter(entry => entry.credentials().switch() === - stellar_sdk_1.xdr.SorobanCredentialsType.sorobanCredentialsAddress() && - (includeAlreadySigned || - entry.credentials().address().signature().switch().name === 'scvVoid')).map(entry => stellar_sdk_1.StrKey.encodeEd25519PublicKey(entry.credentials().address().address().accountId().ed25519())))]; - }; - preImageFor(entry, signatureExpirationLedger) { - const addrAuth = entry.credentials().address(); - return stellar_sdk_1.xdr.HashIdPreimage.envelopeTypeSorobanAuthorization(new stellar_sdk_1.xdr.HashIdPreimageSorobanAuthorization({ - networkId: (0, stellar_sdk_1.hash)(buffer_1.Buffer.from(this.options.networkPassphrase)), - nonce: addrAuth.nonce(), - invocation: entry.rootInvocation(), - signatureExpirationLedger, - })); - } - /** - * If {@link needsNonInvokerSigningBy} returns a non-empty list, you can serialize - * the transaction with `toJSON`, send it to the owner of one of the public keys - * in the map, deserialize with `txFromJSON`, and call this method on their - * machine. Internally, this will use `signAuthEntry` function from connected - * `wallet` for each. - * - * Then, re-serialize the transaction and either send to the next - * `needsNonInvokerSigningBy` owner, or send it back to the original account - * who simulated the transaction so they can {@link sign} the transaction - * envelope and {@link send} it to the network. - * - * Sending to all `needsNonInvokerSigningBy` owners in parallel is not currently - * supported! - */ - signAuthEntries = async ( - /** - * When to set each auth entry to expire. Could be any number of blocks in - * the future. Can be supplied as a promise or a raw number. Default: - * contract's current `persistent` storage expiration date/ledger - * number/block. - */ - expiration = this.getStorageExpiration()) => { - if (!this.raw) - throw new Error('Transaction has not yet been assembled or simulated'); - const needsNonInvokerSigningBy = await this.needsNonInvokerSigningBy(); - if (!needsNonInvokerSigningBy) - throw new NoUnsignedNonInvokerAuthEntriesError('No unsigned non-invoker auth entries; maybe you already signed?'); - const publicKey = await this.getPublicKey(); - if (!publicKey) - throw new Error('Could not get public key from wallet; maybe Freighter is not signed in?'); - if (needsNonInvokerSigningBy.indexOf(publicKey) === -1) - throw new Error(`No auth entries for public key "${publicKey}"`); - const wallet = await this.getWallet(); - const rawInvokeHostFunctionOp = this.raw - .operations[0]; - const authEntries = rawInvokeHostFunctionOp.auth ?? []; - for (const [i, entry] of authEntries.entries()) { - if (entry.credentials().switch() !== - stellar_sdk_1.xdr.SorobanCredentialsType.sorobanCredentialsAddress()) { - // if the invoker/source account, then the entry doesn't need explicit - // signature, since the tx envelope is already signed by the source - // account, so only check for sorobanCredentialsAddress - continue; - } - const pk = stellar_sdk_1.StrKey.encodeEd25519PublicKey(entry.credentials().address().address().accountId().ed25519()); - // this auth entry needs to be signed by a different account - // (or maybe already was!) - if (pk !== publicKey) - continue; - authEntries[i] = await (0, stellar_sdk_1.authorizeEntry)(entry, async (preimage) => buffer_1.Buffer.from(await wallet.signAuthEntry(preimage.toXDR('base64')), 'base64'), await expiration, this.options.networkPassphrase); - } - }; - get isReadCall() { - const authsCount = this.simulationData.result.auth.length; - const writeLength = this.simulationData.transactionData.resources().footprint().readWrite().length; - return (authsCount === 0) && (writeLength === 0); - } - hasRealInvoker = async () => { - const account = await this.getAccount(); - return account.accountId() !== exports.NULL_ACCOUNT; - }; -} -exports.AssembledTransaction = AssembledTransaction; -/** - * A transaction that has been sent to the Soroban network. This happens in two steps: - * - * 1. `sendTransaction`: initial submission of the transaction to the network. - * This step can run into problems, and will be retried with exponential - * backoff if it does. See all attempts in `sendTransactionResponseAll` and the - * most recent attempt in `sendTransactionResponse`. - * 2. `getTransaction`: once the transaction has been submitted to the network - * successfully, you need to wait for it to finalize to get the results of the - * transaction. This step can also run into problems, and will be retried with - * exponential backoff if it does. See all attempts in - * `getTransactionResponseAll` and the most recent attempt in - * `getTransactionResponse`. - */ -class SentTransaction { - options; - assembled; - server; - signed; - sendTransactionResponse; - sendTransactionResponseAll; - getTransactionResponse; - getTransactionResponseAll; - constructor(options, assembled) { - this.options = options; - this.assembled = assembled; - this.server = new stellar_sdk_1.SorobanRpc.Server(this.options.rpcUrl, { - allowHttp: this.options.rpcUrl.startsWith("http://"), - }); - this.assembled = assembled; - } - static init = async (options, assembled, secondsToWait = 10) => { - const tx = new SentTransaction(options, assembled); - return await tx.send(secondsToWait); - }; - send = async (secondsToWait = 10) => { - const wallet = await this.assembled.getWallet(); - this.sendTransactionResponseAll = await withExponentialBackoff(async (previousFailure) => { - if (previousFailure) { - // Increment transaction sequence number and resimulate before trying again - // Soroban transaction can only have 1 operation - const op = this.assembled.raw.operations[0]; - this.assembled.raw = new stellar_sdk_1.TransactionBuilder(await this.assembled.getAccount(), { - fee: this.assembled.raw.fee, - networkPassphrase: this.options.networkPassphrase, - }) - .setTimeout(stellar_sdk_1.TimeoutInfinite) - .addOperation(stellar_sdk_1.Operation.invokeHostFunction({ ...op, auth: op.auth ?? [] })) - .build(); - await this.assembled.simulate(); - } - const signature = await wallet.signTransaction(this.assembled.raw.toXDR(), { - networkPassphrase: this.options.networkPassphrase, - }); - this.signed = stellar_sdk_1.TransactionBuilder.fromXDR(signature, this.options.networkPassphrase); - return this.server.sendTransaction(this.signed); - }, resp => resp.status !== "PENDING", secondsToWait); - this.sendTransactionResponse = this.sendTransactionResponseAll[this.sendTransactionResponseAll.length - 1]; - if (this.sendTransactionResponse.status !== "PENDING") { - throw new Error(`Tried to resubmit transaction for ${secondsToWait} seconds, but it's still failing. ` + - `All attempts: ${JSON.stringify(this.sendTransactionResponseAll, null, 2)}`); - } - const { hash } = this.sendTransactionResponse; - this.getTransactionResponseAll = await withExponentialBackoff(() => this.server.getTransaction(hash), resp => resp.status === stellar_sdk_1.SorobanRpc.Api.GetTransactionStatus.NOT_FOUND, secondsToWait); - this.getTransactionResponse = this.getTransactionResponseAll[this.getTransactionResponseAll.length - 1]; - if (this.getTransactionResponse.status === stellar_sdk_1.SorobanRpc.Api.GetTransactionStatus.NOT_FOUND) { - console.error(`Waited ${secondsToWait} seconds for transaction to complete, but it did not. ` + - `Returning anyway. Check the transaction status manually. ` + - `Sent transaction: ${JSON.stringify(this.sendTransactionResponse, null, 2)}\n` + - `All attempts to get the result: ${JSON.stringify(this.getTransactionResponseAll, null, 2)}`); - } - return this; - }; - get result() { - // 1. check if transaction was submitted and awaited with `getTransaction` - if ("getTransactionResponse" in this && - this.getTransactionResponse) { - // getTransactionResponse has a `returnValue` field unless it failed - if ("returnValue" in this.getTransactionResponse) { - return this.options.parseResultXdr(this.getTransactionResponse.returnValue); - } - // if "returnValue" not present, the transaction failed; return without parsing the result - throw new Error("Transaction failed! Cannot parse result."); - } - // 2. otherwise, maybe it was merely sent with `sendTransaction` - if (this.sendTransactionResponse) { - const errorResult = this.sendTransactionResponse.errorResult?.result(); - if (errorResult) { - throw new SendFailedError(`Transaction simulation looked correct, but attempting to send the transaction failed. Check \`simulation\` and \`sendTransactionResponseAll\` to troubleshoot. Decoded \`sendTransactionResponse.errorResultXdr\`: ${errorResult}`); - } - throw new SendResultOnlyError(`Transaction was sent to the network, but not yet awaited. No result to show. Await transaction completion with \`getTransaction(sendTransactionResponse.hash)\``); - } - // 3. finally, if neither of those are present, throw an error - throw new Error(`Sending transaction failed: ${JSON.stringify(this.assembled)}`); - } -} -/** - * Keep calling a `fn` for `secondsToWait` seconds, if `keepWaitingIf` is true. - * Returns an array of all attempts to call the function. - */ -async function withExponentialBackoff(fn, keepWaitingIf, secondsToWait, exponentialFactor = 1.5, verbose = false) { - const attempts = []; - let count = 0; - attempts.push(await fn()); - if (!keepWaitingIf(attempts[attempts.length - 1])) - return attempts; - const waitUntil = new Date(Date.now() + secondsToWait * 1000).valueOf(); - let waitTime = 1000; - let totalWaitTime = waitTime; - while (Date.now() < waitUntil && keepWaitingIf(attempts[attempts.length - 1])) { - count++; - // Wait a beat - if (verbose) { - console.info(`Waiting ${waitTime}ms before trying again (bringing the total wait time to ${totalWaitTime}ms so far, of total ${secondsToWait * 1000}ms)`); - } - await new Promise(res => setTimeout(res, waitTime)); - // Exponential backoff - waitTime = waitTime * exponentialFactor; - if (new Date(Date.now() + waitTime).valueOf() > waitUntil) { - waitTime = waitUntil - Date.now(); - if (verbose) { - console.info(`was gonna wait too long; new waitTime: ${waitTime}ms`); - } - } - totalWaitTime = waitTime + totalWaitTime; - // Try again - attempts.push(await fn(attempts[attempts.length - 1])); - if (verbose && keepWaitingIf(attempts[attempts.length - 1])) { - console.info(`${count}. Called ${fn}; ${attempts.length} prev attempts. Most recent: ${JSON.stringify(attempts[attempts.length - 1], null, 2)}`); - } - } - return attempts; -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.d.ts deleted file mode 100644 index 66d3d595..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.d.ts +++ /dev/null @@ -1,424 +0,0 @@ -import { ContractSpec } from '@stellar/stellar-sdk'; -import { Buffer } from "buffer"; -import { AssembledTransaction, Ok, Err } from './assembled-tx.js'; -import type { u32, i32, i64, i128, Option, Error_ } from './assembled-tx.js'; -import type { ClassOptions } from './method-options.js'; -export * from './assembled-tx.js'; -export * from './method-options.js'; -export declare const networks: { - readonly futurenet: { - readonly networkPassphrase: "Test SDF Future Network ; October 2022"; - readonly contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK"; - }; -}; -/** - This is from the rust doc above the struct Test - */ -export interface Test { - /** - - */ - a: u32; - /** - - */ - b: boolean; - /** - - */ - c: string; -} -/** - - */ -export type SimpleEnum = { - tag: "First"; - values: void; -} | { - tag: "Second"; - values: void; -} | { - tag: "Third"; - values: void; -}; -/** - - */ -export declare enum RoyalCard { - Jack = 11, - Queen = 12, - King = 13 -} -/** - - */ -export type TupleStruct = readonly [Test, SimpleEnum]; -/** - - */ -export type ComplexEnum = { - tag: "Struct"; - values: readonly [Test]; -} | { - tag: "Tuple"; - values: readonly [TupleStruct]; -} | { - tag: "Enum"; - values: readonly [SimpleEnum]; -} | { - tag: "Asset"; - values: readonly [string, i128]; -} | { - tag: "Void"; - values: void; -}; -/** - - */ -export declare const Errors: { - 1: { - message: string; - }; -}; -export declare class Contract { - readonly options: ClassOptions; - spec: ContractSpec; - constructor(options: ClassOptions); - private readonly parsers; - private txFromJSON; - readonly fromJSON: { - hello: (json: string) => AssembledTransaction; - woid: (json: string) => AssembledTransaction; - val: (json: string) => AssembledTransaction; - u32FailOnEven: (json: string) => AssembledTransaction | Ok>; - u32: (json: string) => AssembledTransaction; - i32: (json: string) => AssembledTransaction; - i64: (json: string) => AssembledTransaction; - struktHel: (json: string) => AssembledTransaction; - strukt: (json: string) => AssembledTransaction; - simple: (json: string) => AssembledTransaction; - complex: (json: string) => AssembledTransaction; - addresse: (json: string) => AssembledTransaction; - bytes: (json: string) => AssembledTransaction; - bytesN: (json: string) => AssembledTransaction; - card: (json: string) => AssembledTransaction; - boolean: (json: string) => AssembledTransaction; - not: (json: string) => AssembledTransaction; - i128: (json: string) => AssembledTransaction; - u128: (json: string) => AssembledTransaction; - multiArgs: (json: string) => AssembledTransaction; - map: (json: string) => AssembledTransaction>; - vec: (json: string) => AssembledTransaction; - tuple: (json: string) => AssembledTransaction; - option: (json: string) => AssembledTransaction>; - u256: (json: string) => AssembledTransaction; - i256: (json: string) => AssembledTransaction; - string: (json: string) => AssembledTransaction; - tupleStrukt: (json: string) => AssembledTransaction; - }; - /** -* Construct and simulate a hello transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - hello: ({ hello }: { - hello: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a woid transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - woid: (options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a val transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - val: (options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a u32_fail_on_even transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u32FailOnEven: ({ u32_ }: { - u32_: u32; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise | Ok>>; - /** -* Construct and simulate a u32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u32: ({ u32_ }: { - u32_: u32; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i32: ({ i32_ }: { - i32_: i32; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i64_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i64: ({ i64_ }: { - i64_: i64; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a strukt_hel transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example contract method which takes a struct -*/ - struktHel: ({ strukt }: { - strukt: Test; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - strukt: ({ strukt }: { - strukt: Test; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a simple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - simple: ({ simple }: { - simple: SimpleEnum; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a complex transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - complex: ({ complex }: { - complex: ComplexEnum; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a addresse transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - addresse: ({ addresse }: { - addresse: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a bytes transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - bytes: ({ bytes }: { - bytes: Buffer; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a bytes_n transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - bytesN: ({ bytes_n }: { - bytes_n: Buffer; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a card transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - card: ({ card }: { - card: RoyalCard; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a boolean transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - boolean: ({ boolean }: { - boolean: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a not transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Negates a boolean value -*/ - not: ({ boolean }: { - boolean: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i128: ({ i128 }: { - i128: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a u128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u128: ({ u128 }: { - u128: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a multi_args transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - multiArgs: ({ a, b }: { - a: u32; - b: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a map transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - map: ({ map }: { - map: Map; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>>; - /** -* Construct and simulate a vec transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - vec: ({ vec }: { - vec: Array; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a tuple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - tuple: ({ tuple }: { - tuple: readonly [string, u32]; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a option transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example of an optional argument -*/ - option: ({ option }: { - option: Option; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>>; - /** -* Construct and simulate a u256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u256: ({ u256 }: { - u256: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i256: ({ i256 }: { - i256: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a string transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - string: ({ string }: { - string: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a tuple_strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - tupleStrukt: ({ tuple_strukt }: { - tuple_strukt: TupleStruct; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.js b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.js deleted file mode 100644 index d6e27aa8..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.js +++ /dev/null @@ -1,527 +0,0 @@ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __exportStar = (this && this.__exportStar) || function(m, exports) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.Contract = exports.Errors = exports.RoyalCard = exports.networks = void 0; -const stellar_sdk_1 = require("@stellar/stellar-sdk"); -const buffer_1 = require("buffer"); -const assembled_tx_js_1 = require("./assembled-tx.js"); -__exportStar(require("./assembled-tx.js"), exports); -__exportStar(require("./method-options.js"), exports); -if (typeof window !== 'undefined') { - //@ts-ignore Buffer exists - window.Buffer = window.Buffer || buffer_1.Buffer; -} -exports.networks = { - futurenet: { - networkPassphrase: "Test SDF Future Network ; October 2022", - contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK", - } -}; -/** - - */ -var RoyalCard; -(function (RoyalCard) { - RoyalCard[RoyalCard["Jack"] = 11] = "Jack"; - RoyalCard[RoyalCard["Queen"] = 12] = "Queen"; - RoyalCard[RoyalCard["King"] = 13] = "King"; -})(RoyalCard || (exports.RoyalCard = RoyalCard = {})); -/** - - */ -exports.Errors = { - 1: { message: "Please provide an odd number" } -}; -class Contract { - options; - spec; - constructor(options) { - this.options = options; - this.spec = new stellar_sdk_1.ContractSpec([ - "AAAAAQAAAC9UaGlzIGlzIGZyb20gdGhlIHJ1c3QgZG9jIGFib3ZlIHRoZSBzdHJ1Y3QgVGVzdAAAAAAAAAAABFRlc3QAAAADAAAAAAAAAAFhAAAAAAAABAAAAAAAAAABYgAAAAAAAAEAAAAAAAAAAWMAAAAAAAAR", - "AAAAAgAAAAAAAAAAAAAAClNpbXBsZUVudW0AAAAAAAMAAAAAAAAAAAAAAAVGaXJzdAAAAAAAAAAAAAAAAAAABlNlY29uZAAAAAAAAAAAAAAAAAAFVGhpcmQAAAA=", - "AAAAAwAAAAAAAAAAAAAACVJveWFsQ2FyZAAAAAAAAAMAAAAAAAAABEphY2sAAAALAAAAAAAAAAVRdWVlbgAAAAAAAAwAAAAAAAAABEtpbmcAAAAN", - "AAAAAQAAAAAAAAAAAAAAC1R1cGxlU3RydWN0AAAAAAIAAAAAAAAAATAAAAAAAAfQAAAABFRlc3QAAAAAAAAAATEAAAAAAAfQAAAAClNpbXBsZUVudW0AAA==", - "AAAAAgAAAAAAAAAAAAAAC0NvbXBsZXhFbnVtAAAAAAUAAAABAAAAAAAAAAZTdHJ1Y3QAAAAAAAEAAAfQAAAABFRlc3QAAAABAAAAAAAAAAVUdXBsZQAAAAAAAAEAAAfQAAAAC1R1cGxlU3RydWN0AAAAAAEAAAAAAAAABEVudW0AAAABAAAH0AAAAApTaW1wbGVFbnVtAAAAAAABAAAAAAAAAAVBc3NldAAAAAAAAAIAAAATAAAACwAAAAAAAAAAAAAABFZvaWQ=", - "AAAABAAAAAAAAAAAAAAABUVycm9yAAAAAAAAAQAAABxQbGVhc2UgcHJvdmlkZSBhbiBvZGQgbnVtYmVyAAAAD051bWJlck11c3RCZU9kZAAAAAAB", - "AAAAAAAAAAAAAAAFaGVsbG8AAAAAAAABAAAAAAAAAAVoZWxsbwAAAAAAABEAAAABAAAAEQ==", - "AAAAAAAAAAAAAAAEd29pZAAAAAAAAAAA", - "AAAAAAAAAAAAAAADdmFsAAAAAAAAAAABAAAAAA==", - "AAAAAAAAAAAAAAAQdTMyX2ZhaWxfb25fZXZlbgAAAAEAAAAAAAAABHUzMl8AAAAEAAAAAQAAA+kAAAAEAAAAAw==", - "AAAAAAAAAAAAAAAEdTMyXwAAAAEAAAAAAAAABHUzMl8AAAAEAAAAAQAAAAQ=", - "AAAAAAAAAAAAAAAEaTMyXwAAAAEAAAAAAAAABGkzMl8AAAAFAAAAAQAAAAU=", - "AAAAAAAAAAAAAAAEaTY0XwAAAAEAAAAAAAAABGk2NF8AAAAHAAAAAQAAAAc=", - "AAAAAAAAACxFeGFtcGxlIGNvbnRyYWN0IG1ldGhvZCB3aGljaCB0YWtlcyBhIHN0cnVjdAAAAApzdHJ1a3RfaGVsAAAAAAABAAAAAAAAAAZzdHJ1a3QAAAAAB9AAAAAEVGVzdAAAAAEAAAPqAAAAEQ==", - "AAAAAAAAAAAAAAAGc3RydWt0AAAAAAABAAAAAAAAAAZzdHJ1a3QAAAAAB9AAAAAEVGVzdAAAAAEAAAfQAAAABFRlc3Q=", - "AAAAAAAAAAAAAAAGc2ltcGxlAAAAAAABAAAAAAAAAAZzaW1wbGUAAAAAB9AAAAAKU2ltcGxlRW51bQAAAAAAAQAAB9AAAAAKU2ltcGxlRW51bQAA", - "AAAAAAAAAAAAAAAHY29tcGxleAAAAAABAAAAAAAAAAdjb21wbGV4AAAAB9AAAAALQ29tcGxleEVudW0AAAAAAQAAB9AAAAALQ29tcGxleEVudW0A", - "AAAAAAAAAAAAAAAIYWRkcmVzc2UAAAABAAAAAAAAAAhhZGRyZXNzZQAAABMAAAABAAAAEw==", - "AAAAAAAAAAAAAAAFYnl0ZXMAAAAAAAABAAAAAAAAAAVieXRlcwAAAAAAAA4AAAABAAAADg==", - "AAAAAAAAAAAAAAAHYnl0ZXNfbgAAAAABAAAAAAAAAAdieXRlc19uAAAAA+4AAAAJAAAAAQAAA+4AAAAJ", - "AAAAAAAAAAAAAAAEY2FyZAAAAAEAAAAAAAAABGNhcmQAAAfQAAAACVJveWFsQ2FyZAAAAAAAAAEAAAfQAAAACVJveWFsQ2FyZAAAAA==", - "AAAAAAAAAAAAAAAHYm9vbGVhbgAAAAABAAAAAAAAAAdib29sZWFuAAAAAAEAAAABAAAAAQ==", - "AAAAAAAAABdOZWdhdGVzIGEgYm9vbGVhbiB2YWx1ZQAAAAADbm90AAAAAAEAAAAAAAAAB2Jvb2xlYW4AAAAAAQAAAAEAAAAB", - "AAAAAAAAAAAAAAAEaTEyOAAAAAEAAAAAAAAABGkxMjgAAAALAAAAAQAAAAs=", - "AAAAAAAAAAAAAAAEdTEyOAAAAAEAAAAAAAAABHUxMjgAAAAKAAAAAQAAAAo=", - "AAAAAAAAAAAAAAAKbXVsdGlfYXJncwAAAAAAAgAAAAAAAAABYQAAAAAAAAQAAAAAAAAAAWIAAAAAAAABAAAAAQAAAAQ=", - "AAAAAAAAAAAAAAADbWFwAAAAAAEAAAAAAAAAA21hcAAAAAPsAAAABAAAAAEAAAABAAAD7AAAAAQAAAAB", - "AAAAAAAAAAAAAAADdmVjAAAAAAEAAAAAAAAAA3ZlYwAAAAPqAAAABAAAAAEAAAPqAAAABA==", - "AAAAAAAAAAAAAAAFdHVwbGUAAAAAAAABAAAAAAAAAAV0dXBsZQAAAAAAA+0AAAACAAAAEQAAAAQAAAABAAAD7QAAAAIAAAARAAAABA==", - "AAAAAAAAAB9FeGFtcGxlIG9mIGFuIG9wdGlvbmFsIGFyZ3VtZW50AAAAAAZvcHRpb24AAAAAAAEAAAAAAAAABm9wdGlvbgAAAAAD6AAAAAQAAAABAAAD6AAAAAQ=", - "AAAAAAAAAAAAAAAEdTI1NgAAAAEAAAAAAAAABHUyNTYAAAAMAAAAAQAAAAw=", - "AAAAAAAAAAAAAAAEaTI1NgAAAAEAAAAAAAAABGkyNTYAAAANAAAAAQAAAA0=", - "AAAAAAAAAAAAAAAGc3RyaW5nAAAAAAABAAAAAAAAAAZzdHJpbmcAAAAAABAAAAABAAAAEA==", - "AAAAAAAAAAAAAAAMdHVwbGVfc3RydWt0AAAAAQAAAAAAAAAMdHVwbGVfc3RydWt0AAAH0AAAAAtUdXBsZVN0cnVjdAAAAAABAAAH0AAAAAtUdXBsZVN0cnVjdAA=" - ]); - } - parsers = { - hello: (result) => this.spec.funcResToNative("hello", result), - woid: () => { }, - val: (result) => this.spec.funcResToNative("val", result), - u32FailOnEven: (result) => { - if (result instanceof assembled_tx_js_1.Err) - return result; - return new assembled_tx_js_1.Ok(this.spec.funcResToNative("u32_fail_on_even", result)); - }, - u32: (result) => this.spec.funcResToNative("u32_", result), - i32: (result) => this.spec.funcResToNative("i32_", result), - i64: (result) => this.spec.funcResToNative("i64_", result), - struktHel: (result) => this.spec.funcResToNative("strukt_hel", result), - strukt: (result) => this.spec.funcResToNative("strukt", result), - simple: (result) => this.spec.funcResToNative("simple", result), - complex: (result) => this.spec.funcResToNative("complex", result), - addresse: (result) => this.spec.funcResToNative("addresse", result), - bytes: (result) => this.spec.funcResToNative("bytes", result), - bytesN: (result) => this.spec.funcResToNative("bytes_n", result), - card: (result) => this.spec.funcResToNative("card", result), - boolean: (result) => this.spec.funcResToNative("boolean", result), - not: (result) => this.spec.funcResToNative("not", result), - i128: (result) => this.spec.funcResToNative("i128", result), - u128: (result) => this.spec.funcResToNative("u128", result), - multiArgs: (result) => this.spec.funcResToNative("multi_args", result), - map: (result) => this.spec.funcResToNative("map", result), - vec: (result) => this.spec.funcResToNative("vec", result), - tuple: (result) => this.spec.funcResToNative("tuple", result), - option: (result) => this.spec.funcResToNative("option", result), - u256: (result) => this.spec.funcResToNative("u256", result), - i256: (result) => this.spec.funcResToNative("i256", result), - string: (result) => this.spec.funcResToNative("string", result), - tupleStrukt: (result) => this.spec.funcResToNative("tuple_strukt", result) - }; - txFromJSON = (json) => { - const { method, ...tx } = JSON.parse(json); - return assembled_tx_js_1.AssembledTransaction.fromJSON({ - ...this.options, - method, - parseResultXdr: this.parsers[method], - }, tx); - }; - fromJSON = { - hello: (this.txFromJSON), - woid: (this.txFromJSON), - val: (this.txFromJSON), - u32FailOnEven: (this.txFromJSON), - u32: (this.txFromJSON), - i32: (this.txFromJSON), - i64: (this.txFromJSON), - struktHel: (this.txFromJSON), - strukt: (this.txFromJSON), - simple: (this.txFromJSON), - complex: (this.txFromJSON), - addresse: (this.txFromJSON), - bytes: (this.txFromJSON), - bytesN: (this.txFromJSON), - card: (this.txFromJSON), - boolean: (this.txFromJSON), - not: (this.txFromJSON), - i128: (this.txFromJSON), - u128: (this.txFromJSON), - multiArgs: (this.txFromJSON), - map: (this.txFromJSON), - vec: (this.txFromJSON), - tuple: (this.txFromJSON), - option: (this.txFromJSON), - u256: (this.txFromJSON), - i256: (this.txFromJSON), - string: (this.txFromJSON), - tupleStrukt: (this.txFromJSON) - }; - /** -* Construct and simulate a hello transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - hello = async ({ hello }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'hello', - args: this.spec.funcArgsToScVals("hello", { hello }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['hello'], - }); - }; - /** -* Construct and simulate a woid transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - woid = async (options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'woid', - args: this.spec.funcArgsToScVals("woid", {}), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['woid'], - }); - }; - /** -* Construct and simulate a val transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - val = async (options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'val', - args: this.spec.funcArgsToScVals("val", {}), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['val'], - }); - }; - /** -* Construct and simulate a u32_fail_on_even transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u32FailOnEven = async ({ u32_ }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'u32_fail_on_even', - args: this.spec.funcArgsToScVals("u32_fail_on_even", { u32_ }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['u32FailOnEven'], - }); - }; - /** -* Construct and simulate a u32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u32 = async ({ u32_ }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'u32_', - args: this.spec.funcArgsToScVals("u32_", { u32_ }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['u32'], - }); - }; - /** -* Construct and simulate a i32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i32 = async ({ i32_ }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'i32_', - args: this.spec.funcArgsToScVals("i32_", { i32_ }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['i32'], - }); - }; - /** -* Construct and simulate a i64_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i64 = async ({ i64_ }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'i64_', - args: this.spec.funcArgsToScVals("i64_", { i64_ }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['i64'], - }); - }; - /** -* Construct and simulate a strukt_hel transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example contract method which takes a struct -*/ - struktHel = async ({ strukt }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'strukt_hel', - args: this.spec.funcArgsToScVals("strukt_hel", { strukt }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['struktHel'], - }); - }; - /** -* Construct and simulate a strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - strukt = async ({ strukt }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'strukt', - args: this.spec.funcArgsToScVals("strukt", { strukt }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['strukt'], - }); - }; - /** -* Construct and simulate a simple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - simple = async ({ simple }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'simple', - args: this.spec.funcArgsToScVals("simple", { simple }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['simple'], - }); - }; - /** -* Construct and simulate a complex transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - complex = async ({ complex }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'complex', - args: this.spec.funcArgsToScVals("complex", { complex }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['complex'], - }); - }; - /** -* Construct and simulate a addresse transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - addresse = async ({ addresse }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'addresse', - args: this.spec.funcArgsToScVals("addresse", { addresse: new stellar_sdk_1.Address(addresse) }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['addresse'], - }); - }; - /** -* Construct and simulate a bytes transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - bytes = async ({ bytes }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'bytes', - args: this.spec.funcArgsToScVals("bytes", { bytes }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['bytes'], - }); - }; - /** -* Construct and simulate a bytes_n transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - bytesN = async ({ bytes_n }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'bytes_n', - args: this.spec.funcArgsToScVals("bytes_n", { bytes_n }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['bytesN'], - }); - }; - /** -* Construct and simulate a card transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - card = async ({ card }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'card', - args: this.spec.funcArgsToScVals("card", { card }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['card'], - }); - }; - /** -* Construct and simulate a boolean transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - boolean = async ({ boolean }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'boolean', - args: this.spec.funcArgsToScVals("boolean", { boolean }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['boolean'], - }); - }; - /** -* Construct and simulate a not transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Negates a boolean value -*/ - not = async ({ boolean }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'not', - args: this.spec.funcArgsToScVals("not", { boolean }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['not'], - }); - }; - /** -* Construct and simulate a i128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i128 = async ({ i128 }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'i128', - args: this.spec.funcArgsToScVals("i128", { i128 }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['i128'], - }); - }; - /** -* Construct and simulate a u128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u128 = async ({ u128 }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'u128', - args: this.spec.funcArgsToScVals("u128", { u128 }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['u128'], - }); - }; - /** -* Construct and simulate a multi_args transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - multiArgs = async ({ a, b }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'multi_args', - args: this.spec.funcArgsToScVals("multi_args", { a, b }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['multiArgs'], - }); - }; - /** -* Construct and simulate a map transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - map = async ({ map }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'map', - args: this.spec.funcArgsToScVals("map", { map }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['map'], - }); - }; - /** -* Construct and simulate a vec transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - vec = async ({ vec }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'vec', - args: this.spec.funcArgsToScVals("vec", { vec }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['vec'], - }); - }; - /** -* Construct and simulate a tuple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - tuple = async ({ tuple }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'tuple', - args: this.spec.funcArgsToScVals("tuple", { tuple }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['tuple'], - }); - }; - /** -* Construct and simulate a option transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example of an optional argument -*/ - option = async ({ option }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'option', - args: this.spec.funcArgsToScVals("option", { option }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['option'], - }); - }; - /** -* Construct and simulate a u256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u256 = async ({ u256 }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'u256', - args: this.spec.funcArgsToScVals("u256", { u256 }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['u256'], - }); - }; - /** -* Construct and simulate a i256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i256 = async ({ i256 }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'i256', - args: this.spec.funcArgsToScVals("i256", { i256 }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['i256'], - }); - }; - /** -* Construct and simulate a string transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - string = async ({ string }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'string', - args: this.spec.funcArgsToScVals("string", { string }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['string'], - }); - }; - /** -* Construct and simulate a tuple_strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - tupleStrukt = async ({ tuple_strukt }, options = {}) => { - return await assembled_tx_js_1.AssembledTransaction.fromSimulation({ - method: 'tuple_strukt', - args: this.spec.funcArgsToScVals("tuple_strukt", { tuple_strukt }), - ...options, - ...this.options, - errorTypes: exports.Errors, - parseResultXdr: this.parsers['tupleStrukt'], - }); - }; -} -exports.Contract = Contract; diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/method-options.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/method-options.d.ts deleted file mode 100644 index fc6b21d5..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/method-options.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -declare let responseTypes: 'simulated' | 'full' | undefined; -export type ResponseTypes = typeof responseTypes; -export type XDR_BASE64 = string; -export interface Wallet { - isConnected: () => Promise; - isAllowed: () => Promise; - getUserInfo: () => Promise<{ - publicKey?: string; - }>; - signTransaction: (tx: XDR_BASE64, opts?: { - network?: string; - networkPassphrase?: string; - accountToSign?: string; - }) => Promise; - signAuthEntry: (entryXdr: XDR_BASE64, opts?: { - accountToSign?: string; - }) => Promise; -} -export type ClassOptions = { - contractId: string; - networkPassphrase: string; - rpcUrl: string; - errorTypes?: Record; - /** - * A Wallet interface, such as Freighter, that has the methods `isConnected`, `isAllowed`, `getUserInfo`, and `signTransaction`. If not provided, will attempt to import and use Freighter. Example: - * - * @example - * ```ts - * import freighter from "@stellar/freighter-api"; - * import { Contract } from "test_custom_types"; - * const contract = new Contract({ - * …, - * wallet: freighter, - * }) - * ``` - */ - wallet?: Wallet; -}; -export type MethodOptions = { - /** - * The fee to pay for the transaction. Default: soroban-sdk's BASE_FEE ('100') - */ - fee?: number; -}; -export {}; diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/method-options.js b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/method-options.js deleted file mode 100644 index 6d483ac3..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/method-options.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -// defined this way so typeahead shows full union, not named alias -let responseTypes; diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/assembled-tx.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/assembled-tx.d.ts deleted file mode 100644 index 1d5e6f5e..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/assembled-tx.d.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Account, Address, Operation, SorobanRpc, xdr } from "@stellar/stellar-sdk"; -import type { Memo, MemoType, Transaction } from "@stellar/stellar-sdk"; -import type { ClassOptions, MethodOptions, Wallet, XDR_BASE64 } from "./method-options.js"; -export type Tx = Transaction, Operation[]>; -export declare class ExpiredStateError extends Error { -} -export declare class NeedsMoreSignaturesError extends Error { -} -export declare class WalletDisconnectedError extends Error { -} -export declare class SendResultOnlyError extends Error { -} -export declare class SendFailedError extends Error { -} -export declare class NoUnsignedNonInvokerAuthEntriesError extends Error { -} -type SendTx = SorobanRpc.Api.SendTransactionResponse; -type GetTx = SorobanRpc.Api.GetTransactionResponse; -export type u32 = number; -export type i32 = number; -export type u64 = bigint; -export type i64 = bigint; -export type u128 = bigint; -export type i128 = bigint; -export type u256 = bigint; -export type i256 = bigint; -export type Option = T | undefined; -export type Typepoint = bigint; -export type Duration = bigint; -export { Address }; -export interface Error_ { - message: string; -} -export interface Result { - unwrap(): T; - unwrapErr(): E; - isOk(): boolean; - isErr(): boolean; -} -export declare class Ok implements Result { - readonly value: T; - constructor(value: T); - unwrapErr(): E; - unwrap(): T; - isOk(): boolean; - isErr(): boolean; -} -export declare class Err implements Result { - readonly error: E; - constructor(error: E); - unwrapErr(): E; - unwrap(): never; - isOk(): boolean; - isErr(): boolean; -} -export declare const contractErrorPattern: RegExp; -type AssembledTransactionOptions = MethodOptions & ClassOptions & { - method: string; - args?: any[]; - parseResultXdr: (xdr: string | xdr.ScVal | Err) => T; -}; -export declare const NULL_ACCOUNT = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF"; -export declare class AssembledTransaction { - options: AssembledTransactionOptions; - raw: Tx; - private simulation?; - private simulationResult?; - private simulationTransactionData?; - private server; - toJSON(): string; - static fromJSON(options: Omit, 'args'>, { tx, simulationResult, simulationTransactionData }: { - tx: XDR_BASE64; - simulationResult: { - auth: XDR_BASE64[]; - retval: XDR_BASE64; - }; - simulationTransactionData: XDR_BASE64; - }): AssembledTransaction; - private constructor(); - static fromSimulation(options: AssembledTransactionOptions): Promise>; - simulate: () => Promise; - get simulationData(): { - result: SorobanRpc.Api.SimulateHostFunctionResult; - transactionData: xdr.SorobanTransactionData; - }; - get result(): T; - parseError(errorMessage: string): Err | undefined; - getWallet: () => Promise; - getPublicKey: () => Promise; - /** - * Get account details from the Soroban network for the publicKey currently - * selected in user's wallet. If not connected to Freighter, use placeholder - * null account. - */ - getAccount: () => Promise; - /** - * Sign the transaction with the `wallet` (default Freighter), then send to - * the network and return a `SentTransaction` that keeps track of all the - * attempts to send and fetch the transaction from the network. - */ - signAndSend: ({ secondsToWait, force }?: { - /** - * Wait `secondsToWait` seconds (default: 10) for both the transaction to SEND successfully (will keep trying if the server returns `TRY_AGAIN_LATER`), as well as for the transaction to COMPLETE (will keep checking if the server returns `PENDING`). - */ - secondsToWait?: number | undefined; - /** - * If `true`, sign and send the transaction even if it is a read call. - */ - force?: boolean | undefined; - }) => Promise>; - getStorageExpiration: () => Promise; - /** - * Get a list of accounts, other than the invoker of the simulation, that - * need to sign auth entries in this transaction. - * - * Soroban allows multiple people to sign a transaction. Someone needs to - * sign the final transaction envelope; this person/account is called the - * _invoker_, or _source_. Other accounts might need to sign individual auth - * entries in the transaction, if they're not also the invoker. - * - * This function returns a list of accounts that need to sign auth entries, - * assuming that the same invoker/source account will sign the final - * transaction envelope as signed the initial simulation. - * - * One at a time, for each public key in this array, you will need to - * serialize this transaction with `toJSON`, send to the owner of that key, - * deserialize the transaction with `txFromJson`, and call - * {@link signAuthEntries}. Then re-serialize and send to the next account - * in this list. - */ - needsNonInvokerSigningBy: ({ includeAlreadySigned, }?: { - /** - * Whether or not to include auth entries that have already been signed. Default: false - */ - includeAlreadySigned?: boolean | undefined; - }) => Promise; - preImageFor(entry: xdr.SorobanAuthorizationEntry, signatureExpirationLedger: number): xdr.HashIdPreimage; - /** - * If {@link needsNonInvokerSigningBy} returns a non-empty list, you can serialize - * the transaction with `toJSON`, send it to the owner of one of the public keys - * in the map, deserialize with `txFromJSON`, and call this method on their - * machine. Internally, this will use `signAuthEntry` function from connected - * `wallet` for each. - * - * Then, re-serialize the transaction and either send to the next - * `needsNonInvokerSigningBy` owner, or send it back to the original account - * who simulated the transaction so they can {@link sign} the transaction - * envelope and {@link send} it to the network. - * - * Sending to all `needsNonInvokerSigningBy` owners in parallel is not currently - * supported! - */ - signAuthEntries: (expiration?: number | Promise) => Promise; - get isReadCall(): boolean; - hasRealInvoker: () => Promise; -} -/** - * A transaction that has been sent to the Soroban network. This happens in two steps: - * - * 1. `sendTransaction`: initial submission of the transaction to the network. - * This step can run into problems, and will be retried with exponential - * backoff if it does. See all attempts in `sendTransactionResponseAll` and the - * most recent attempt in `sendTransactionResponse`. - * 2. `getTransaction`: once the transaction has been submitted to the network - * successfully, you need to wait for it to finalize to get the results of the - * transaction. This step can also run into problems, and will be retried with - * exponential backoff if it does. See all attempts in - * `getTransactionResponseAll` and the most recent attempt in - * `getTransactionResponse`. - */ -declare class SentTransaction { - options: AssembledTransactionOptions; - assembled: AssembledTransaction; - server: SorobanRpc.Server; - signed: Tx; - sendTransactionResponse?: SendTx; - sendTransactionResponseAll?: SendTx[]; - getTransactionResponse?: GetTx; - getTransactionResponseAll?: GetTx[]; - constructor(options: AssembledTransactionOptions, assembled: AssembledTransaction); - static init: (options: AssembledTransactionOptions, assembled: AssembledTransaction, secondsToWait?: number) => Promise>; - private send; - get result(): T; -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/assembled-tx.js b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/assembled-tx.js deleted file mode 100644 index 79b7c01d..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/assembled-tx.js +++ /dev/null @@ -1,450 +0,0 @@ -import { Account, Address, Contract, Operation, SorobanRpc, StrKey, TimeoutInfinite, TransactionBuilder, authorizeEntry, hash, xdr, BASE_FEE, } from "@stellar/stellar-sdk"; -import { Buffer } from "buffer"; -export class ExpiredStateError extends Error { -} -export class NeedsMoreSignaturesError extends Error { -} -export class WalletDisconnectedError extends Error { -} -export class SendResultOnlyError extends Error { -} -export class SendFailedError extends Error { -} -export class NoUnsignedNonInvokerAuthEntriesError extends Error { -} -export { Address }; -; -; -export class Ok { - value; - constructor(value) { - this.value = value; - } - unwrapErr() { - throw new Error('No error'); - } - unwrap() { - return this.value; - } - isOk() { - return true; - } - isErr() { - return !this.isOk(); - } -} -export class Err { - error; - constructor(error) { - this.error = error; - } - unwrapErr() { - return this.error; - } - unwrap() { - throw new Error(this.error.message); - } - isOk() { - return false; - } - isErr() { - return !this.isOk(); - } -} -export const contractErrorPattern = /Error\(Contract, #(\d+)\)/; -export const NULL_ACCOUNT = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF"; -export class AssembledTransaction { - options; - raw; - simulation; - simulationResult; - simulationTransactionData; - server; - toJSON() { - return JSON.stringify({ - method: this.options.method, - tx: this.raw?.toXDR(), - simulationResult: { - auth: this.simulationData.result.auth.map(a => a.toXDR('base64')), - retval: this.simulationData.result.retval.toXDR('base64'), - }, - simulationTransactionData: this.simulationData.transactionData.toXDR('base64'), - }); - } - static fromJSON(options, { tx, simulationResult, simulationTransactionData }) { - const txn = new AssembledTransaction(options); - txn.raw = TransactionBuilder.fromXDR(tx, options.networkPassphrase); - txn.simulationResult = { - auth: simulationResult.auth.map(a => xdr.SorobanAuthorizationEntry.fromXDR(a, 'base64')), - retval: xdr.ScVal.fromXDR(simulationResult.retval, 'base64'), - }; - txn.simulationTransactionData = xdr.SorobanTransactionData.fromXDR(simulationTransactionData, 'base64'); - return txn; - } - constructor(options) { - this.options = options; - this.server = new SorobanRpc.Server(this.options.rpcUrl, { - allowHttp: this.options.rpcUrl.startsWith("http://"), - }); - } - static async fromSimulation(options) { - const tx = new AssembledTransaction(options); - const contract = new Contract(options.contractId); - tx.raw = new TransactionBuilder(await tx.getAccount(), { - fee: options.fee?.toString(10) ?? BASE_FEE, - networkPassphrase: options.networkPassphrase, - }) - .addOperation(contract.call(options.method, ...(options.args ?? []))) - .setTimeout(TimeoutInfinite) - .build(); - return await tx.simulate(); - } - simulate = async () => { - if (!this.raw) - throw new Error('Transaction has not yet been assembled'); - this.simulation = await this.server.simulateTransaction(this.raw); - if (SorobanRpc.Api.isSimulationSuccess(this.simulation)) { - this.raw = SorobanRpc.assembleTransaction(this.raw, this.simulation).build(); - } - return this; - }; - get simulationData() { - if (this.simulationResult && this.simulationTransactionData) { - return { - result: this.simulationResult, - transactionData: this.simulationTransactionData, - }; - } - // else, we know we just did the simulation on this machine - const simulation = this.simulation; - if (SorobanRpc.Api.isSimulationError(simulation)) { - throw new Error(`Transaction simulation failed: "${simulation.error}"`); - } - if (SorobanRpc.Api.isSimulationRestore(simulation)) { - throw new ExpiredStateError(`You need to restore some contract state before you can invoke this method. ${JSON.stringify(simulation, null, 2)}`); - } - if (!simulation.result) { - throw new Error(`Expected an invocation simulation, but got no 'result' field. Simulation: ${JSON.stringify(simulation, null, 2)}`); - } - // add to object for serialization & deserialization - this.simulationResult = simulation.result; - this.simulationTransactionData = simulation.transactionData.build(); - return { - result: this.simulationResult, - transactionData: this.simulationTransactionData, - }; - } - get result() { - try { - return this.options.parseResultXdr(this.simulationData.result.retval); - } - catch (e) { - let err = this.parseError(e.toString()); - if (err) - return err; - throw e; - } - } - parseError(errorMessage) { - if (!this.options.errorTypes) - return; - const match = errorMessage.match(contractErrorPattern); - if (!match) - return; - let i = parseInt(match[1], 10); - let err = this.options.errorTypes[i]; - if (err) - return new Err(err); - } - getWallet = async () => { - return this.options.wallet ?? (await import("@stellar/freighter-api")).default; - }; - getPublicKey = async () => { - const wallet = await this.getWallet(); - if (await wallet.isConnected() && await wallet.isAllowed()) { - return (await wallet.getUserInfo()).publicKey; - } - }; - /** - * Get account details from the Soroban network for the publicKey currently - * selected in user's wallet. If not connected to Freighter, use placeholder - * null account. - */ - getAccount = async () => { - const publicKey = await this.getPublicKey(); - return publicKey - ? await this.server.getAccount(publicKey) - : new Account(NULL_ACCOUNT, "0"); - }; - /** - * Sign the transaction with the `wallet` (default Freighter), then send to - * the network and return a `SentTransaction` that keeps track of all the - * attempts to send and fetch the transaction from the network. - */ - signAndSend = async ({ secondsToWait = 10, force = false } = {}) => { - if (!this.raw) { - throw new Error('Transaction has not yet been simulated'); - } - if (!force && this.isReadCall) { - throw new Error('This is a read call. It requires no signature or sending. Use `force: true` to sign and send anyway.'); - } - if (!await this.hasRealInvoker()) { - throw new WalletDisconnectedError('Wallet is not connected'); - } - if (this.raw.source !== (await this.getAccount()).accountId()) { - throw new Error(`You must submit the transaction with the account that originally created it. Please switch to the wallet with "${this.raw.source}" as its public key.`); - } - if ((await this.needsNonInvokerSigningBy()).length) { - throw new NeedsMoreSignaturesError('Transaction requires more signatures. See `needsNonInvokerSigningBy` for details.'); - } - return await SentTransaction.init(this.options, this, secondsToWait); - }; - getStorageExpiration = async () => { - const entryRes = await this.server.getLedgerEntries(new Contract(this.options.contractId).getFootprint()); - if (!entryRes.entries || - !entryRes.entries.length || - !entryRes.entries[0].liveUntilLedgerSeq) - throw new Error('failed to get ledger entry'); - return entryRes.entries[0].liveUntilLedgerSeq; - }; - /** - * Get a list of accounts, other than the invoker of the simulation, that - * need to sign auth entries in this transaction. - * - * Soroban allows multiple people to sign a transaction. Someone needs to - * sign the final transaction envelope; this person/account is called the - * _invoker_, or _source_. Other accounts might need to sign individual auth - * entries in the transaction, if they're not also the invoker. - * - * This function returns a list of accounts that need to sign auth entries, - * assuming that the same invoker/source account will sign the final - * transaction envelope as signed the initial simulation. - * - * One at a time, for each public key in this array, you will need to - * serialize this transaction with `toJSON`, send to the owner of that key, - * deserialize the transaction with `txFromJson`, and call - * {@link signAuthEntries}. Then re-serialize and send to the next account - * in this list. - */ - needsNonInvokerSigningBy = async ({ includeAlreadySigned = false, } = {}) => { - if (!this.raw) { - throw new Error('Transaction has not yet been simulated'); - } - // We expect that any transaction constructed by these libraries has a - // single operation, which is an InvokeHostFunction operation. The host - // function being invoked is the contract method call. - if (!("operations" in this.raw)) { - throw new Error(`Unexpected Transaction type; no operations: ${JSON.stringify(this.raw)}`); - } - const rawInvokeHostFunctionOp = this.raw - .operations[0]; - return [...new Set((rawInvokeHostFunctionOp.auth ?? []).filter(entry => entry.credentials().switch() === - xdr.SorobanCredentialsType.sorobanCredentialsAddress() && - (includeAlreadySigned || - entry.credentials().address().signature().switch().name === 'scvVoid')).map(entry => StrKey.encodeEd25519PublicKey(entry.credentials().address().address().accountId().ed25519())))]; - }; - preImageFor(entry, signatureExpirationLedger) { - const addrAuth = entry.credentials().address(); - return xdr.HashIdPreimage.envelopeTypeSorobanAuthorization(new xdr.HashIdPreimageSorobanAuthorization({ - networkId: hash(Buffer.from(this.options.networkPassphrase)), - nonce: addrAuth.nonce(), - invocation: entry.rootInvocation(), - signatureExpirationLedger, - })); - } - /** - * If {@link needsNonInvokerSigningBy} returns a non-empty list, you can serialize - * the transaction with `toJSON`, send it to the owner of one of the public keys - * in the map, deserialize with `txFromJSON`, and call this method on their - * machine. Internally, this will use `signAuthEntry` function from connected - * `wallet` for each. - * - * Then, re-serialize the transaction and either send to the next - * `needsNonInvokerSigningBy` owner, or send it back to the original account - * who simulated the transaction so they can {@link sign} the transaction - * envelope and {@link send} it to the network. - * - * Sending to all `needsNonInvokerSigningBy` owners in parallel is not currently - * supported! - */ - signAuthEntries = async ( - /** - * When to set each auth entry to expire. Could be any number of blocks in - * the future. Can be supplied as a promise or a raw number. Default: - * contract's current `persistent` storage expiration date/ledger - * number/block. - */ - expiration = this.getStorageExpiration()) => { - if (!this.raw) - throw new Error('Transaction has not yet been assembled or simulated'); - const needsNonInvokerSigningBy = await this.needsNonInvokerSigningBy(); - if (!needsNonInvokerSigningBy) - throw new NoUnsignedNonInvokerAuthEntriesError('No unsigned non-invoker auth entries; maybe you already signed?'); - const publicKey = await this.getPublicKey(); - if (!publicKey) - throw new Error('Could not get public key from wallet; maybe Freighter is not signed in?'); - if (needsNonInvokerSigningBy.indexOf(publicKey) === -1) - throw new Error(`No auth entries for public key "${publicKey}"`); - const wallet = await this.getWallet(); - const rawInvokeHostFunctionOp = this.raw - .operations[0]; - const authEntries = rawInvokeHostFunctionOp.auth ?? []; - for (const [i, entry] of authEntries.entries()) { - if (entry.credentials().switch() !== - xdr.SorobanCredentialsType.sorobanCredentialsAddress()) { - // if the invoker/source account, then the entry doesn't need explicit - // signature, since the tx envelope is already signed by the source - // account, so only check for sorobanCredentialsAddress - continue; - } - const pk = StrKey.encodeEd25519PublicKey(entry.credentials().address().address().accountId().ed25519()); - // this auth entry needs to be signed by a different account - // (or maybe already was!) - if (pk !== publicKey) - continue; - authEntries[i] = await authorizeEntry(entry, async (preimage) => Buffer.from(await wallet.signAuthEntry(preimage.toXDR('base64')), 'base64'), await expiration, this.options.networkPassphrase); - } - }; - get isReadCall() { - const authsCount = this.simulationData.result.auth.length; - const writeLength = this.simulationData.transactionData.resources().footprint().readWrite().length; - return (authsCount === 0) && (writeLength === 0); - } - hasRealInvoker = async () => { - const account = await this.getAccount(); - return account.accountId() !== NULL_ACCOUNT; - }; -} -/** - * A transaction that has been sent to the Soroban network. This happens in two steps: - * - * 1. `sendTransaction`: initial submission of the transaction to the network. - * This step can run into problems, and will be retried with exponential - * backoff if it does. See all attempts in `sendTransactionResponseAll` and the - * most recent attempt in `sendTransactionResponse`. - * 2. `getTransaction`: once the transaction has been submitted to the network - * successfully, you need to wait for it to finalize to get the results of the - * transaction. This step can also run into problems, and will be retried with - * exponential backoff if it does. See all attempts in - * `getTransactionResponseAll` and the most recent attempt in - * `getTransactionResponse`. - */ -class SentTransaction { - options; - assembled; - server; - signed; - sendTransactionResponse; - sendTransactionResponseAll; - getTransactionResponse; - getTransactionResponseAll; - constructor(options, assembled) { - this.options = options; - this.assembled = assembled; - this.server = new SorobanRpc.Server(this.options.rpcUrl, { - allowHttp: this.options.rpcUrl.startsWith("http://"), - }); - this.assembled = assembled; - } - static init = async (options, assembled, secondsToWait = 10) => { - const tx = new SentTransaction(options, assembled); - return await tx.send(secondsToWait); - }; - send = async (secondsToWait = 10) => { - const wallet = await this.assembled.getWallet(); - this.sendTransactionResponseAll = await withExponentialBackoff(async (previousFailure) => { - if (previousFailure) { - // Increment transaction sequence number and resimulate before trying again - // Soroban transaction can only have 1 operation - const op = this.assembled.raw.operations[0]; - this.assembled.raw = new TransactionBuilder(await this.assembled.getAccount(), { - fee: this.assembled.raw.fee, - networkPassphrase: this.options.networkPassphrase, - }) - .setTimeout(TimeoutInfinite) - .addOperation(Operation.invokeHostFunction({ ...op, auth: op.auth ?? [] })) - .build(); - await this.assembled.simulate(); - } - const signature = await wallet.signTransaction(this.assembled.raw.toXDR(), { - networkPassphrase: this.options.networkPassphrase, - }); - this.signed = TransactionBuilder.fromXDR(signature, this.options.networkPassphrase); - return this.server.sendTransaction(this.signed); - }, resp => resp.status !== "PENDING", secondsToWait); - this.sendTransactionResponse = this.sendTransactionResponseAll[this.sendTransactionResponseAll.length - 1]; - if (this.sendTransactionResponse.status !== "PENDING") { - throw new Error(`Tried to resubmit transaction for ${secondsToWait} seconds, but it's still failing. ` + - `All attempts: ${JSON.stringify(this.sendTransactionResponseAll, null, 2)}`); - } - const { hash } = this.sendTransactionResponse; - this.getTransactionResponseAll = await withExponentialBackoff(() => this.server.getTransaction(hash), resp => resp.status === SorobanRpc.Api.GetTransactionStatus.NOT_FOUND, secondsToWait); - this.getTransactionResponse = this.getTransactionResponseAll[this.getTransactionResponseAll.length - 1]; - if (this.getTransactionResponse.status === SorobanRpc.Api.GetTransactionStatus.NOT_FOUND) { - console.error(`Waited ${secondsToWait} seconds for transaction to complete, but it did not. ` + - `Returning anyway. Check the transaction status manually. ` + - `Sent transaction: ${JSON.stringify(this.sendTransactionResponse, null, 2)}\n` + - `All attempts to get the result: ${JSON.stringify(this.getTransactionResponseAll, null, 2)}`); - } - return this; - }; - get result() { - // 1. check if transaction was submitted and awaited with `getTransaction` - if ("getTransactionResponse" in this && - this.getTransactionResponse) { - // getTransactionResponse has a `returnValue` field unless it failed - if ("returnValue" in this.getTransactionResponse) { - return this.options.parseResultXdr(this.getTransactionResponse.returnValue); - } - // if "returnValue" not present, the transaction failed; return without parsing the result - throw new Error("Transaction failed! Cannot parse result."); - } - // 2. otherwise, maybe it was merely sent with `sendTransaction` - if (this.sendTransactionResponse) { - const errorResult = this.sendTransactionResponse.errorResult?.result(); - if (errorResult) { - throw new SendFailedError(`Transaction simulation looked correct, but attempting to send the transaction failed. Check \`simulation\` and \`sendTransactionResponseAll\` to troubleshoot. Decoded \`sendTransactionResponse.errorResultXdr\`: ${errorResult}`); - } - throw new SendResultOnlyError(`Transaction was sent to the network, but not yet awaited. No result to show. Await transaction completion with \`getTransaction(sendTransactionResponse.hash)\``); - } - // 3. finally, if neither of those are present, throw an error - throw new Error(`Sending transaction failed: ${JSON.stringify(this.assembled)}`); - } -} -/** - * Keep calling a `fn` for `secondsToWait` seconds, if `keepWaitingIf` is true. - * Returns an array of all attempts to call the function. - */ -async function withExponentialBackoff(fn, keepWaitingIf, secondsToWait, exponentialFactor = 1.5, verbose = false) { - const attempts = []; - let count = 0; - attempts.push(await fn()); - if (!keepWaitingIf(attempts[attempts.length - 1])) - return attempts; - const waitUntil = new Date(Date.now() + secondsToWait * 1000).valueOf(); - let waitTime = 1000; - let totalWaitTime = waitTime; - while (Date.now() < waitUntil && keepWaitingIf(attempts[attempts.length - 1])) { - count++; - // Wait a beat - if (verbose) { - console.info(`Waiting ${waitTime}ms before trying again (bringing the total wait time to ${totalWaitTime}ms so far, of total ${secondsToWait * 1000}ms)`); - } - await new Promise(res => setTimeout(res, waitTime)); - // Exponential backoff - waitTime = waitTime * exponentialFactor; - if (new Date(Date.now() + waitTime).valueOf() > waitUntil) { - waitTime = waitUntil - Date.now(); - if (verbose) { - console.info(`was gonna wait too long; new waitTime: ${waitTime}ms`); - } - } - totalWaitTime = waitTime + totalWaitTime; - // Try again - attempts.push(await fn(attempts[attempts.length - 1])); - if (verbose && keepWaitingIf(attempts[attempts.length - 1])) { - console.info(`${count}. Called ${fn}; ${attempts.length} prev attempts. Most recent: ${JSON.stringify(attempts[attempts.length - 1], null, 2)}`); - } - } - return attempts; -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.d.ts deleted file mode 100644 index 66d3d595..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.d.ts +++ /dev/null @@ -1,424 +0,0 @@ -import { ContractSpec } from '@stellar/stellar-sdk'; -import { Buffer } from "buffer"; -import { AssembledTransaction, Ok, Err } from './assembled-tx.js'; -import type { u32, i32, i64, i128, Option, Error_ } from './assembled-tx.js'; -import type { ClassOptions } from './method-options.js'; -export * from './assembled-tx.js'; -export * from './method-options.js'; -export declare const networks: { - readonly futurenet: { - readonly networkPassphrase: "Test SDF Future Network ; October 2022"; - readonly contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK"; - }; -}; -/** - This is from the rust doc above the struct Test - */ -export interface Test { - /** - - */ - a: u32; - /** - - */ - b: boolean; - /** - - */ - c: string; -} -/** - - */ -export type SimpleEnum = { - tag: "First"; - values: void; -} | { - tag: "Second"; - values: void; -} | { - tag: "Third"; - values: void; -}; -/** - - */ -export declare enum RoyalCard { - Jack = 11, - Queen = 12, - King = 13 -} -/** - - */ -export type TupleStruct = readonly [Test, SimpleEnum]; -/** - - */ -export type ComplexEnum = { - tag: "Struct"; - values: readonly [Test]; -} | { - tag: "Tuple"; - values: readonly [TupleStruct]; -} | { - tag: "Enum"; - values: readonly [SimpleEnum]; -} | { - tag: "Asset"; - values: readonly [string, i128]; -} | { - tag: "Void"; - values: void; -}; -/** - - */ -export declare const Errors: { - 1: { - message: string; - }; -}; -export declare class Contract { - readonly options: ClassOptions; - spec: ContractSpec; - constructor(options: ClassOptions); - private readonly parsers; - private txFromJSON; - readonly fromJSON: { - hello: (json: string) => AssembledTransaction; - woid: (json: string) => AssembledTransaction; - val: (json: string) => AssembledTransaction; - u32FailOnEven: (json: string) => AssembledTransaction | Ok>; - u32: (json: string) => AssembledTransaction; - i32: (json: string) => AssembledTransaction; - i64: (json: string) => AssembledTransaction; - struktHel: (json: string) => AssembledTransaction; - strukt: (json: string) => AssembledTransaction; - simple: (json: string) => AssembledTransaction; - complex: (json: string) => AssembledTransaction; - addresse: (json: string) => AssembledTransaction; - bytes: (json: string) => AssembledTransaction; - bytesN: (json: string) => AssembledTransaction; - card: (json: string) => AssembledTransaction; - boolean: (json: string) => AssembledTransaction; - not: (json: string) => AssembledTransaction; - i128: (json: string) => AssembledTransaction; - u128: (json: string) => AssembledTransaction; - multiArgs: (json: string) => AssembledTransaction; - map: (json: string) => AssembledTransaction>; - vec: (json: string) => AssembledTransaction; - tuple: (json: string) => AssembledTransaction; - option: (json: string) => AssembledTransaction>; - u256: (json: string) => AssembledTransaction; - i256: (json: string) => AssembledTransaction; - string: (json: string) => AssembledTransaction; - tupleStrukt: (json: string) => AssembledTransaction; - }; - /** -* Construct and simulate a hello transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - hello: ({ hello }: { - hello: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a woid transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - woid: (options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a val transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - val: (options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a u32_fail_on_even transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u32FailOnEven: ({ u32_ }: { - u32_: u32; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise | Ok>>; - /** -* Construct and simulate a u32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u32: ({ u32_ }: { - u32_: u32; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i32: ({ i32_ }: { - i32_: i32; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i64_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i64: ({ i64_ }: { - i64_: i64; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a strukt_hel transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example contract method which takes a struct -*/ - struktHel: ({ strukt }: { - strukt: Test; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - strukt: ({ strukt }: { - strukt: Test; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a simple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - simple: ({ simple }: { - simple: SimpleEnum; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a complex transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - complex: ({ complex }: { - complex: ComplexEnum; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a addresse transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - addresse: ({ addresse }: { - addresse: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a bytes transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - bytes: ({ bytes }: { - bytes: Buffer; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a bytes_n transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - bytesN: ({ bytes_n }: { - bytes_n: Buffer; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a card transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - card: ({ card }: { - card: RoyalCard; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a boolean transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - boolean: ({ boolean }: { - boolean: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a not transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Negates a boolean value -*/ - not: ({ boolean }: { - boolean: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i128: ({ i128 }: { - i128: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a u128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u128: ({ u128 }: { - u128: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a multi_args transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - multiArgs: ({ a, b }: { - a: u32; - b: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a map transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - map: ({ map }: { - map: Map; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>>; - /** -* Construct and simulate a vec transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - vec: ({ vec }: { - vec: Array; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a tuple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - tuple: ({ tuple }: { - tuple: readonly [string, u32]; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a option transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example of an optional argument -*/ - option: ({ option }: { - option: Option; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>>; - /** -* Construct and simulate a u256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u256: ({ u256 }: { - u256: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i256: ({ i256 }: { - i256: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a string transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - string: ({ string }: { - string: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a tuple_strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - tupleStrukt: ({ tuple_strukt }: { - tuple_strukt: TupleStruct; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.js b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.js deleted file mode 100644 index b97cff55..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.js +++ /dev/null @@ -1,509 +0,0 @@ -import { ContractSpec, Address } from '@stellar/stellar-sdk'; -import { Buffer } from "buffer"; -import { AssembledTransaction, Ok, Err } from './assembled-tx.js'; -export * from './assembled-tx.js'; -export * from './method-options.js'; -if (typeof window !== 'undefined') { - //@ts-ignore Buffer exists - window.Buffer = window.Buffer || Buffer; -} -export const networks = { - futurenet: { - networkPassphrase: "Test SDF Future Network ; October 2022", - contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK", - } -}; -/** - - */ -export var RoyalCard; -(function (RoyalCard) { - RoyalCard[RoyalCard["Jack"] = 11] = "Jack"; - RoyalCard[RoyalCard["Queen"] = 12] = "Queen"; - RoyalCard[RoyalCard["King"] = 13] = "King"; -})(RoyalCard || (RoyalCard = {})); -/** - - */ -export const Errors = { - 1: { message: "Please provide an odd number" } -}; -export class Contract { - options; - spec; - constructor(options) { - this.options = options; - this.spec = new ContractSpec([ - "AAAAAQAAAC9UaGlzIGlzIGZyb20gdGhlIHJ1c3QgZG9jIGFib3ZlIHRoZSBzdHJ1Y3QgVGVzdAAAAAAAAAAABFRlc3QAAAADAAAAAAAAAAFhAAAAAAAABAAAAAAAAAABYgAAAAAAAAEAAAAAAAAAAWMAAAAAAAAR", - "AAAAAgAAAAAAAAAAAAAAClNpbXBsZUVudW0AAAAAAAMAAAAAAAAAAAAAAAVGaXJzdAAAAAAAAAAAAAAAAAAABlNlY29uZAAAAAAAAAAAAAAAAAAFVGhpcmQAAAA=", - "AAAAAwAAAAAAAAAAAAAACVJveWFsQ2FyZAAAAAAAAAMAAAAAAAAABEphY2sAAAALAAAAAAAAAAVRdWVlbgAAAAAAAAwAAAAAAAAABEtpbmcAAAAN", - "AAAAAQAAAAAAAAAAAAAAC1R1cGxlU3RydWN0AAAAAAIAAAAAAAAAATAAAAAAAAfQAAAABFRlc3QAAAAAAAAAATEAAAAAAAfQAAAAClNpbXBsZUVudW0AAA==", - "AAAAAgAAAAAAAAAAAAAAC0NvbXBsZXhFbnVtAAAAAAUAAAABAAAAAAAAAAZTdHJ1Y3QAAAAAAAEAAAfQAAAABFRlc3QAAAABAAAAAAAAAAVUdXBsZQAAAAAAAAEAAAfQAAAAC1R1cGxlU3RydWN0AAAAAAEAAAAAAAAABEVudW0AAAABAAAH0AAAAApTaW1wbGVFbnVtAAAAAAABAAAAAAAAAAVBc3NldAAAAAAAAAIAAAATAAAACwAAAAAAAAAAAAAABFZvaWQ=", - "AAAABAAAAAAAAAAAAAAABUVycm9yAAAAAAAAAQAAABxQbGVhc2UgcHJvdmlkZSBhbiBvZGQgbnVtYmVyAAAAD051bWJlck11c3RCZU9kZAAAAAAB", - "AAAAAAAAAAAAAAAFaGVsbG8AAAAAAAABAAAAAAAAAAVoZWxsbwAAAAAAABEAAAABAAAAEQ==", - "AAAAAAAAAAAAAAAEd29pZAAAAAAAAAAA", - "AAAAAAAAAAAAAAADdmFsAAAAAAAAAAABAAAAAA==", - "AAAAAAAAAAAAAAAQdTMyX2ZhaWxfb25fZXZlbgAAAAEAAAAAAAAABHUzMl8AAAAEAAAAAQAAA+kAAAAEAAAAAw==", - "AAAAAAAAAAAAAAAEdTMyXwAAAAEAAAAAAAAABHUzMl8AAAAEAAAAAQAAAAQ=", - "AAAAAAAAAAAAAAAEaTMyXwAAAAEAAAAAAAAABGkzMl8AAAAFAAAAAQAAAAU=", - "AAAAAAAAAAAAAAAEaTY0XwAAAAEAAAAAAAAABGk2NF8AAAAHAAAAAQAAAAc=", - "AAAAAAAAACxFeGFtcGxlIGNvbnRyYWN0IG1ldGhvZCB3aGljaCB0YWtlcyBhIHN0cnVjdAAAAApzdHJ1a3RfaGVsAAAAAAABAAAAAAAAAAZzdHJ1a3QAAAAAB9AAAAAEVGVzdAAAAAEAAAPqAAAAEQ==", - "AAAAAAAAAAAAAAAGc3RydWt0AAAAAAABAAAAAAAAAAZzdHJ1a3QAAAAAB9AAAAAEVGVzdAAAAAEAAAfQAAAABFRlc3Q=", - "AAAAAAAAAAAAAAAGc2ltcGxlAAAAAAABAAAAAAAAAAZzaW1wbGUAAAAAB9AAAAAKU2ltcGxlRW51bQAAAAAAAQAAB9AAAAAKU2ltcGxlRW51bQAA", - "AAAAAAAAAAAAAAAHY29tcGxleAAAAAABAAAAAAAAAAdjb21wbGV4AAAAB9AAAAALQ29tcGxleEVudW0AAAAAAQAAB9AAAAALQ29tcGxleEVudW0A", - "AAAAAAAAAAAAAAAIYWRkcmVzc2UAAAABAAAAAAAAAAhhZGRyZXNzZQAAABMAAAABAAAAEw==", - "AAAAAAAAAAAAAAAFYnl0ZXMAAAAAAAABAAAAAAAAAAVieXRlcwAAAAAAAA4AAAABAAAADg==", - "AAAAAAAAAAAAAAAHYnl0ZXNfbgAAAAABAAAAAAAAAAdieXRlc19uAAAAA+4AAAAJAAAAAQAAA+4AAAAJ", - "AAAAAAAAAAAAAAAEY2FyZAAAAAEAAAAAAAAABGNhcmQAAAfQAAAACVJveWFsQ2FyZAAAAAAAAAEAAAfQAAAACVJveWFsQ2FyZAAAAA==", - "AAAAAAAAAAAAAAAHYm9vbGVhbgAAAAABAAAAAAAAAAdib29sZWFuAAAAAAEAAAABAAAAAQ==", - "AAAAAAAAABdOZWdhdGVzIGEgYm9vbGVhbiB2YWx1ZQAAAAADbm90AAAAAAEAAAAAAAAAB2Jvb2xlYW4AAAAAAQAAAAEAAAAB", - "AAAAAAAAAAAAAAAEaTEyOAAAAAEAAAAAAAAABGkxMjgAAAALAAAAAQAAAAs=", - "AAAAAAAAAAAAAAAEdTEyOAAAAAEAAAAAAAAABHUxMjgAAAAKAAAAAQAAAAo=", - "AAAAAAAAAAAAAAAKbXVsdGlfYXJncwAAAAAAAgAAAAAAAAABYQAAAAAAAAQAAAAAAAAAAWIAAAAAAAABAAAAAQAAAAQ=", - "AAAAAAAAAAAAAAADbWFwAAAAAAEAAAAAAAAAA21hcAAAAAPsAAAABAAAAAEAAAABAAAD7AAAAAQAAAAB", - "AAAAAAAAAAAAAAADdmVjAAAAAAEAAAAAAAAAA3ZlYwAAAAPqAAAABAAAAAEAAAPqAAAABA==", - "AAAAAAAAAAAAAAAFdHVwbGUAAAAAAAABAAAAAAAAAAV0dXBsZQAAAAAAA+0AAAACAAAAEQAAAAQAAAABAAAD7QAAAAIAAAARAAAABA==", - "AAAAAAAAAB9FeGFtcGxlIG9mIGFuIG9wdGlvbmFsIGFyZ3VtZW50AAAAAAZvcHRpb24AAAAAAAEAAAAAAAAABm9wdGlvbgAAAAAD6AAAAAQAAAABAAAD6AAAAAQ=", - "AAAAAAAAAAAAAAAEdTI1NgAAAAEAAAAAAAAABHUyNTYAAAAMAAAAAQAAAAw=", - "AAAAAAAAAAAAAAAEaTI1NgAAAAEAAAAAAAAABGkyNTYAAAANAAAAAQAAAA0=", - "AAAAAAAAAAAAAAAGc3RyaW5nAAAAAAABAAAAAAAAAAZzdHJpbmcAAAAAABAAAAABAAAAEA==", - "AAAAAAAAAAAAAAAMdHVwbGVfc3RydWt0AAAAAQAAAAAAAAAMdHVwbGVfc3RydWt0AAAH0AAAAAtUdXBsZVN0cnVjdAAAAAABAAAH0AAAAAtUdXBsZVN0cnVjdAA=" - ]); - } - parsers = { - hello: (result) => this.spec.funcResToNative("hello", result), - woid: () => { }, - val: (result) => this.spec.funcResToNative("val", result), - u32FailOnEven: (result) => { - if (result instanceof Err) - return result; - return new Ok(this.spec.funcResToNative("u32_fail_on_even", result)); - }, - u32: (result) => this.spec.funcResToNative("u32_", result), - i32: (result) => this.spec.funcResToNative("i32_", result), - i64: (result) => this.spec.funcResToNative("i64_", result), - struktHel: (result) => this.spec.funcResToNative("strukt_hel", result), - strukt: (result) => this.spec.funcResToNative("strukt", result), - simple: (result) => this.spec.funcResToNative("simple", result), - complex: (result) => this.spec.funcResToNative("complex", result), - addresse: (result) => this.spec.funcResToNative("addresse", result), - bytes: (result) => this.spec.funcResToNative("bytes", result), - bytesN: (result) => this.spec.funcResToNative("bytes_n", result), - card: (result) => this.spec.funcResToNative("card", result), - boolean: (result) => this.spec.funcResToNative("boolean", result), - not: (result) => this.spec.funcResToNative("not", result), - i128: (result) => this.spec.funcResToNative("i128", result), - u128: (result) => this.spec.funcResToNative("u128", result), - multiArgs: (result) => this.spec.funcResToNative("multi_args", result), - map: (result) => this.spec.funcResToNative("map", result), - vec: (result) => this.spec.funcResToNative("vec", result), - tuple: (result) => this.spec.funcResToNative("tuple", result), - option: (result) => this.spec.funcResToNative("option", result), - u256: (result) => this.spec.funcResToNative("u256", result), - i256: (result) => this.spec.funcResToNative("i256", result), - string: (result) => this.spec.funcResToNative("string", result), - tupleStrukt: (result) => this.spec.funcResToNative("tuple_strukt", result) - }; - txFromJSON = (json) => { - const { method, ...tx } = JSON.parse(json); - return AssembledTransaction.fromJSON({ - ...this.options, - method, - parseResultXdr: this.parsers[method], - }, tx); - }; - fromJSON = { - hello: (this.txFromJSON), - woid: (this.txFromJSON), - val: (this.txFromJSON), - u32FailOnEven: (this.txFromJSON), - u32: (this.txFromJSON), - i32: (this.txFromJSON), - i64: (this.txFromJSON), - struktHel: (this.txFromJSON), - strukt: (this.txFromJSON), - simple: (this.txFromJSON), - complex: (this.txFromJSON), - addresse: (this.txFromJSON), - bytes: (this.txFromJSON), - bytesN: (this.txFromJSON), - card: (this.txFromJSON), - boolean: (this.txFromJSON), - not: (this.txFromJSON), - i128: (this.txFromJSON), - u128: (this.txFromJSON), - multiArgs: (this.txFromJSON), - map: (this.txFromJSON), - vec: (this.txFromJSON), - tuple: (this.txFromJSON), - option: (this.txFromJSON), - u256: (this.txFromJSON), - i256: (this.txFromJSON), - string: (this.txFromJSON), - tupleStrukt: (this.txFromJSON) - }; - /** -* Construct and simulate a hello transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - hello = async ({ hello }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'hello', - args: this.spec.funcArgsToScVals("hello", { hello }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['hello'], - }); - }; - /** -* Construct and simulate a woid transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - woid = async (options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'woid', - args: this.spec.funcArgsToScVals("woid", {}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['woid'], - }); - }; - /** -* Construct and simulate a val transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - val = async (options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'val', - args: this.spec.funcArgsToScVals("val", {}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['val'], - }); - }; - /** -* Construct and simulate a u32_fail_on_even transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u32FailOnEven = async ({ u32_ }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'u32_fail_on_even', - args: this.spec.funcArgsToScVals("u32_fail_on_even", { u32_ }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['u32FailOnEven'], - }); - }; - /** -* Construct and simulate a u32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u32 = async ({ u32_ }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'u32_', - args: this.spec.funcArgsToScVals("u32_", { u32_ }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['u32'], - }); - }; - /** -* Construct and simulate a i32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i32 = async ({ i32_ }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'i32_', - args: this.spec.funcArgsToScVals("i32_", { i32_ }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['i32'], - }); - }; - /** -* Construct and simulate a i64_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i64 = async ({ i64_ }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'i64_', - args: this.spec.funcArgsToScVals("i64_", { i64_ }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['i64'], - }); - }; - /** -* Construct and simulate a strukt_hel transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example contract method which takes a struct -*/ - struktHel = async ({ strukt }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'strukt_hel', - args: this.spec.funcArgsToScVals("strukt_hel", { strukt }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['struktHel'], - }); - }; - /** -* Construct and simulate a strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - strukt = async ({ strukt }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'strukt', - args: this.spec.funcArgsToScVals("strukt", { strukt }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['strukt'], - }); - }; - /** -* Construct and simulate a simple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - simple = async ({ simple }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'simple', - args: this.spec.funcArgsToScVals("simple", { simple }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['simple'], - }); - }; - /** -* Construct and simulate a complex transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - complex = async ({ complex }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'complex', - args: this.spec.funcArgsToScVals("complex", { complex }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['complex'], - }); - }; - /** -* Construct and simulate a addresse transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - addresse = async ({ addresse }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'addresse', - args: this.spec.funcArgsToScVals("addresse", { addresse: new Address(addresse) }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['addresse'], - }); - }; - /** -* Construct and simulate a bytes transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - bytes = async ({ bytes }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'bytes', - args: this.spec.funcArgsToScVals("bytes", { bytes }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['bytes'], - }); - }; - /** -* Construct and simulate a bytes_n transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - bytesN = async ({ bytes_n }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'bytes_n', - args: this.spec.funcArgsToScVals("bytes_n", { bytes_n }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['bytesN'], - }); - }; - /** -* Construct and simulate a card transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - card = async ({ card }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'card', - args: this.spec.funcArgsToScVals("card", { card }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['card'], - }); - }; - /** -* Construct and simulate a boolean transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - boolean = async ({ boolean }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'boolean', - args: this.spec.funcArgsToScVals("boolean", { boolean }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['boolean'], - }); - }; - /** -* Construct and simulate a not transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Negates a boolean value -*/ - not = async ({ boolean }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'not', - args: this.spec.funcArgsToScVals("not", { boolean }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['not'], - }); - }; - /** -* Construct and simulate a i128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i128 = async ({ i128 }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'i128', - args: this.spec.funcArgsToScVals("i128", { i128 }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['i128'], - }); - }; - /** -* Construct and simulate a u128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u128 = async ({ u128 }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'u128', - args: this.spec.funcArgsToScVals("u128", { u128 }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['u128'], - }); - }; - /** -* Construct and simulate a multi_args transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - multiArgs = async ({ a, b }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'multi_args', - args: this.spec.funcArgsToScVals("multi_args", { a, b }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['multiArgs'], - }); - }; - /** -* Construct and simulate a map transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - map = async ({ map }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'map', - args: this.spec.funcArgsToScVals("map", { map }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['map'], - }); - }; - /** -* Construct and simulate a vec transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - vec = async ({ vec }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'vec', - args: this.spec.funcArgsToScVals("vec", { vec }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['vec'], - }); - }; - /** -* Construct and simulate a tuple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - tuple = async ({ tuple }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'tuple', - args: this.spec.funcArgsToScVals("tuple", { tuple }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['tuple'], - }); - }; - /** -* Construct and simulate a option transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example of an optional argument -*/ - option = async ({ option }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'option', - args: this.spec.funcArgsToScVals("option", { option }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['option'], - }); - }; - /** -* Construct and simulate a u256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u256 = async ({ u256 }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'u256', - args: this.spec.funcArgsToScVals("u256", { u256 }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['u256'], - }); - }; - /** -* Construct and simulate a i256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i256 = async ({ i256 }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'i256', - args: this.spec.funcArgsToScVals("i256", { i256 }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['i256'], - }); - }; - /** -* Construct and simulate a string transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - string = async ({ string }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'string', - args: this.spec.funcArgsToScVals("string", { string }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['string'], - }); - }; - /** -* Construct and simulate a tuple_strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - tupleStrukt = async ({ tuple_strukt }, options = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'tuple_strukt', - args: this.spec.funcArgsToScVals("tuple_strukt", { tuple_strukt }), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['tupleStrukt'], - }); - }; -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/method-options.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/method-options.d.ts deleted file mode 100644 index fc6b21d5..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/method-options.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -declare let responseTypes: 'simulated' | 'full' | undefined; -export type ResponseTypes = typeof responseTypes; -export type XDR_BASE64 = string; -export interface Wallet { - isConnected: () => Promise; - isAllowed: () => Promise; - getUserInfo: () => Promise<{ - publicKey?: string; - }>; - signTransaction: (tx: XDR_BASE64, opts?: { - network?: string; - networkPassphrase?: string; - accountToSign?: string; - }) => Promise; - signAuthEntry: (entryXdr: XDR_BASE64, opts?: { - accountToSign?: string; - }) => Promise; -} -export type ClassOptions = { - contractId: string; - networkPassphrase: string; - rpcUrl: string; - errorTypes?: Record; - /** - * A Wallet interface, such as Freighter, that has the methods `isConnected`, `isAllowed`, `getUserInfo`, and `signTransaction`. If not provided, will attempt to import and use Freighter. Example: - * - * @example - * ```ts - * import freighter from "@stellar/freighter-api"; - * import { Contract } from "test_custom_types"; - * const contract = new Contract({ - * …, - * wallet: freighter, - * }) - * ``` - */ - wallet?: Wallet; -}; -export type MethodOptions = { - /** - * The fee to pay for the transaction. Default: soroban-sdk's BASE_FEE ('100') - */ - fee?: number; -}; -export {}; diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/method-options.js b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/method-options.js deleted file mode 100644 index 00ad9d3c..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/method-options.js +++ /dev/null @@ -1,3 +0,0 @@ -// defined this way so typeahead shows full union, not named alias -let responseTypes; -export {}; diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/package.json b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/package.json deleted file mode 100644 index 1632c2c4..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/package.json +++ /dev/null @@ -1 +0,0 @@ -{"type": "module"} \ No newline at end of file diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/assembled-tx.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/assembled-tx.d.ts deleted file mode 100644 index 1d5e6f5e..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/assembled-tx.d.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Account, Address, Operation, SorobanRpc, xdr } from "@stellar/stellar-sdk"; -import type { Memo, MemoType, Transaction } from "@stellar/stellar-sdk"; -import type { ClassOptions, MethodOptions, Wallet, XDR_BASE64 } from "./method-options.js"; -export type Tx = Transaction, Operation[]>; -export declare class ExpiredStateError extends Error { -} -export declare class NeedsMoreSignaturesError extends Error { -} -export declare class WalletDisconnectedError extends Error { -} -export declare class SendResultOnlyError extends Error { -} -export declare class SendFailedError extends Error { -} -export declare class NoUnsignedNonInvokerAuthEntriesError extends Error { -} -type SendTx = SorobanRpc.Api.SendTransactionResponse; -type GetTx = SorobanRpc.Api.GetTransactionResponse; -export type u32 = number; -export type i32 = number; -export type u64 = bigint; -export type i64 = bigint; -export type u128 = bigint; -export type i128 = bigint; -export type u256 = bigint; -export type i256 = bigint; -export type Option = T | undefined; -export type Typepoint = bigint; -export type Duration = bigint; -export { Address }; -export interface Error_ { - message: string; -} -export interface Result { - unwrap(): T; - unwrapErr(): E; - isOk(): boolean; - isErr(): boolean; -} -export declare class Ok implements Result { - readonly value: T; - constructor(value: T); - unwrapErr(): E; - unwrap(): T; - isOk(): boolean; - isErr(): boolean; -} -export declare class Err implements Result { - readonly error: E; - constructor(error: E); - unwrapErr(): E; - unwrap(): never; - isOk(): boolean; - isErr(): boolean; -} -export declare const contractErrorPattern: RegExp; -type AssembledTransactionOptions = MethodOptions & ClassOptions & { - method: string; - args?: any[]; - parseResultXdr: (xdr: string | xdr.ScVal | Err) => T; -}; -export declare const NULL_ACCOUNT = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF"; -export declare class AssembledTransaction { - options: AssembledTransactionOptions; - raw: Tx; - private simulation?; - private simulationResult?; - private simulationTransactionData?; - private server; - toJSON(): string; - static fromJSON(options: Omit, 'args'>, { tx, simulationResult, simulationTransactionData }: { - tx: XDR_BASE64; - simulationResult: { - auth: XDR_BASE64[]; - retval: XDR_BASE64; - }; - simulationTransactionData: XDR_BASE64; - }): AssembledTransaction; - private constructor(); - static fromSimulation(options: AssembledTransactionOptions): Promise>; - simulate: () => Promise; - get simulationData(): { - result: SorobanRpc.Api.SimulateHostFunctionResult; - transactionData: xdr.SorobanTransactionData; - }; - get result(): T; - parseError(errorMessage: string): Err | undefined; - getWallet: () => Promise; - getPublicKey: () => Promise; - /** - * Get account details from the Soroban network for the publicKey currently - * selected in user's wallet. If not connected to Freighter, use placeholder - * null account. - */ - getAccount: () => Promise; - /** - * Sign the transaction with the `wallet` (default Freighter), then send to - * the network and return a `SentTransaction` that keeps track of all the - * attempts to send and fetch the transaction from the network. - */ - signAndSend: ({ secondsToWait, force }?: { - /** - * Wait `secondsToWait` seconds (default: 10) for both the transaction to SEND successfully (will keep trying if the server returns `TRY_AGAIN_LATER`), as well as for the transaction to COMPLETE (will keep checking if the server returns `PENDING`). - */ - secondsToWait?: number | undefined; - /** - * If `true`, sign and send the transaction even if it is a read call. - */ - force?: boolean | undefined; - }) => Promise>; - getStorageExpiration: () => Promise; - /** - * Get a list of accounts, other than the invoker of the simulation, that - * need to sign auth entries in this transaction. - * - * Soroban allows multiple people to sign a transaction. Someone needs to - * sign the final transaction envelope; this person/account is called the - * _invoker_, or _source_. Other accounts might need to sign individual auth - * entries in the transaction, if they're not also the invoker. - * - * This function returns a list of accounts that need to sign auth entries, - * assuming that the same invoker/source account will sign the final - * transaction envelope as signed the initial simulation. - * - * One at a time, for each public key in this array, you will need to - * serialize this transaction with `toJSON`, send to the owner of that key, - * deserialize the transaction with `txFromJson`, and call - * {@link signAuthEntries}. Then re-serialize and send to the next account - * in this list. - */ - needsNonInvokerSigningBy: ({ includeAlreadySigned, }?: { - /** - * Whether or not to include auth entries that have already been signed. Default: false - */ - includeAlreadySigned?: boolean | undefined; - }) => Promise; - preImageFor(entry: xdr.SorobanAuthorizationEntry, signatureExpirationLedger: number): xdr.HashIdPreimage; - /** - * If {@link needsNonInvokerSigningBy} returns a non-empty list, you can serialize - * the transaction with `toJSON`, send it to the owner of one of the public keys - * in the map, deserialize with `txFromJSON`, and call this method on their - * machine. Internally, this will use `signAuthEntry` function from connected - * `wallet` for each. - * - * Then, re-serialize the transaction and either send to the next - * `needsNonInvokerSigningBy` owner, or send it back to the original account - * who simulated the transaction so they can {@link sign} the transaction - * envelope and {@link send} it to the network. - * - * Sending to all `needsNonInvokerSigningBy` owners in parallel is not currently - * supported! - */ - signAuthEntries: (expiration?: number | Promise) => Promise; - get isReadCall(): boolean; - hasRealInvoker: () => Promise; -} -/** - * A transaction that has been sent to the Soroban network. This happens in two steps: - * - * 1. `sendTransaction`: initial submission of the transaction to the network. - * This step can run into problems, and will be retried with exponential - * backoff if it does. See all attempts in `sendTransactionResponseAll` and the - * most recent attempt in `sendTransactionResponse`. - * 2. `getTransaction`: once the transaction has been submitted to the network - * successfully, you need to wait for it to finalize to get the results of the - * transaction. This step can also run into problems, and will be retried with - * exponential backoff if it does. See all attempts in - * `getTransactionResponseAll` and the most recent attempt in - * `getTransactionResponse`. - */ -declare class SentTransaction { - options: AssembledTransactionOptions; - assembled: AssembledTransaction; - server: SorobanRpc.Server; - signed: Tx; - sendTransactionResponse?: SendTx; - sendTransactionResponseAll?: SendTx[]; - getTransactionResponse?: GetTx; - getTransactionResponseAll?: GetTx[]; - constructor(options: AssembledTransactionOptions, assembled: AssembledTransaction); - static init: (options: AssembledTransactionOptions, assembled: AssembledTransaction, secondsToWait?: number) => Promise>; - private send; - get result(): T; -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/index.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/index.d.ts deleted file mode 100644 index 66d3d595..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/index.d.ts +++ /dev/null @@ -1,424 +0,0 @@ -import { ContractSpec } from '@stellar/stellar-sdk'; -import { Buffer } from "buffer"; -import { AssembledTransaction, Ok, Err } from './assembled-tx.js'; -import type { u32, i32, i64, i128, Option, Error_ } from './assembled-tx.js'; -import type { ClassOptions } from './method-options.js'; -export * from './assembled-tx.js'; -export * from './method-options.js'; -export declare const networks: { - readonly futurenet: { - readonly networkPassphrase: "Test SDF Future Network ; October 2022"; - readonly contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK"; - }; -}; -/** - This is from the rust doc above the struct Test - */ -export interface Test { - /** - - */ - a: u32; - /** - - */ - b: boolean; - /** - - */ - c: string; -} -/** - - */ -export type SimpleEnum = { - tag: "First"; - values: void; -} | { - tag: "Second"; - values: void; -} | { - tag: "Third"; - values: void; -}; -/** - - */ -export declare enum RoyalCard { - Jack = 11, - Queen = 12, - King = 13 -} -/** - - */ -export type TupleStruct = readonly [Test, SimpleEnum]; -/** - - */ -export type ComplexEnum = { - tag: "Struct"; - values: readonly [Test]; -} | { - tag: "Tuple"; - values: readonly [TupleStruct]; -} | { - tag: "Enum"; - values: readonly [SimpleEnum]; -} | { - tag: "Asset"; - values: readonly [string, i128]; -} | { - tag: "Void"; - values: void; -}; -/** - - */ -export declare const Errors: { - 1: { - message: string; - }; -}; -export declare class Contract { - readonly options: ClassOptions; - spec: ContractSpec; - constructor(options: ClassOptions); - private readonly parsers; - private txFromJSON; - readonly fromJSON: { - hello: (json: string) => AssembledTransaction; - woid: (json: string) => AssembledTransaction; - val: (json: string) => AssembledTransaction; - u32FailOnEven: (json: string) => AssembledTransaction | Ok>; - u32: (json: string) => AssembledTransaction; - i32: (json: string) => AssembledTransaction; - i64: (json: string) => AssembledTransaction; - struktHel: (json: string) => AssembledTransaction; - strukt: (json: string) => AssembledTransaction; - simple: (json: string) => AssembledTransaction; - complex: (json: string) => AssembledTransaction; - addresse: (json: string) => AssembledTransaction; - bytes: (json: string) => AssembledTransaction; - bytesN: (json: string) => AssembledTransaction; - card: (json: string) => AssembledTransaction; - boolean: (json: string) => AssembledTransaction; - not: (json: string) => AssembledTransaction; - i128: (json: string) => AssembledTransaction; - u128: (json: string) => AssembledTransaction; - multiArgs: (json: string) => AssembledTransaction; - map: (json: string) => AssembledTransaction>; - vec: (json: string) => AssembledTransaction; - tuple: (json: string) => AssembledTransaction; - option: (json: string) => AssembledTransaction>; - u256: (json: string) => AssembledTransaction; - i256: (json: string) => AssembledTransaction; - string: (json: string) => AssembledTransaction; - tupleStrukt: (json: string) => AssembledTransaction; - }; - /** -* Construct and simulate a hello transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - hello: ({ hello }: { - hello: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a woid transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - woid: (options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a val transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - val: (options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a u32_fail_on_even transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u32FailOnEven: ({ u32_ }: { - u32_: u32; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise | Ok>>; - /** -* Construct and simulate a u32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u32: ({ u32_ }: { - u32_: u32; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i32: ({ i32_ }: { - i32_: i32; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i64_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i64: ({ i64_ }: { - i64_: i64; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a strukt_hel transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example contract method which takes a struct -*/ - struktHel: ({ strukt }: { - strukt: Test; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - strukt: ({ strukt }: { - strukt: Test; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a simple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - simple: ({ simple }: { - simple: SimpleEnum; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a complex transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - complex: ({ complex }: { - complex: ComplexEnum; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a addresse transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - addresse: ({ addresse }: { - addresse: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a bytes transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - bytes: ({ bytes }: { - bytes: Buffer; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a bytes_n transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - bytesN: ({ bytes_n }: { - bytes_n: Buffer; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a card transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - card: ({ card }: { - card: RoyalCard; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a boolean transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - boolean: ({ boolean }: { - boolean: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a not transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Negates a boolean value -*/ - not: ({ boolean }: { - boolean: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i128: ({ i128 }: { - i128: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a u128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u128: ({ u128 }: { - u128: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a multi_args transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - multiArgs: ({ a, b }: { - a: u32; - b: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a map transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - map: ({ map }: { - map: Map; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>>; - /** -* Construct and simulate a vec transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - vec: ({ vec }: { - vec: Array; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a tuple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - tuple: ({ tuple }: { - tuple: readonly [string, u32]; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a option transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example of an optional argument -*/ - option: ({ option }: { - option: Option; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>>; - /** -* Construct and simulate a u256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - u256: ({ u256 }: { - u256: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a i256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - i256: ({ i256 }: { - i256: bigint; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a string transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - string: ({ string }: { - string: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; - /** -* Construct and simulate a tuple_strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. -*/ - tupleStrukt: ({ tuple_strukt }: { - tuple_strukt: TupleStruct; - }, options?: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number; - }) => Promise>; -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/method-options.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/method-options.d.ts deleted file mode 100644 index fc6b21d5..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/method-options.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -declare let responseTypes: 'simulated' | 'full' | undefined; -export type ResponseTypes = typeof responseTypes; -export type XDR_BASE64 = string; -export interface Wallet { - isConnected: () => Promise; - isAllowed: () => Promise; - getUserInfo: () => Promise<{ - publicKey?: string; - }>; - signTransaction: (tx: XDR_BASE64, opts?: { - network?: string; - networkPassphrase?: string; - accountToSign?: string; - }) => Promise; - signAuthEntry: (entryXdr: XDR_BASE64, opts?: { - accountToSign?: string; - }) => Promise; -} -export type ClassOptions = { - contractId: string; - networkPassphrase: string; - rpcUrl: string; - errorTypes?: Record; - /** - * A Wallet interface, such as Freighter, that has the methods `isConnected`, `isAllowed`, `getUserInfo`, and `signTransaction`. If not provided, will attempt to import and use Freighter. Example: - * - * @example - * ```ts - * import freighter from "@stellar/freighter-api"; - * import { Contract } from "test_custom_types"; - * const contract = new Contract({ - * …, - * wallet: freighter, - * }) - * ``` - */ - wallet?: Wallet; -}; -export type MethodOptions = { - /** - * The fee to pay for the transaction. Default: soroban-sdk's BASE_FEE ('100') - */ - fee?: number; -}; -export {}; diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package-lock.json b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package-lock.json deleted file mode 100644 index 44332a41..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package-lock.json +++ /dev/null @@ -1,328 +0,0 @@ -{ - "name": "test_custom_types", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "test_custom_types", - "version": "0.0.0", - "dependencies": { - "@stellar/freighter-api": "1.7.1", - "@stellar/stellar-sdk": "11.2.0", - "buffer": "6.0.3" - }, - "devDependencies": { - "typescript": "5.3.3" - } - }, - "node_modules/@stellar/freighter-api": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@stellar/freighter-api/-/freighter-api-1.7.1.tgz", - "integrity": "sha512-XvPO+XgEbkeP0VhP0U1edOkds+rGS28+y8GRGbCVXeZ9ZslbWqRFQoETAdX8IXGuykk2ib/aPokiLc5ZaWYP7w==" - }, - "node_modules/@stellar/js-xdr": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@stellar/js-xdr/-/js-xdr-3.0.1.tgz", - "integrity": "sha512-dp5Eh7Nr1YjiIeqpdkj2cQYxfoPudDAH3ck8MWggp48Htw66Z/hUssNYUQG/OftLjEmHT90Z/dtey2Y77DOxIw==" - }, - "node_modules/@stellar/stellar-base": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@stellar/stellar-base/-/stellar-base-10.0.1.tgz", - "integrity": "sha512-BDbx7VHOEQh+4J3Q+gStNXgPaNckVFmD4aOlBBGwxlF6vPFmVnW8IoJdkX7T58zpX55eWI6DXvEhDBlrqTlhAQ==", - "dependencies": { - "@stellar/js-xdr": "^3.0.1", - "base32.js": "^0.1.0", - "bignumber.js": "^9.1.2", - "buffer": "^6.0.3", - "sha.js": "^2.3.6", - "tweetnacl": "^1.0.3" - }, - "optionalDependencies": { - "sodium-native": "^4.0.1" - } - }, - "node_modules/@stellar/stellar-sdk": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@stellar/stellar-sdk/-/stellar-sdk-11.2.0.tgz", - "integrity": "sha512-qInRR+mLLl9O/AI6Q+Sr19RZeYJtlNoJQJi3pch5BYoMvVhjO8IU8AhHADP//Zmc2osyogwPuqXBiFdaGlfHWA==", - "dependencies": { - "@stellar/stellar-base": "10.0.1", - "axios": "^1.6.5", - "bignumber.js": "^9.1.2", - "eventsource": "^2.0.2", - "randombytes": "^2.1.0", - "toml": "^3.0.0", - "urijs": "^1.19.1" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", - "dependencies": { - "follow-redirects": "^1.15.4", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/base32.js": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz", - "integrity": "sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "engines": { - "node": "*" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/eventsource": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", - "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-gyp-build": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", - "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", - "optional": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/sodium-native": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.0.5.tgz", - "integrity": "sha512-YGimGhy7Ho6pTAAvuNdn3Tv9C2MD7HP89X1omReHat0Fd1mMnapGqwzb5YoHTAbIEh8tQmKP6+uLlwYCkf+EOA==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build": "^4.6.0" - } - }, - "node_modules/toml": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/urijs": { - "version": "1.19.11", - "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", - "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" - } - } -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package.json b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package.json deleted file mode 100644 index 1f63968a..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "0.0.0", - "name": "test_custom_types", - "dependencies": { - "@stellar/freighter-api": "1.7.1", - "buffer": "6.0.3", - "@stellar/stellar-sdk": "11.2.0" - }, - "scripts": { - "build": "node ./scripts/build.mjs" - }, - "exports": { - "require": "./dist/cjs/index.js", - "import": "./dist/esm/index.js" - }, - "typings": "dist/types/index.d.ts", - "devDependencies": { - "typescript": "5.3.3" - } -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/build.mjs b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/build.mjs deleted file mode 100644 index 15a17042..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/build.mjs +++ /dev/null @@ -1,37 +0,0 @@ -import { spawnSync } from "node:child_process" -import fs from "node:fs" -import path from "node:path" - -const buildDir = "./dist" - -const { error, stderr } = spawnSync("tsc", ["-b", "./scripts/tsconfig.cjs.json", "./scripts/tsconfig.esm.json", "./scripts/tsconfig.types.json"], { stdio: "inherit" }) - -if (error) { - console.error(stderr) - console.error(error) - throw error -} - -function createEsmModulePackageJson() { - fs.readdir(buildDir, function (err, dirs) { - if (err) { - throw err - } - dirs.forEach(function (dir) { - if (dir === "esm") { - // 1. add package.json file with "type": "module" - var packageJsonFile = path.join(buildDir, dir, "/package.json") - if (!fs.existsSync(packageJsonFile)) { - fs.writeFileSync( - packageJsonFile, - '{"type": "module"}', - 'utf8', - err => { if (err) throw err } - ) - } - } - }) - }) -} - -createEsmModulePackageJson() diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/tsconfig.cjs.json b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/tsconfig.cjs.json deleted file mode 100644 index 542ea86d..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/tsconfig.cjs.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../dist/cjs", - "module": "commonjs" - } -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/tsconfig.esm.json b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/tsconfig.esm.json deleted file mode 100644 index 92b45277..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/tsconfig.esm.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../dist/esm", - "module": "esnext" - } -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/tsconfig.types.json b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/tsconfig.types.json deleted file mode 100644 index 8a24fc13..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/scripts/tsconfig.types.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../dist/types", - "declaration": true, - "emitDeclarationOnly": true - } -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/assembled-tx.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/assembled-tx.ts deleted file mode 100644 index f4f892d4..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/assembled-tx.ts +++ /dev/null @@ -1,664 +0,0 @@ -import { - Account, - Address, - Contract, - Operation, - SorobanRpc, - StrKey, - TimeoutInfinite, - TransactionBuilder, - authorizeEntry, - hash, - nativeToScVal, - xdr, - BASE_FEE, -} from "@stellar/stellar-sdk"; -import type { Memo, MemoType, Transaction } from "@stellar/stellar-sdk"; -import { Buffer } from "buffer"; -import type { - ClassOptions, - MethodOptions, - Wallet, - XDR_BASE64, -} from "./method-options.js"; - -export type Tx = Transaction, Operation[]> - -export class ExpiredStateError extends Error { } -export class NeedsMoreSignaturesError extends Error { } -export class WalletDisconnectedError extends Error { } -export class SendResultOnlyError extends Error { } -export class SendFailedError extends Error { } -export class NoUnsignedNonInvokerAuthEntriesError extends Error { } - -type SendTx = SorobanRpc.Api.SendTransactionResponse; -type GetTx = SorobanRpc.Api.GetTransactionResponse; - -export type u32 = number; -export type i32 = number; -export type u64 = bigint; -export type i64 = bigint; -export type u128 = bigint; -export type i128 = bigint; -export type u256 = bigint; -export type i256 = bigint; -export type Option = T | undefined; -export type Typepoint = bigint; -export type Duration = bigint; -export {Address}; - -/// Error interface containing the error message -export interface Error_ { message: string }; - -export interface Result { - unwrap(): T, - unwrapErr(): E, - isOk(): boolean, - isErr(): boolean, -}; - -export class Ok implements Result { - constructor(readonly value: T) { } - unwrapErr(): E { - throw new Error('No error'); - } - unwrap(): T { - return this.value; - } - - isOk(): boolean { - return true; - } - - isErr(): boolean { - return !this.isOk() - } -} - -export class Err implements Result { - constructor(readonly error: E) { } - unwrapErr(): E { - return this.error; - } - unwrap(): never { - throw new Error(this.error.message); - } - - isOk(): boolean { - return false; - } - - isErr(): boolean { - return !this.isOk() - } -} - -export const contractErrorPattern = /Error\(Contract, #(\d+)\)/; - -type AssembledTransactionOptions = MethodOptions & - ClassOptions & { - method: string; - args?: any[]; - parseResultXdr: (xdr: string | xdr.ScVal | Err) => T; - }; - -export const NULL_ACCOUNT = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF" - -export class AssembledTransaction { - public raw: Tx - private simulation?: SorobanRpc.Api.SimulateTransactionResponse - private simulationResult?: SorobanRpc.Api.SimulateHostFunctionResult - private simulationTransactionData?: xdr.SorobanTransactionData - private server: SorobanRpc.Server - - toJSON() { - return JSON.stringify({ - method: this.options.method, - tx: this.raw?.toXDR(), - simulationResult: { - auth: this.simulationData.result.auth.map(a => a.toXDR('base64')), - retval: this.simulationData.result.retval.toXDR('base64'), - }, - simulationTransactionData: this.simulationData.transactionData.toXDR('base64'), - }) - } - - static fromJSON( - options: Omit, 'args'>, - { tx, simulationResult, simulationTransactionData }: - { - tx: XDR_BASE64, - simulationResult: { - auth: XDR_BASE64[], - retval: XDR_BASE64, - }, - simulationTransactionData: XDR_BASE64, - } - ): AssembledTransaction { - const txn = new AssembledTransaction(options) - txn.raw = TransactionBuilder.fromXDR(tx, options.networkPassphrase) as Tx - txn.simulationResult = { - auth: simulationResult.auth.map(a => xdr.SorobanAuthorizationEntry.fromXDR(a, 'base64')), - retval: xdr.ScVal.fromXDR(simulationResult.retval, 'base64'), - } - txn.simulationTransactionData = xdr.SorobanTransactionData.fromXDR(simulationTransactionData, 'base64') - return txn - } - - private constructor(public options: AssembledTransactionOptions) { - this.server = new SorobanRpc.Server(this.options.rpcUrl, { - allowHttp: this.options.rpcUrl.startsWith("http://"), - }); - } - - static async fromSimulation(options: AssembledTransactionOptions): Promise> { - const tx = new AssembledTransaction(options) - const contract = new Contract(options.contractId); - - tx.raw = new TransactionBuilder(await tx.getAccount(), { - fee: options.fee?.toString(10) ?? BASE_FEE, - networkPassphrase: options.networkPassphrase, - }) - .addOperation(contract.call(options.method, ...(options.args ?? []))) - .setTimeout(TimeoutInfinite) - .build(); - - return await tx.simulate() - } - - simulate = async (): Promise => { - if (!this.raw) throw new Error('Transaction has not yet been assembled') - this.simulation = await this.server.simulateTransaction(this.raw); - - if (SorobanRpc.Api.isSimulationSuccess(this.simulation)) { - this.raw = SorobanRpc.assembleTransaction( - this.raw, - this.simulation - ).build() - } - - return this - } - - get simulationData(): { - result: SorobanRpc.Api.SimulateHostFunctionResult - transactionData: xdr.SorobanTransactionData - } { - if (this.simulationResult && this.simulationTransactionData) { - return { - result: this.simulationResult, - transactionData: this.simulationTransactionData, - } - } - // else, we know we just did the simulation on this machine - const simulation = this.simulation! - if (SorobanRpc.Api.isSimulationError(simulation)) { - throw new Error(`Transaction simulation failed: "${simulation.error}"`) - } - - if (SorobanRpc.Api.isSimulationRestore(simulation)) { - throw new ExpiredStateError(`You need to restore some contract state before you can invoke this method. ${JSON.stringify(simulation, null, 2)}`) - } - - if (!simulation.result) { - throw new Error(`Expected an invocation simulation, but got no 'result' field. Simulation: ${JSON.stringify(simulation, null, 2)}`) - } - - // add to object for serialization & deserialization - this.simulationResult = simulation.result - this.simulationTransactionData = simulation.transactionData.build() - - return { - result: this.simulationResult, - transactionData: this.simulationTransactionData!, - } - } - - get result(): T { - try { - return this.options.parseResultXdr(this.simulationData.result.retval) - } catch (e) { - let err = this.parseError(e.toString()) - if (err) return err as T - throw e - } - } - - parseError(errorMessage: string): Err | undefined { - if (!this.options.errorTypes) return - const match = errorMessage.match(contractErrorPattern) - if (!match) return - let i = parseInt(match[1], 10) - let err = this.options.errorTypes[i] - if (err) return new Err(err) - } - - getWallet = async (): Promise => { - return this.options.wallet ?? (await import("@stellar/freighter-api")).default - } - - getPublicKey = async (): Promise => { - const wallet = await this.getWallet() - if (await wallet.isConnected() && await wallet.isAllowed()) { - return (await wallet.getUserInfo()).publicKey - } - } - - /** - * Get account details from the Soroban network for the publicKey currently - * selected in user's wallet. If not connected to Freighter, use placeholder - * null account. - */ - getAccount = async (): Promise => { - const publicKey = await this.getPublicKey() - return publicKey - ? await this.server.getAccount(publicKey) - : new Account(NULL_ACCOUNT, "0") - } - - /** - * Sign the transaction with the `wallet` (default Freighter), then send to - * the network and return a `SentTransaction` that keeps track of all the - * attempts to send and fetch the transaction from the network. - */ - signAndSend = async ({ secondsToWait = 10, force = false }: { - /** - * Wait `secondsToWait` seconds (default: 10) for both the transaction to SEND successfully (will keep trying if the server returns `TRY_AGAIN_LATER`), as well as for the transaction to COMPLETE (will keep checking if the server returns `PENDING`). - */ - secondsToWait?: number - /** - * If `true`, sign and send the transaction even if it is a read call. - */ - force?: boolean - } = {}): Promise> => { - if (!this.raw) { - throw new Error('Transaction has not yet been simulated') - } - - if (!force && this.isReadCall) { - throw new Error('This is a read call. It requires no signature or sending. Use `force: true` to sign and send anyway.') - } - - if (!await this.hasRealInvoker()) { - throw new WalletDisconnectedError('Wallet is not connected') - } - - if (this.raw.source !== (await this.getAccount()).accountId()) { - throw new Error(`You must submit the transaction with the account that originally created it. Please switch to the wallet with "${this.raw.source}" as its public key.`) - } - - if ((await this.needsNonInvokerSigningBy()).length) { - throw new NeedsMoreSignaturesError( - 'Transaction requires more signatures. See `needsNonInvokerSigningBy` for details.' - ) - } - - return await SentTransaction.init(this.options, this, secondsToWait); - } - - getStorageExpiration = async () => { - const entryRes = await this.server.getLedgerEntries( - new Contract(this.options.contractId).getFootprint() - ) - if ( - !entryRes.entries || - !entryRes.entries.length || - !entryRes.entries[0].liveUntilLedgerSeq - ) throw new Error('failed to get ledger entry') - return entryRes.entries[0].liveUntilLedgerSeq - } - - /** - * Get a list of accounts, other than the invoker of the simulation, that - * need to sign auth entries in this transaction. - * - * Soroban allows multiple people to sign a transaction. Someone needs to - * sign the final transaction envelope; this person/account is called the - * _invoker_, or _source_. Other accounts might need to sign individual auth - * entries in the transaction, if they're not also the invoker. - * - * This function returns a list of accounts that need to sign auth entries, - * assuming that the same invoker/source account will sign the final - * transaction envelope as signed the initial simulation. - * - * One at a time, for each public key in this array, you will need to - * serialize this transaction with `toJSON`, send to the owner of that key, - * deserialize the transaction with `txFromJson`, and call - * {@link signAuthEntries}. Then re-serialize and send to the next account - * in this list. - */ - needsNonInvokerSigningBy = async ({ - includeAlreadySigned = false, - }: { - /** - * Whether or not to include auth entries that have already been signed. Default: false - */ - includeAlreadySigned?: boolean - } = {}): Promise => { - if (!this.raw) { - throw new Error('Transaction has not yet been simulated') - } - - // We expect that any transaction constructed by these libraries has a - // single operation, which is an InvokeHostFunction operation. The host - // function being invoked is the contract method call. - if (!("operations" in this.raw)) { - throw new Error( - `Unexpected Transaction type; no operations: ${JSON.stringify(this.raw) - }` - ) - } - const rawInvokeHostFunctionOp = this.raw - .operations[0] as Operation.InvokeHostFunction - - return [...new Set((rawInvokeHostFunctionOp.auth ?? []).filter(entry => - entry.credentials().switch() === - xdr.SorobanCredentialsType.sorobanCredentialsAddress() && - ( - includeAlreadySigned || - entry.credentials().address().signature().switch().name === 'scvVoid' - ) - ).map(entry => StrKey.encodeEd25519PublicKey( - entry.credentials().address().address().accountId().ed25519() - )))] - } - - preImageFor( - entry: xdr.SorobanAuthorizationEntry, - signatureExpirationLedger: number - ): xdr.HashIdPreimage { - const addrAuth = entry.credentials().address() - return xdr.HashIdPreimage.envelopeTypeSorobanAuthorization( - new xdr.HashIdPreimageSorobanAuthorization({ - networkId: hash(Buffer.from(this.options.networkPassphrase)), - nonce: addrAuth.nonce(), - invocation: entry.rootInvocation(), - signatureExpirationLedger, - }), - ) - } - - /** - * If {@link needsNonInvokerSigningBy} returns a non-empty list, you can serialize - * the transaction with `toJSON`, send it to the owner of one of the public keys - * in the map, deserialize with `txFromJSON`, and call this method on their - * machine. Internally, this will use `signAuthEntry` function from connected - * `wallet` for each. - * - * Then, re-serialize the transaction and either send to the next - * `needsNonInvokerSigningBy` owner, or send it back to the original account - * who simulated the transaction so they can {@link sign} the transaction - * envelope and {@link send} it to the network. - * - * Sending to all `needsNonInvokerSigningBy` owners in parallel is not currently - * supported! - */ - signAuthEntries = async ( - /** - * When to set each auth entry to expire. Could be any number of blocks in - * the future. Can be supplied as a promise or a raw number. Default: - * contract's current `persistent` storage expiration date/ledger - * number/block. - */ - expiration: number | Promise = this.getStorageExpiration() - ): Promise => { - if (!this.raw) throw new Error('Transaction has not yet been assembled or simulated') - const needsNonInvokerSigningBy = await this.needsNonInvokerSigningBy() - - if (!needsNonInvokerSigningBy) throw new NoUnsignedNonInvokerAuthEntriesError('No unsigned non-invoker auth entries; maybe you already signed?') - const publicKey = await this.getPublicKey() - if (!publicKey) throw new Error('Could not get public key from wallet; maybe Freighter is not signed in?') - if (needsNonInvokerSigningBy.indexOf(publicKey) === -1) throw new Error(`No auth entries for public key "${publicKey}"`) - const wallet = await this.getWallet() - - const rawInvokeHostFunctionOp = this.raw - .operations[0] as Operation.InvokeHostFunction - - const authEntries = rawInvokeHostFunctionOp.auth ?? [] - - for (const [i, entry] of authEntries.entries()) { - if ( - entry.credentials().switch() !== - xdr.SorobanCredentialsType.sorobanCredentialsAddress() - ) { - // if the invoker/source account, then the entry doesn't need explicit - // signature, since the tx envelope is already signed by the source - // account, so only check for sorobanCredentialsAddress - continue - } - const pk = StrKey.encodeEd25519PublicKey( - entry.credentials().address().address().accountId().ed25519() - ) - - // this auth entry needs to be signed by a different account - // (or maybe already was!) - if (pk !== publicKey) continue - - authEntries[i] = await authorizeEntry( - entry, - async preimage => Buffer.from( - await wallet.signAuthEntry(preimage.toXDR('base64')), - 'base64' - ), - await expiration, - this.options.networkPassphrase - ) - } - } - - get isReadCall(): boolean { - const authsCount = this.simulationData.result.auth.length; - const writeLength = this.simulationData.transactionData.resources().footprint().readWrite().length - return (authsCount === 0) && (writeLength === 0); - } - - hasRealInvoker = async (): Promise => { - const account = await this.getAccount() - return account.accountId() !== NULL_ACCOUNT - } -} - -/** - * A transaction that has been sent to the Soroban network. This happens in two steps: - * - * 1. `sendTransaction`: initial submission of the transaction to the network. - * This step can run into problems, and will be retried with exponential - * backoff if it does. See all attempts in `sendTransactionResponseAll` and the - * most recent attempt in `sendTransactionResponse`. - * 2. `getTransaction`: once the transaction has been submitted to the network - * successfully, you need to wait for it to finalize to get the results of the - * transaction. This step can also run into problems, and will be retried with - * exponential backoff if it does. See all attempts in - * `getTransactionResponseAll` and the most recent attempt in - * `getTransactionResponse`. - */ -class SentTransaction { - public server: SorobanRpc.Server - public signed: Tx - public sendTransactionResponse?: SendTx - public sendTransactionResponseAll?: SendTx[] - public getTransactionResponse?: GetTx - public getTransactionResponseAll?: GetTx[] - - constructor(public options: AssembledTransactionOptions, public assembled: AssembledTransaction) { - this.server = new SorobanRpc.Server(this.options.rpcUrl, { - allowHttp: this.options.rpcUrl.startsWith("http://"), - }); - this.assembled = assembled - } - - static init = async ( - options: AssembledTransactionOptions, - assembled: AssembledTransaction, - secondsToWait: number = 10 - ): Promise> => { - const tx = new SentTransaction(options, assembled) - return await tx.send(secondsToWait) - } - - private send = async (secondsToWait: number = 10): Promise => { - const wallet = await this.assembled.getWallet() - - this.sendTransactionResponseAll = await withExponentialBackoff( - async (previousFailure) => { - if (previousFailure) { - // Increment transaction sequence number and resimulate before trying again - - // Soroban transaction can only have 1 operation - const op = this.assembled.raw.operations[0] as Operation.InvokeHostFunction; - - this.assembled.raw = new TransactionBuilder(await this.assembled.getAccount(), { - fee: this.assembled.raw.fee, - networkPassphrase: this.options.networkPassphrase, - }) - .setTimeout(TimeoutInfinite) - .addOperation( - Operation.invokeHostFunction({ ...op, auth: op.auth ?? [] }), - ) - .build() - - await this.assembled.simulate() - } - - const signature = await wallet.signTransaction(this.assembled.raw.toXDR(), { - networkPassphrase: this.options.networkPassphrase, - }); - - this.signed = TransactionBuilder.fromXDR( - signature, - this.options.networkPassphrase - ) as Tx - - return this.server.sendTransaction(this.signed) - }, - resp => resp.status !== "PENDING", - secondsToWait - ) - - this.sendTransactionResponse = this.sendTransactionResponseAll[this.sendTransactionResponseAll.length - 1] - - if (this.sendTransactionResponse.status !== "PENDING") { - throw new Error( - `Tried to resubmit transaction for ${secondsToWait - } seconds, but it's still failing. ` + - `All attempts: ${JSON.stringify( - this.sendTransactionResponseAll, - null, - 2 - )}` - ); - } - - const { hash } = this.sendTransactionResponse - - this.getTransactionResponseAll = await withExponentialBackoff( - () => this.server.getTransaction(hash), - resp => resp.status === SorobanRpc.Api.GetTransactionStatus.NOT_FOUND, - secondsToWait - ) - - this.getTransactionResponse = this.getTransactionResponseAll[this.getTransactionResponseAll.length - 1] - if (this.getTransactionResponse.status === SorobanRpc.Api.GetTransactionStatus.NOT_FOUND) { - console.error( - `Waited ${secondsToWait - } seconds for transaction to complete, but it did not. ` + - `Returning anyway. Check the transaction status manually. ` + - `Sent transaction: ${JSON.stringify( - this.sendTransactionResponse, - null, - 2 - )}\n` + - `All attempts to get the result: ${JSON.stringify( - this.getTransactionResponseAll, - null, - 2 - )}` - ); - } - - return this; - } - - get result(): T { - // 1. check if transaction was submitted and awaited with `getTransaction` - if ( - "getTransactionResponse" in this && - this.getTransactionResponse - ) { - // getTransactionResponse has a `returnValue` field unless it failed - if ("returnValue" in this.getTransactionResponse) { - return this.options.parseResultXdr(this.getTransactionResponse.returnValue!) - } - - // if "returnValue" not present, the transaction failed; return without parsing the result - throw new Error("Transaction failed! Cannot parse result.") - } - - // 2. otherwise, maybe it was merely sent with `sendTransaction` - if (this.sendTransactionResponse) { - const errorResult = this.sendTransactionResponse.errorResult?.result() - if (errorResult) { - throw new SendFailedError( - `Transaction simulation looked correct, but attempting to send the transaction failed. Check \`simulation\` and \`sendTransactionResponseAll\` to troubleshoot. Decoded \`sendTransactionResponse.errorResultXdr\`: ${errorResult}` - ) - } - throw new SendResultOnlyError( - `Transaction was sent to the network, but not yet awaited. No result to show. Await transaction completion with \`getTransaction(sendTransactionResponse.hash)\`` - ) - } - - // 3. finally, if neither of those are present, throw an error - throw new Error(`Sending transaction failed: ${JSON.stringify(this.assembled)}`) - } -} - -/** - * Keep calling a `fn` for `secondsToWait` seconds, if `keepWaitingIf` is true. - * Returns an array of all attempts to call the function. - */ -async function withExponentialBackoff( - fn: (previousFailure?: T) => Promise, - keepWaitingIf: (result: T) => boolean, - secondsToWait: number, - exponentialFactor = 1.5, - verbose = false, -): Promise { - const attempts: T[] = [] - - let count = 0 - attempts.push(await fn()) - if (!keepWaitingIf(attempts[attempts.length - 1])) return attempts - - const waitUntil = new Date(Date.now() + secondsToWait * 1000).valueOf() - let waitTime = 1000 - let totalWaitTime = waitTime - - while (Date.now() < waitUntil && keepWaitingIf(attempts[attempts.length - 1])) { - count++ - // Wait a beat - if (verbose) { - console.info(`Waiting ${waitTime}ms before trying again (bringing the total wait time to ${totalWaitTime}ms so far, of total ${secondsToWait * 1000}ms)`) - } - await new Promise(res => setTimeout(res, waitTime)) - // Exponential backoff - waitTime = waitTime * exponentialFactor; - if (new Date(Date.now() + waitTime).valueOf() > waitUntil) { - waitTime = waitUntil - Date.now() - if (verbose) { - console.info(`was gonna wait too long; new waitTime: ${waitTime}ms`) - } - } - totalWaitTime = waitTime + totalWaitTime - // Try again - attempts.push(await fn(attempts[attempts.length - 1])) - if (verbose && keepWaitingIf(attempts[attempts.length - 1])) { - console.info( - `${count}. Called ${fn}; ${attempts.length - } prev attempts. Most recent: ${JSON.stringify(attempts[attempts.length - 1], null, 2) - }` - ) - } - } - - return attempts -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/index.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/index.ts deleted file mode 100644 index e3119225..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/index.ts +++ /dev/null @@ -1,758 +0,0 @@ -import { ContractSpec, Address } from '@stellar/stellar-sdk'; -import { Buffer } from "buffer"; -import { AssembledTransaction, Ok, Err } from './assembled-tx.js'; -import type { - u32, - i32, - u64, - i64, - u128, - i128, - u256, - i256, - Option, - Typepoint, - Duration, - Error_, - Result, -} from './assembled-tx.js'; -import type { ClassOptions, XDR_BASE64 } from './method-options.js'; - -export * from './assembled-tx.js'; -export * from './method-options.js'; - -if (typeof window !== 'undefined') { - //@ts-ignore Buffer exists - window.Buffer = window.Buffer || Buffer; -} - - -export const networks = { - futurenet: { - networkPassphrase: "Test SDF Future Network ; October 2022", - contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK", - } -} as const - -/** - This is from the rust doc above the struct Test - */ -export interface Test { - /** - - */ -a: u32; - /** - - */ -b: boolean; - /** - - */ -c: string; -} - -/** - - */ -export type SimpleEnum = {tag: "First", values: void} | {tag: "Second", values: void} | {tag: "Third", values: void}; - -/** - - */ -export enum RoyalCard { - Jack = 11, - Queen = 12, - King = 13, -} - -/** - - */ -export type TupleStruct = readonly [Test, SimpleEnum]; -/** - - */ -export type ComplexEnum = {tag: "Struct", values: readonly [Test]} | {tag: "Tuple", values: readonly [TupleStruct]} | {tag: "Enum", values: readonly [SimpleEnum]} | {tag: "Asset", values: readonly [string, i128]} | {tag: "Void", values: void}; - -/** - - */ -export const Errors = { -1: {message:"Please provide an odd number"} -} - -export class Contract { - spec: ContractSpec; - constructor(public readonly options: ClassOptions) { - this.spec = new ContractSpec([ - "AAAAAQAAAC9UaGlzIGlzIGZyb20gdGhlIHJ1c3QgZG9jIGFib3ZlIHRoZSBzdHJ1Y3QgVGVzdAAAAAAAAAAABFRlc3QAAAADAAAAAAAAAAFhAAAAAAAABAAAAAAAAAABYgAAAAAAAAEAAAAAAAAAAWMAAAAAAAAR", - "AAAAAgAAAAAAAAAAAAAAClNpbXBsZUVudW0AAAAAAAMAAAAAAAAAAAAAAAVGaXJzdAAAAAAAAAAAAAAAAAAABlNlY29uZAAAAAAAAAAAAAAAAAAFVGhpcmQAAAA=", - "AAAAAwAAAAAAAAAAAAAACVJveWFsQ2FyZAAAAAAAAAMAAAAAAAAABEphY2sAAAALAAAAAAAAAAVRdWVlbgAAAAAAAAwAAAAAAAAABEtpbmcAAAAN", - "AAAAAQAAAAAAAAAAAAAAC1R1cGxlU3RydWN0AAAAAAIAAAAAAAAAATAAAAAAAAfQAAAABFRlc3QAAAAAAAAAATEAAAAAAAfQAAAAClNpbXBsZUVudW0AAA==", - "AAAAAgAAAAAAAAAAAAAAC0NvbXBsZXhFbnVtAAAAAAUAAAABAAAAAAAAAAZTdHJ1Y3QAAAAAAAEAAAfQAAAABFRlc3QAAAABAAAAAAAAAAVUdXBsZQAAAAAAAAEAAAfQAAAAC1R1cGxlU3RydWN0AAAAAAEAAAAAAAAABEVudW0AAAABAAAH0AAAAApTaW1wbGVFbnVtAAAAAAABAAAAAAAAAAVBc3NldAAAAAAAAAIAAAATAAAACwAAAAAAAAAAAAAABFZvaWQ=", - "AAAABAAAAAAAAAAAAAAABUVycm9yAAAAAAAAAQAAABxQbGVhc2UgcHJvdmlkZSBhbiBvZGQgbnVtYmVyAAAAD051bWJlck11c3RCZU9kZAAAAAAB", - "AAAAAAAAAAAAAAAFaGVsbG8AAAAAAAABAAAAAAAAAAVoZWxsbwAAAAAAABEAAAABAAAAEQ==", - "AAAAAAAAAAAAAAAEd29pZAAAAAAAAAAA", - "AAAAAAAAAAAAAAADdmFsAAAAAAAAAAABAAAAAA==", - "AAAAAAAAAAAAAAAQdTMyX2ZhaWxfb25fZXZlbgAAAAEAAAAAAAAABHUzMl8AAAAEAAAAAQAAA+kAAAAEAAAAAw==", - "AAAAAAAAAAAAAAAEdTMyXwAAAAEAAAAAAAAABHUzMl8AAAAEAAAAAQAAAAQ=", - "AAAAAAAAAAAAAAAEaTMyXwAAAAEAAAAAAAAABGkzMl8AAAAFAAAAAQAAAAU=", - "AAAAAAAAAAAAAAAEaTY0XwAAAAEAAAAAAAAABGk2NF8AAAAHAAAAAQAAAAc=", - "AAAAAAAAACxFeGFtcGxlIGNvbnRyYWN0IG1ldGhvZCB3aGljaCB0YWtlcyBhIHN0cnVjdAAAAApzdHJ1a3RfaGVsAAAAAAABAAAAAAAAAAZzdHJ1a3QAAAAAB9AAAAAEVGVzdAAAAAEAAAPqAAAAEQ==", - "AAAAAAAAAAAAAAAGc3RydWt0AAAAAAABAAAAAAAAAAZzdHJ1a3QAAAAAB9AAAAAEVGVzdAAAAAEAAAfQAAAABFRlc3Q=", - "AAAAAAAAAAAAAAAGc2ltcGxlAAAAAAABAAAAAAAAAAZzaW1wbGUAAAAAB9AAAAAKU2ltcGxlRW51bQAAAAAAAQAAB9AAAAAKU2ltcGxlRW51bQAA", - "AAAAAAAAAAAAAAAHY29tcGxleAAAAAABAAAAAAAAAAdjb21wbGV4AAAAB9AAAAALQ29tcGxleEVudW0AAAAAAQAAB9AAAAALQ29tcGxleEVudW0A", - "AAAAAAAAAAAAAAAIYWRkcmVzc2UAAAABAAAAAAAAAAhhZGRyZXNzZQAAABMAAAABAAAAEw==", - "AAAAAAAAAAAAAAAFYnl0ZXMAAAAAAAABAAAAAAAAAAVieXRlcwAAAAAAAA4AAAABAAAADg==", - "AAAAAAAAAAAAAAAHYnl0ZXNfbgAAAAABAAAAAAAAAAdieXRlc19uAAAAA+4AAAAJAAAAAQAAA+4AAAAJ", - "AAAAAAAAAAAAAAAEY2FyZAAAAAEAAAAAAAAABGNhcmQAAAfQAAAACVJveWFsQ2FyZAAAAAAAAAEAAAfQAAAACVJveWFsQ2FyZAAAAA==", - "AAAAAAAAAAAAAAAHYm9vbGVhbgAAAAABAAAAAAAAAAdib29sZWFuAAAAAAEAAAABAAAAAQ==", - "AAAAAAAAABdOZWdhdGVzIGEgYm9vbGVhbiB2YWx1ZQAAAAADbm90AAAAAAEAAAAAAAAAB2Jvb2xlYW4AAAAAAQAAAAEAAAAB", - "AAAAAAAAAAAAAAAEaTEyOAAAAAEAAAAAAAAABGkxMjgAAAALAAAAAQAAAAs=", - "AAAAAAAAAAAAAAAEdTEyOAAAAAEAAAAAAAAABHUxMjgAAAAKAAAAAQAAAAo=", - "AAAAAAAAAAAAAAAKbXVsdGlfYXJncwAAAAAAAgAAAAAAAAABYQAAAAAAAAQAAAAAAAAAAWIAAAAAAAABAAAAAQAAAAQ=", - "AAAAAAAAAAAAAAADbWFwAAAAAAEAAAAAAAAAA21hcAAAAAPsAAAABAAAAAEAAAABAAAD7AAAAAQAAAAB", - "AAAAAAAAAAAAAAADdmVjAAAAAAEAAAAAAAAAA3ZlYwAAAAPqAAAABAAAAAEAAAPqAAAABA==", - "AAAAAAAAAAAAAAAFdHVwbGUAAAAAAAABAAAAAAAAAAV0dXBsZQAAAAAAA+0AAAACAAAAEQAAAAQAAAABAAAD7QAAAAIAAAARAAAABA==", - "AAAAAAAAAB9FeGFtcGxlIG9mIGFuIG9wdGlvbmFsIGFyZ3VtZW50AAAAAAZvcHRpb24AAAAAAAEAAAAAAAAABm9wdGlvbgAAAAAD6AAAAAQAAAABAAAD6AAAAAQ=", - "AAAAAAAAAAAAAAAEdTI1NgAAAAEAAAAAAAAABHUyNTYAAAAMAAAAAQAAAAw=", - "AAAAAAAAAAAAAAAEaTI1NgAAAAEAAAAAAAAABGkyNTYAAAANAAAAAQAAAA0=", - "AAAAAAAAAAAAAAAGc3RyaW5nAAAAAAABAAAAAAAAAAZzdHJpbmcAAAAAABAAAAABAAAAEA==", - "AAAAAAAAAAAAAAAMdHVwbGVfc3RydWt0AAAAAQAAAAAAAAAMdHVwbGVfc3RydWt0AAAH0AAAAAtUdXBsZVN0cnVjdAAAAAABAAAH0AAAAAtUdXBsZVN0cnVjdAA=" - ]); - } - private readonly parsers = { - hello: (result: XDR_BASE64): string => this.spec.funcResToNative("hello", result), - woid: () => {}, - val: (result: XDR_BASE64): any => this.spec.funcResToNative("val", result), - u32FailOnEven: (result: XDR_BASE64 | Err): Ok | Err => { - if (result instanceof Err) return result - return new Ok(this.spec.funcResToNative("u32_fail_on_even", result)) - }, - u32: (result: XDR_BASE64): u32 => this.spec.funcResToNative("u32_", result), - i32: (result: XDR_BASE64): i32 => this.spec.funcResToNative("i32_", result), - i64: (result: XDR_BASE64): i64 => this.spec.funcResToNative("i64_", result), - struktHel: (result: XDR_BASE64): Array => this.spec.funcResToNative("strukt_hel", result), - strukt: (result: XDR_BASE64): Test => this.spec.funcResToNative("strukt", result), - simple: (result: XDR_BASE64): SimpleEnum => this.spec.funcResToNative("simple", result), - complex: (result: XDR_BASE64): ComplexEnum => this.spec.funcResToNative("complex", result), - addresse: (result: XDR_BASE64): string => this.spec.funcResToNative("addresse", result), - bytes: (result: XDR_BASE64): Buffer => this.spec.funcResToNative("bytes", result), - bytesN: (result: XDR_BASE64): Buffer => this.spec.funcResToNative("bytes_n", result), - card: (result: XDR_BASE64): RoyalCard => this.spec.funcResToNative("card", result), - boolean: (result: XDR_BASE64): boolean => this.spec.funcResToNative("boolean", result), - not: (result: XDR_BASE64): boolean => this.spec.funcResToNative("not", result), - i128: (result: XDR_BASE64): i128 => this.spec.funcResToNative("i128", result), - u128: (result: XDR_BASE64): u128 => this.spec.funcResToNative("u128", result), - multiArgs: (result: XDR_BASE64): u32 => this.spec.funcResToNative("multi_args", result), - map: (result: XDR_BASE64): Map => this.spec.funcResToNative("map", result), - vec: (result: XDR_BASE64): Array => this.spec.funcResToNative("vec", result), - tuple: (result: XDR_BASE64): readonly [string, u32] => this.spec.funcResToNative("tuple", result), - option: (result: XDR_BASE64): Option => this.spec.funcResToNative("option", result), - u256: (result: XDR_BASE64): u256 => this.spec.funcResToNative("u256", result), - i256: (result: XDR_BASE64): i256 => this.spec.funcResToNative("i256", result), - string: (result: XDR_BASE64): string => this.spec.funcResToNative("string", result), - tupleStrukt: (result: XDR_BASE64): TupleStruct => this.spec.funcResToNative("tuple_strukt", result) - }; - private txFromJSON = (json: string): AssembledTransaction => { - const { method, ...tx } = JSON.parse(json) - return AssembledTransaction.fromJSON( - { - ...this.options, - method, - parseResultXdr: this.parsers[method], - }, - tx, - ); - } - public readonly fromJSON = { - hello: this.txFromJSON>, - woid: this.txFromJSON>, - val: this.txFromJSON>, - u32FailOnEven: this.txFromJSON>, - u32: this.txFromJSON>, - i32: this.txFromJSON>, - i64: this.txFromJSON>, - struktHel: this.txFromJSON>, - strukt: this.txFromJSON>, - simple: this.txFromJSON>, - complex: this.txFromJSON>, - addresse: this.txFromJSON>, - bytes: this.txFromJSON>, - bytesN: this.txFromJSON>, - card: this.txFromJSON>, - boolean: this.txFromJSON>, - not: this.txFromJSON>, - i128: this.txFromJSON>, - u128: this.txFromJSON>, - multiArgs: this.txFromJSON>, - map: this.txFromJSON>, - vec: this.txFromJSON>, - tuple: this.txFromJSON>, - option: this.txFromJSON>, - u256: this.txFromJSON>, - i256: this.txFromJSON>, - string: this.txFromJSON>, - tupleStrukt: this.txFromJSON> - } - /** - * Construct and simulate a hello transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - hello = async ({hello}: {hello: string}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'hello', - args: this.spec.funcArgsToScVals("hello", {hello}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['hello'], - }); - } - - - /** - * Construct and simulate a woid transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - woid = async (options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'woid', - args: this.spec.funcArgsToScVals("woid", {}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['woid'], - }); - } - - - /** - * Construct and simulate a val transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - val = async (options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'val', - args: this.spec.funcArgsToScVals("val", {}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['val'], - }); - } - - - /** - * Construct and simulate a u32_fail_on_even transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - u32FailOnEven = async ({u32_}: {u32_: u32}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'u32_fail_on_even', - args: this.spec.funcArgsToScVals("u32_fail_on_even", {u32_}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['u32FailOnEven'], - }); - } - - - /** - * Construct and simulate a u32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - u32 = async ({u32_}: {u32_: u32}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'u32_', - args: this.spec.funcArgsToScVals("u32_", {u32_}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['u32'], - }); - } - - - /** - * Construct and simulate a i32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - i32 = async ({i32_}: {i32_: i32}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'i32_', - args: this.spec.funcArgsToScVals("i32_", {i32_}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['i32'], - }); - } - - - /** - * Construct and simulate a i64_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - i64 = async ({i64_}: {i64_: i64}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'i64_', - args: this.spec.funcArgsToScVals("i64_", {i64_}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['i64'], - }); - } - - - /** - * Construct and simulate a strukt_hel transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example contract method which takes a struct - */ - struktHel = async ({strukt}: {strukt: Test}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'strukt_hel', - args: this.spec.funcArgsToScVals("strukt_hel", {strukt}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['struktHel'], - }); - } - - - /** - * Construct and simulate a strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - strukt = async ({strukt}: {strukt: Test}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'strukt', - args: this.spec.funcArgsToScVals("strukt", {strukt}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['strukt'], - }); - } - - - /** - * Construct and simulate a simple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - simple = async ({simple}: {simple: SimpleEnum}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'simple', - args: this.spec.funcArgsToScVals("simple", {simple}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['simple'], - }); - } - - - /** - * Construct and simulate a complex transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - complex = async ({complex}: {complex: ComplexEnum}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'complex', - args: this.spec.funcArgsToScVals("complex", {complex}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['complex'], - }); - } - - - /** - * Construct and simulate a addresse transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - addresse = async ({addresse}: {addresse: string}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'addresse', - args: this.spec.funcArgsToScVals("addresse", {addresse: new Address(addresse)}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['addresse'], - }); - } - - - /** - * Construct and simulate a bytes transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - bytes = async ({bytes}: {bytes: Buffer}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'bytes', - args: this.spec.funcArgsToScVals("bytes", {bytes}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['bytes'], - }); - } - - - /** - * Construct and simulate a bytes_n transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - bytesN = async ({bytes_n}: {bytes_n: Buffer}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'bytes_n', - args: this.spec.funcArgsToScVals("bytes_n", {bytes_n}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['bytesN'], - }); - } - - - /** - * Construct and simulate a card transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - card = async ({card}: {card: RoyalCard}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'card', - args: this.spec.funcArgsToScVals("card", {card}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['card'], - }); - } - - - /** - * Construct and simulate a boolean transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - boolean = async ({boolean}: {boolean: boolean}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'boolean', - args: this.spec.funcArgsToScVals("boolean", {boolean}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['boolean'], - }); - } - - - /** - * Construct and simulate a not transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Negates a boolean value - */ - not = async ({boolean}: {boolean: boolean}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'not', - args: this.spec.funcArgsToScVals("not", {boolean}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['not'], - }); - } - - - /** - * Construct and simulate a i128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - i128 = async ({i128}: {i128: i128}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'i128', - args: this.spec.funcArgsToScVals("i128", {i128}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['i128'], - }); - } - - - /** - * Construct and simulate a u128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - u128 = async ({u128}: {u128: u128}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'u128', - args: this.spec.funcArgsToScVals("u128", {u128}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['u128'], - }); - } - - - /** - * Construct and simulate a multi_args transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - multiArgs = async ({a, b}: {a: u32, b: boolean}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'multi_args', - args: this.spec.funcArgsToScVals("multi_args", {a, b}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['multiArgs'], - }); - } - - - /** - * Construct and simulate a map transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - map = async ({map}: {map: Map}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'map', - args: this.spec.funcArgsToScVals("map", {map}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['map'], - }); - } - - - /** - * Construct and simulate a vec transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - vec = async ({vec}: {vec: Array}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'vec', - args: this.spec.funcArgsToScVals("vec", {vec}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['vec'], - }); - } - - - /** - * Construct and simulate a tuple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - tuple = async ({tuple}: {tuple: readonly [string, u32]}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'tuple', - args: this.spec.funcArgsToScVals("tuple", {tuple}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['tuple'], - }); - } - - - /** - * Construct and simulate a option transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.Example of an optional argument - */ - option = async ({option}: {option: Option}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'option', - args: this.spec.funcArgsToScVals("option", {option}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['option'], - }); - } - - - /** - * Construct and simulate a u256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - u256 = async ({u256}: {u256: u256}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'u256', - args: this.spec.funcArgsToScVals("u256", {u256}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['u256'], - }); - } - - - /** - * Construct and simulate a i256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - i256 = async ({i256}: {i256: i256}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'i256', - args: this.spec.funcArgsToScVals("i256", {i256}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['i256'], - }); - } - - - /** - * Construct and simulate a string transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - string = async ({string}: {string: string}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'string', - args: this.spec.funcArgsToScVals("string", {string}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['string'], - }); - } - - - /** - * Construct and simulate a tuple_strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - tupleStrukt = async ({tuple_strukt}: {tuple_strukt: TupleStruct}, options: { - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - } = {}) => { - return await AssembledTransaction.fromSimulation({ - method: 'tuple_strukt', - args: this.spec.funcArgsToScVals("tuple_strukt", {tuple_strukt}), - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['tupleStrukt'], - }); - } - -} \ No newline at end of file diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/method-options.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/method-options.ts deleted file mode 100644 index 737ae0a0..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/method-options.ts +++ /dev/null @@ -1,50 +0,0 @@ -// defined this way so typeahead shows full union, not named alias -let responseTypes: 'simulated' | 'full' | undefined -export type ResponseTypes = typeof responseTypes - -export type XDR_BASE64 = string - -export interface Wallet { - isConnected: () => Promise, - isAllowed: () => Promise, - getUserInfo: () => Promise<{ publicKey?: string }>, - signTransaction: (tx: XDR_BASE64, opts?: { - network?: string, - networkPassphrase?: string, - accountToSign?: string, - }) => Promise, - signAuthEntry: ( - entryXdr: XDR_BASE64, - opts?: { - accountToSign?: string; - } - ) => Promise -} - -export type ClassOptions = { - contractId: string - networkPassphrase: string - rpcUrl: string - errorTypes?: Record - /** - * A Wallet interface, such as Freighter, that has the methods `isConnected`, `isAllowed`, `getUserInfo`, and `signTransaction`. If not provided, will attempt to import and use Freighter. Example: - * - * @example - * ```ts - * import freighter from "@stellar/freighter-api"; - * import { Contract } from "test_custom_types"; - * const contract = new Contract({ - * …, - * wallet: freighter, - * }) - * ``` - */ - wallet?: Wallet -} - -export type MethodOptions = { - /** - * The fee to pay for the transaction. Default: soroban-sdk's BASE_FEE ('100') - */ - fee?: number -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/tsconfig.json b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/tsconfig.json deleted file mode 100644 index efd4c619..00000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/tsconfig.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - /* Language and Environment */ - "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - /* Modules */ - "module": "ESNext", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - /* Emit */ - "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./dist", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - // "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - // "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - /* Type Checking */ - // "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - }, - "include": [ - "src/*" - ] -} diff --git a/cmd/crates/soroban-spec-typescript/src/boilerplate.rs b/cmd/crates/soroban-spec-typescript/src/boilerplate.rs deleted file mode 100644 index 7ffe6418..00000000 --- a/cmd/crates/soroban-spec-typescript/src/boilerplate.rs +++ /dev/null @@ -1,218 +0,0 @@ -#![allow(non_snake_case)] -use heck::{ToLowerCamelCase, ToShoutySnakeCase}; -use include_dir::{include_dir, Dir}; -use std::{ - fs, - io::Write, - path::{Path, PathBuf}, -}; -use stellar_xdr::curr::ScSpecEntry; - -use super::generate; - -static PROJECT_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/src/project_template"); - -const NETWORK_PASSPHRASE_TESTNET: &str = "Test SDF Network ; September 2015"; -const NETWORK_PASSPHRASE_FUTURENET: &str = "Test SDF Future Network ; October 2022"; -const NETWORK_PASSPHRASE_STANDALONE: &str = "Standalone Network ; February 2017"; - -pub struct Project(PathBuf); - -impl TryInto for PathBuf { - type Error = std::io::Error; - - fn try_into(self) -> Result { - PROJECT_DIR.extract(&self)?; - Ok(Project(self)) - } -} - -impl AsRef for Project { - fn as_ref(&self) -> &Path { - self.0.as_ref() - } -} - -impl Project { - /// Initialize a new JS client project, updating placeholder strings in the template and - /// appending functions for each method in the contract to the index.ts file. - /// - /// # Arguments - /// - /// * `contract_name` - The colloquial name of this contract that will be used in the README and package.json - /// * `contract_id` - The ID/address of the contract on the network. Will be overridable with environment variables. - /// * `rpc_url` - The RPC URL of the network where this contract is deployed. Will be overridable with environment variables. - /// * `network_passphrase` - The passphrase of the network where this contract is deployed. Will be overridable with environment variables. - /// * `spec` - The contract specification. - pub fn init( - &self, - contract_name: &str, - contract_id: &str, - rpc_url: &str, - network_passphrase: &str, - spec: &[ScSpecEntry], - ) -> std::io::Result<()> { - self.replace_placeholder_patterns(contract_name, contract_id, rpc_url, network_passphrase)?; - self.append_index_ts(spec, contract_id, network_passphrase) - } - - fn replace_placeholder_patterns( - &self, - contract_name: &str, - contract_id: &str, - rpc_url: &str, - network_passphrase: &str, - ) -> std::io::Result<()> { - let replacement_strings = &[ - ("INSERT_CONTRACT_NAME_HERE", contract_name), - ( - "INSERT_SCREAMING_SNAKE_CASE_CONTRACT_NAME_HERE", - &contract_name.to_shouty_snake_case(), - ), - ( - "INSERT_CAMEL_CASE_CONTRACT_NAME_HERE", - &contract_name.to_lower_camel_case(), - ), - ("INSERT_CONTRACT_ID_HERE", contract_id), - ("INSERT_NETWORK_PASSPHRASE_HERE", network_passphrase), - ("INSERT_RPC_URL_HERE", rpc_url), - ]; - let root: &Path = self.as_ref(); - [ - "package.json", - "README.md", - "src/assembled-tx.ts", - "src/index.ts", - "src/method-options.ts", - ] - .into_iter() - .try_for_each(|file_name| { - let file = &root.join(file_name); - let mut contents = fs::read_to_string(file).unwrap(); - for (pattern, replacement) in replacement_strings { - contents = contents.replace(pattern, replacement); - } - fs::write(file, contents) - }) - } - - fn append_index_ts( - &self, - spec: &[ScSpecEntry], - contract_id: &str, - network_passphrase: &str, - ) -> std::io::Result<()> { - let networks = Project::format_networks_object(contract_id, network_passphrase); - let types_and_fns = generate(spec); - fs::OpenOptions::new() - .append(true) - .open(self.0.join("src/index.ts"))? - .write_all(format!("\n\n{networks}\n\n{types_and_fns}").as_bytes()) - } - - fn format_networks_object(contract_id: &str, network_passphrase: &str) -> String { - let network = match network_passphrase { - NETWORK_PASSPHRASE_TESTNET => "testnet", - NETWORK_PASSPHRASE_FUTURENET => "futurenet", - NETWORK_PASSPHRASE_STANDALONE => "standalone", - _ => "unknown", - }; - format!( - r#"export const networks = {{ - {network}: {{ - networkPassphrase: "{network_passphrase}", - contractId: "{contract_id}", - }} -}} as const"# - ) - } -} - -#[cfg(test)] -mod test { - use temp_dir::TempDir; - use walkdir::WalkDir; - - use super::*; - - const EXAMPLE_WASM: &[u8] = include_bytes!( - "../../../../target/wasm32-unknown-unknown/test-wasms/test_custom_types.wasm" - ); - - fn init(root: impl AsRef) -> std::io::Result { - let spec = soroban_spec::read::from_wasm(EXAMPLE_WASM).unwrap(); - let p: Project = root.as_ref().to_path_buf().try_into()?; - p.init( - "test_custom_types", - "CA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAXE", - "https://rpc-futurenet.stellar.org:443", - "Test SDF Future Network ; October 2022", - &spec, - ) - .unwrap(); - Ok(p) - } - - // TODO : fix the test below : - // the test below should verify only a certain subset of the files were copied - // rather then the entire directory. - #[ignore] - #[test] - fn test_project_dir_location() { - // TODO: Ensure windows support - if cfg!(windows) { - return; - } - let temp_dir = TempDir::new().unwrap(); - let _: Project = init(temp_dir.path()).unwrap(); - let fixture = PathBuf::from("./fixtures/test_custom_types"); - assert_dirs_equal(temp_dir.path(), &fixture); - } - - #[ignore] - #[test] - fn build_package() { - let root = PathBuf::from("./fixtures/ts"); - std::fs::remove_dir_all(&root).unwrap_or_default(); - std::fs::create_dir_all(&root).unwrap(); - let _: Project = init(&root).unwrap(); - println!("Updated Snapshot!"); - } - - fn assert_dirs_equal>(dir1: P, dir2: P) { - let walker1 = WalkDir::new(&dir1); - let walker2 = WalkDir::new(&dir2); - - let mut paths1: Vec<_> = walker1.into_iter().collect::>().unwrap(); - let mut paths2: Vec<_> = walker2.into_iter().collect::>().unwrap(); - - paths1 - .sort_unstable_by_key(|entry| entry.path().strip_prefix(&dir1).unwrap().to_path_buf()); - paths2 - .sort_unstable_by_key(|entry| entry.path().strip_prefix(&dir2).unwrap().to_path_buf()); - - assert_eq!( - paths1.len(), - paths2.len(), - "{paths1:?}.len() != {paths2:?}.len()" - ); - - for (entry1, entry2) in paths1.iter().zip(paths2.iter()) { - let path1 = entry1.path(); - let path2 = entry2.path(); - - if path1.is_file() && path2.is_file() { - let content1 = fs::read_to_string(path1).unwrap(); - let content2 = fs::read_to_string(path2).unwrap(); - pretty_assertions::assert_eq!(content1, content2, "{:?} != {:?}", path1, path2); - } else if path1.is_dir() && path2.is_dir() { - continue; - } else { - panic!( - "{:?} is not a file", - if path1.is_file() { path2 } else { path1 } - ); - } - } - } -} diff --git a/cmd/crates/soroban-spec-typescript/src/lib.rs b/cmd/crates/soroban-spec-typescript/src/lib.rs deleted file mode 100644 index 790f43b0..00000000 --- a/cmd/crates/soroban-spec-typescript/src/lib.rs +++ /dev/null @@ -1,377 +0,0 @@ -#![allow( - clippy::missing_errors_doc, - clippy::must_use_candidate, - clippy::missing_panics_doc -)] - -use std::{fs, io}; - -use crate::types::Type; -use heck::ToLowerCamelCase; -use itertools::Itertools; -use sha2::{Digest, Sha256}; -use stellar_xdr::curr::{Limits, ScSpecEntry, WriteXdr}; - -use types::Entry; - -use soroban_spec::read::{from_wasm, FromWasmError}; - -pub mod boilerplate; -mod types; -pub mod wrapper; - -#[derive(thiserror::Error, Debug)] -pub enum GenerateFromFileError { - #[error("reading file: {0}")] - Io(io::Error), - #[error("sha256 does not match, expected: {expected}")] - VerifySha256 { expected: String }, - #[error("parsing contract spec: {0}")] - Parse(stellar_xdr::curr::Error), - #[error("getting contract spec: {0}")] - GetSpec(FromWasmError), -} - -pub fn generate_from_file( - file: &str, - verify_sha256: Option<&str>, -) -> Result { - // Read file. - let wasm = fs::read(file).map_err(GenerateFromFileError::Io)?; - - // Produce hash for file. - let sha256 = Sha256::digest(&wasm); - let sha256 = format!("{sha256:x}"); - - if let Some(verify_sha256) = verify_sha256 { - if verify_sha256 != sha256 { - return Err(GenerateFromFileError::VerifySha256 { expected: sha256 }); - } - } - - // Generate code. - let json = generate_from_wasm(&wasm).map_err(GenerateFromFileError::GetSpec)?; - Ok(json) -} - -pub fn generate_from_wasm(wasm: &[u8]) -> Result { - let spec = from_wasm(wasm)?; - let json = generate(&spec); - Ok(json) -} - -fn generate_class(fns: &[Entry], spec: &[ScSpecEntry]) -> String { - let methods = fns.iter().map(entry_to_method).join("\n\n "); - let parsers = fns - .iter() - .filter_map(entry_to_parser) - .map(|(method, parser)| format!("{method}: {parser}")) - .join(",\n "); - let from_jsons = fns - .iter() - .filter_map(entry_to_parser) - .map(|(method, _)| { - format!("{method}: this.txFromJSON>") - }) - .join(",\n "); - let spec = spec - .iter() - .map(|s| format!("\"{}\"", s.to_xdr_base64(Limits::none()).unwrap())) - .join(",\n "); - format!( - r#"export class Contract {{ - spec: ContractSpec; - constructor(public readonly options: ClassOptions) {{ - this.spec = new ContractSpec([ - {spec} - ]); - }} - private readonly parsers = {{ - {parsers} - }}; - private txFromJSON = (json: string): AssembledTransaction => {{ - const {{ method, ...tx }} = JSON.parse(json) - return AssembledTransaction.fromJSON( - {{ - ...this.options, - method, - parseResultXdr: this.parsers[method], - }}, - tx, - ); - }} - public readonly fromJSON = {{ - {from_jsons} - }} - {methods} -}}"#, - ) -} - -pub fn generate(spec: &[ScSpecEntry]) -> String { - let mut collected: Vec<_> = spec.iter().map(Entry::from).collect(); - if !spec.iter().any(is_error_enum) { - collected.push(Entry::ErrorEnum { - doc: String::new(), - name: "Error".to_string(), - cases: vec![], - }); - } - let (fns, other): (Vec<_>, Vec<_>) = collected - .into_iter() - .partition(|entry| matches!(entry, Entry::Function { .. })); - let top = other.iter().map(entry_to_method).join("\n"); - let bottom = generate_class(&fns, spec); - format!("{top}\n\n{bottom}") -} - -fn doc_to_ts_doc(doc: &str, method: Option<&str>) -> String { - let header = if let Some(method) = method { - format!( - r#"/** - * Construct and simulate a {method} transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object."# - ) - } else { - "/**\n ".to_string() - }; - let footer = "\n */\n"; - let body = if doc.is_empty() { - String::new() - } else { - doc.split('\n').join("\n * ") - }; - format!(r#"{header}{body}{footer}"#) -} - -fn is_error_enum(entry: &ScSpecEntry) -> bool { - matches!(entry, ScSpecEntry::UdtErrorEnumV0(_)) -} - -const METHOD_OPTIONS: &str = r"{ - /** - * The fee to pay for the transaction. Default: 100. - */ - fee?: number, - }"; - -fn jsify_name(name: &String) -> String { - name.to_lower_camel_case() -} - -pub fn entry_to_parser(entry: &Entry) -> Option<(String, String)> { - if let Entry::Function { name, outputs, .. } = entry { - let mut is_result = false; - let mut return_type: String; - if outputs.is_empty() { - return_type = "void".to_owned(); - } else if outputs.len() == 1 { - return_type = type_to_ts(&outputs[0]); - is_result = return_type.starts_with("Result<"); - } else { - return_type = format!("readonly [{}]", outputs.iter().map(type_to_ts).join(", ")); - }; - - if is_result { - return_type = return_type - .strip_prefix("Result<") - .unwrap() - .strip_suffix('>') - .unwrap() - .to_owned(); - return_type = format!("Ok<{return_type}> | Err"); - } - - let output = outputs - .first() - .map(|_| format!("this.spec.funcResToNative(\"{name}\", result)")) - .unwrap_or_default(); - let parse_result_xdr = if return_type == "void" { - r"() => {}".to_owned() - } else if is_result { - format!( - r"(result: XDR_BASE64 | Err): {return_type} => {{ - if (result instanceof Err) return result - return new Ok({output}) - }}" - ) - } else { - format!(r"(result: XDR_BASE64): {return_type} => {output}") - }; - let js_name = jsify_name(name); - Some((js_name, parse_result_xdr)) - } else { - None - } -} - -#[allow(clippy::too_many_lines)] -pub fn entry_to_method(entry: &Entry) -> String { - match entry { - Entry::Function { - doc, name, inputs, .. - } => { - let input_vals = inputs.iter().map(func_input_to_arg_name).join(", "); - let input = (!inputs.is_empty()) - .then(|| { - format!( - "{{{input_vals}}}: {{{}}}, ", - inputs.iter().map(func_input_to_ts).join(", ") - ) - }) - .unwrap_or_default(); - let ts_doc = doc_to_ts_doc(doc, Some(name)); - let (js_name, _) = entry_to_parser(entry).unwrap(); - let parsed_scvals = inputs.iter().map(parse_arg_to_scval).join(", "); - let args = - format!("args: this.spec.funcArgsToScVals(\"{name}\", {{{parsed_scvals}}}),"); - let body = format!( - r#"return await AssembledTransaction.fromSimulation({{ - method: '{name}', - {args} - ...options, - ...this.options, - errorTypes: Errors, - parseResultXdr: this.parsers['{js_name}'], - }});"# - ); - format!( - r#" {ts_doc} {js_name} = async ({input}options: {METHOD_OPTIONS} = {{}}) => {{ - {body} - }} -"# - ) - } - Entry::Struct { doc, name, fields } => { - let docs = doc_to_ts_doc(doc, None); - let fields = fields.iter().map(field_to_ts).join("\n "); - format!( - r#"{docs}export interface {name} {{ - {fields} -}} -"# - ) - } - - Entry::TupleStruct { doc, name, fields } => { - let docs = doc_to_ts_doc(doc, None); - let fields = fields.iter().map(type_to_ts).join(", "); - format!("{docs}export type {name} = readonly [{fields}];") - } - - Entry::Union { name, doc, cases } => { - let doc = doc_to_ts_doc(doc, None); - let cases = cases.iter().map(case_to_ts).join(" | "); - - format!( - r#"{doc}export type {name} = {cases}; -"# - ) - } - Entry::Enum { doc, name, cases } => { - let doc = doc_to_ts_doc(doc, None); - let cases = cases.iter().map(enum_case_to_ts).join("\n "); - let name = (name == "Error") - .then(|| format!("{name}s")) - .unwrap_or(name.to_string()); - format!( - r#"{doc}export enum {name} {{ - {cases} -}} -"#, - ) - } - Entry::ErrorEnum { doc, cases, .. } => { - let doc = doc_to_ts_doc(doc, None); - let cases = cases - .iter() - .map(|c| format!("{}: {{message:\"{}\"}}", c.value, c.doc)) - .join(",\n "); - format!( - r#"{doc}export const Errors = {{ -{cases} -}}"# - ) - } - } -} - -fn enum_case_to_ts(case: &types::EnumCase) -> String { - let types::EnumCase { name, value, .. } = case; - format!("{name} = {value},") -} - -fn case_to_ts(case: &types::UnionCase) -> String { - let types::UnionCase { name, values, .. } = case; - format!( - "{{tag: \"{name}\", values: {}}}", - type_to_ts(&Type::Tuple { - elements: values.clone(), - }) - ) -} - -fn field_to_ts(field: &types::StructField) -> String { - let types::StructField { doc, name, value } = field; - let doc = doc_to_ts_doc(doc, None); - let type_ = type_to_ts(value); - format!("{doc}{name}: {type_};") -} - -pub fn func_input_to_ts(input: &types::FunctionInput) -> String { - let types::FunctionInput { name, value, .. } = input; - let type_ = type_to_ts(value); - format!("{name}: {type_}") -} - -pub fn func_input_to_arg_name(input: &types::FunctionInput) -> String { - let types::FunctionInput { name, .. } = input; - name.to_string() -} - -pub fn parse_arg_to_scval(input: &types::FunctionInput) -> String { - let types::FunctionInput { name, value, .. } = input; - match value { - types::Type::Address => format!("{name}: new Address({name})"), - _ => name.to_string(), - } -} - -pub fn type_to_ts(value: &types::Type) -> String { - match value { - types::Type::U64 => "u64".to_owned(), - types::Type::I64 => "i64".to_owned(), - types::Type::U128 => "u128".to_owned(), - types::Type::I128 => "i128".to_owned(), - types::Type::U32 => "u32".to_owned(), - types::Type::I32 => "i32".to_owned(), - types::Type::Bool => "boolean".to_owned(), - types::Type::Symbol | types::Type::String => "string".to_owned(), - types::Type::Map { key, value } => { - format!("Map<{}, {}>", type_to_ts(key), type_to_ts(value)) - } - types::Type::Option { value } => format!("Option<{}>", type_to_ts(value)), - types::Type::Result { value, .. } => { - format!("Result<{}>", type_to_ts(value)) - } - types::Type::Vec { element } => format!("Array<{}>", type_to_ts(element)), - types::Type::Tuple { elements } => { - if elements.is_empty() { - "void".to_owned() - } else { - format!("readonly [{}]", elements.iter().map(type_to_ts).join(", ")) - } - } - types::Type::Custom { name } => name.clone(), - // TODO: Figure out what js type to map this to. There is already an `Error_` one that - // ahalabs have added in the bindings, so.. maybe rename that? - types::Type::Val => "any".to_owned(), - types::Type::Error { .. } => "Error_".to_owned(), - types::Type::Address => "string".to_string(), - types::Type::Bytes | types::Type::BytesN { .. } => "Buffer".to_string(), - types::Type::Void => "void".to_owned(), - types::Type::U256 => "u256".to_string(), - types::Type::I256 => "i256".to_string(), - types::Type::Timepoint => "Timepoint".to_string(), - types::Type::Duration => "Duration".to_string(), - } -} diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/.gitignore b/cmd/crates/soroban-spec-typescript/src/project_template/.gitignore deleted file mode 100644 index 72aae85f..00000000 --- a/cmd/crates/soroban-spec-typescript/src/project_template/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -out/ diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/README.md b/cmd/crates/soroban-spec-typescript/src/project_template/README.md deleted file mode 100644 index 3995e52b..00000000 --- a/cmd/crates/soroban-spec-typescript/src/project_template/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# INSERT_CONTRACT_NAME_HERE JS - -JS library for interacting with [Soroban](https://soroban.stellar.org/) smart contract `INSERT_CONTRACT_NAME_HERE` via Soroban RPC. - -This library was automatically generated by Soroban CLI using a command similar to: - -```bash -soroban contract bindings ts \ - --rpc-url INSERT_RPC_URL_HERE \ - --network-passphrase "INSERT_NETWORK_PASSPHRASE_HERE" \ - --contract-id INSERT_CONTRACT_ID_HERE \ - --output-dir ./path/to/INSERT_CONTRACT_NAME_HERE -``` - -The network passphrase and contract ID are exported from [index.ts](./src/index.ts) in the `networks` constant. If you are the one who generated this library and you know that this contract is also deployed to other networks, feel free to update `networks` with other valid options. This will help your contract consumers use this library more easily. - -# To publish or not to publish - -This library is suitable for publishing to NPM. You can publish it to NPM using the `npm publish` command. - -But you don't need to publish this library to NPM to use it. You can add it to your project's `package.json` using a file path: - -```json -"dependencies": { - "INSERT_CONTRACT_NAME_HERE": "./path/to/this/folder" -} -``` - -However, we've actually encountered [frustration](https://github.com/stellar/soroban-example-dapp/pull/117#discussion_r1232873560) using local libraries with NPM in this way. Though it seems a bit messy, we suggest generating the library directly to your `node_modules` folder automatically after each install by using a `postinstall` script. We've had the least trouble with this approach. NPM will automatically remove what it sees as erroneous directories during the `install` step, and then regenerate them when it gets to your `postinstall` step, which will keep the library up-to-date with your contract. - -```json -"scripts": { - "postinstall": "soroban contract bindings ts --rpc-url INSERT_RPC_URL_HERE --network-passphrase \"INSERT_NETWORK_PASSPHRASE_HERE\" --id INSERT_CONTRACT_ID_HERE --name INSERT_CONTRACT_NAME_HERE" -} -``` - -Obviously you need to adjust the above command based on the actual command you used to generate the library. - -# Use it - -Now that you have your library up-to-date and added to your project, you can import it in a file and see inline documentation for all of its exported methods: - -```js -import { Contract, networks } from "INSERT_CONTRACT_NAME_HERE" - -const contract = new Contract({ - ...networks.futurenet, // for example; check which networks this library exports - rpcUrl: '...', // use your own, or find one for testing at https://soroban.stellar.org/docs/reference/rpc#public-rpc-providers -}) - -contract.| -``` - -As long as your editor is configured to show JavaScript/TypeScript documentation, you can pause your typing at that `|` to get a list of all exports and inline-documentation for each. It exports a separate [async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) function for each method in the smart contract, with documentation for each generated from the comments the contract's author included in the original source code. diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/package.json b/cmd/crates/soroban-spec-typescript/src/project_template/package.json deleted file mode 100644 index e32d0f5e..00000000 --- a/cmd/crates/soroban-spec-typescript/src/project_template/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "0.0.0", - "name": "INSERT_CONTRACT_NAME_HERE", - "dependencies": { - "@stellar/freighter-api": "1.7.1", - "buffer": "6.0.3", - "@stellar/stellar-sdk": "11.2.0" - }, - "scripts": { - "build": "node ./scripts/build.mjs" - }, - "exports": { - "require": "./dist/cjs/index.js", - "import": "./dist/esm/index.js" - }, - "typings": "dist/types/index.d.ts", - "devDependencies": { - "typescript": "5.3.3" - } -} diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/scripts/build.mjs b/cmd/crates/soroban-spec-typescript/src/project_template/scripts/build.mjs deleted file mode 100644 index 15a17042..00000000 --- a/cmd/crates/soroban-spec-typescript/src/project_template/scripts/build.mjs +++ /dev/null @@ -1,37 +0,0 @@ -import { spawnSync } from "node:child_process" -import fs from "node:fs" -import path from "node:path" - -const buildDir = "./dist" - -const { error, stderr } = spawnSync("tsc", ["-b", "./scripts/tsconfig.cjs.json", "./scripts/tsconfig.esm.json", "./scripts/tsconfig.types.json"], { stdio: "inherit" }) - -if (error) { - console.error(stderr) - console.error(error) - throw error -} - -function createEsmModulePackageJson() { - fs.readdir(buildDir, function (err, dirs) { - if (err) { - throw err - } - dirs.forEach(function (dir) { - if (dir === "esm") { - // 1. add package.json file with "type": "module" - var packageJsonFile = path.join(buildDir, dir, "/package.json") - if (!fs.existsSync(packageJsonFile)) { - fs.writeFileSync( - packageJsonFile, - '{"type": "module"}', - 'utf8', - err => { if (err) throw err } - ) - } - } - }) - }) -} - -createEsmModulePackageJson() diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/scripts/tsconfig.cjs.json b/cmd/crates/soroban-spec-typescript/src/project_template/scripts/tsconfig.cjs.json deleted file mode 100644 index 542ea86d..00000000 --- a/cmd/crates/soroban-spec-typescript/src/project_template/scripts/tsconfig.cjs.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../dist/cjs", - "module": "commonjs" - } -} diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/scripts/tsconfig.esm.json b/cmd/crates/soroban-spec-typescript/src/project_template/scripts/tsconfig.esm.json deleted file mode 100644 index 92b45277..00000000 --- a/cmd/crates/soroban-spec-typescript/src/project_template/scripts/tsconfig.esm.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../dist/esm", - "module": "esnext" - } -} diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/scripts/tsconfig.types.json b/cmd/crates/soroban-spec-typescript/src/project_template/scripts/tsconfig.types.json deleted file mode 100644 index 8a24fc13..00000000 --- a/cmd/crates/soroban-spec-typescript/src/project_template/scripts/tsconfig.types.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../dist/types", - "declaration": true, - "emitDeclarationOnly": true - } -} diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/src/assembled-tx.ts b/cmd/crates/soroban-spec-typescript/src/project_template/src/assembled-tx.ts deleted file mode 100644 index f4f892d4..00000000 --- a/cmd/crates/soroban-spec-typescript/src/project_template/src/assembled-tx.ts +++ /dev/null @@ -1,664 +0,0 @@ -import { - Account, - Address, - Contract, - Operation, - SorobanRpc, - StrKey, - TimeoutInfinite, - TransactionBuilder, - authorizeEntry, - hash, - nativeToScVal, - xdr, - BASE_FEE, -} from "@stellar/stellar-sdk"; -import type { Memo, MemoType, Transaction } from "@stellar/stellar-sdk"; -import { Buffer } from "buffer"; -import type { - ClassOptions, - MethodOptions, - Wallet, - XDR_BASE64, -} from "./method-options.js"; - -export type Tx = Transaction, Operation[]> - -export class ExpiredStateError extends Error { } -export class NeedsMoreSignaturesError extends Error { } -export class WalletDisconnectedError extends Error { } -export class SendResultOnlyError extends Error { } -export class SendFailedError extends Error { } -export class NoUnsignedNonInvokerAuthEntriesError extends Error { } - -type SendTx = SorobanRpc.Api.SendTransactionResponse; -type GetTx = SorobanRpc.Api.GetTransactionResponse; - -export type u32 = number; -export type i32 = number; -export type u64 = bigint; -export type i64 = bigint; -export type u128 = bigint; -export type i128 = bigint; -export type u256 = bigint; -export type i256 = bigint; -export type Option = T | undefined; -export type Typepoint = bigint; -export type Duration = bigint; -export {Address}; - -/// Error interface containing the error message -export interface Error_ { message: string }; - -export interface Result { - unwrap(): T, - unwrapErr(): E, - isOk(): boolean, - isErr(): boolean, -}; - -export class Ok implements Result { - constructor(readonly value: T) { } - unwrapErr(): E { - throw new Error('No error'); - } - unwrap(): T { - return this.value; - } - - isOk(): boolean { - return true; - } - - isErr(): boolean { - return !this.isOk() - } -} - -export class Err implements Result { - constructor(readonly error: E) { } - unwrapErr(): E { - return this.error; - } - unwrap(): never { - throw new Error(this.error.message); - } - - isOk(): boolean { - return false; - } - - isErr(): boolean { - return !this.isOk() - } -} - -export const contractErrorPattern = /Error\(Contract, #(\d+)\)/; - -type AssembledTransactionOptions = MethodOptions & - ClassOptions & { - method: string; - args?: any[]; - parseResultXdr: (xdr: string | xdr.ScVal | Err) => T; - }; - -export const NULL_ACCOUNT = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF" - -export class AssembledTransaction { - public raw: Tx - private simulation?: SorobanRpc.Api.SimulateTransactionResponse - private simulationResult?: SorobanRpc.Api.SimulateHostFunctionResult - private simulationTransactionData?: xdr.SorobanTransactionData - private server: SorobanRpc.Server - - toJSON() { - return JSON.stringify({ - method: this.options.method, - tx: this.raw?.toXDR(), - simulationResult: { - auth: this.simulationData.result.auth.map(a => a.toXDR('base64')), - retval: this.simulationData.result.retval.toXDR('base64'), - }, - simulationTransactionData: this.simulationData.transactionData.toXDR('base64'), - }) - } - - static fromJSON( - options: Omit, 'args'>, - { tx, simulationResult, simulationTransactionData }: - { - tx: XDR_BASE64, - simulationResult: { - auth: XDR_BASE64[], - retval: XDR_BASE64, - }, - simulationTransactionData: XDR_BASE64, - } - ): AssembledTransaction { - const txn = new AssembledTransaction(options) - txn.raw = TransactionBuilder.fromXDR(tx, options.networkPassphrase) as Tx - txn.simulationResult = { - auth: simulationResult.auth.map(a => xdr.SorobanAuthorizationEntry.fromXDR(a, 'base64')), - retval: xdr.ScVal.fromXDR(simulationResult.retval, 'base64'), - } - txn.simulationTransactionData = xdr.SorobanTransactionData.fromXDR(simulationTransactionData, 'base64') - return txn - } - - private constructor(public options: AssembledTransactionOptions) { - this.server = new SorobanRpc.Server(this.options.rpcUrl, { - allowHttp: this.options.rpcUrl.startsWith("http://"), - }); - } - - static async fromSimulation(options: AssembledTransactionOptions): Promise> { - const tx = new AssembledTransaction(options) - const contract = new Contract(options.contractId); - - tx.raw = new TransactionBuilder(await tx.getAccount(), { - fee: options.fee?.toString(10) ?? BASE_FEE, - networkPassphrase: options.networkPassphrase, - }) - .addOperation(contract.call(options.method, ...(options.args ?? []))) - .setTimeout(TimeoutInfinite) - .build(); - - return await tx.simulate() - } - - simulate = async (): Promise => { - if (!this.raw) throw new Error('Transaction has not yet been assembled') - this.simulation = await this.server.simulateTransaction(this.raw); - - if (SorobanRpc.Api.isSimulationSuccess(this.simulation)) { - this.raw = SorobanRpc.assembleTransaction( - this.raw, - this.simulation - ).build() - } - - return this - } - - get simulationData(): { - result: SorobanRpc.Api.SimulateHostFunctionResult - transactionData: xdr.SorobanTransactionData - } { - if (this.simulationResult && this.simulationTransactionData) { - return { - result: this.simulationResult, - transactionData: this.simulationTransactionData, - } - } - // else, we know we just did the simulation on this machine - const simulation = this.simulation! - if (SorobanRpc.Api.isSimulationError(simulation)) { - throw new Error(`Transaction simulation failed: "${simulation.error}"`) - } - - if (SorobanRpc.Api.isSimulationRestore(simulation)) { - throw new ExpiredStateError(`You need to restore some contract state before you can invoke this method. ${JSON.stringify(simulation, null, 2)}`) - } - - if (!simulation.result) { - throw new Error(`Expected an invocation simulation, but got no 'result' field. Simulation: ${JSON.stringify(simulation, null, 2)}`) - } - - // add to object for serialization & deserialization - this.simulationResult = simulation.result - this.simulationTransactionData = simulation.transactionData.build() - - return { - result: this.simulationResult, - transactionData: this.simulationTransactionData!, - } - } - - get result(): T { - try { - return this.options.parseResultXdr(this.simulationData.result.retval) - } catch (e) { - let err = this.parseError(e.toString()) - if (err) return err as T - throw e - } - } - - parseError(errorMessage: string): Err | undefined { - if (!this.options.errorTypes) return - const match = errorMessage.match(contractErrorPattern) - if (!match) return - let i = parseInt(match[1], 10) - let err = this.options.errorTypes[i] - if (err) return new Err(err) - } - - getWallet = async (): Promise => { - return this.options.wallet ?? (await import("@stellar/freighter-api")).default - } - - getPublicKey = async (): Promise => { - const wallet = await this.getWallet() - if (await wallet.isConnected() && await wallet.isAllowed()) { - return (await wallet.getUserInfo()).publicKey - } - } - - /** - * Get account details from the Soroban network for the publicKey currently - * selected in user's wallet. If not connected to Freighter, use placeholder - * null account. - */ - getAccount = async (): Promise => { - const publicKey = await this.getPublicKey() - return publicKey - ? await this.server.getAccount(publicKey) - : new Account(NULL_ACCOUNT, "0") - } - - /** - * Sign the transaction with the `wallet` (default Freighter), then send to - * the network and return a `SentTransaction` that keeps track of all the - * attempts to send and fetch the transaction from the network. - */ - signAndSend = async ({ secondsToWait = 10, force = false }: { - /** - * Wait `secondsToWait` seconds (default: 10) for both the transaction to SEND successfully (will keep trying if the server returns `TRY_AGAIN_LATER`), as well as for the transaction to COMPLETE (will keep checking if the server returns `PENDING`). - */ - secondsToWait?: number - /** - * If `true`, sign and send the transaction even if it is a read call. - */ - force?: boolean - } = {}): Promise> => { - if (!this.raw) { - throw new Error('Transaction has not yet been simulated') - } - - if (!force && this.isReadCall) { - throw new Error('This is a read call. It requires no signature or sending. Use `force: true` to sign and send anyway.') - } - - if (!await this.hasRealInvoker()) { - throw new WalletDisconnectedError('Wallet is not connected') - } - - if (this.raw.source !== (await this.getAccount()).accountId()) { - throw new Error(`You must submit the transaction with the account that originally created it. Please switch to the wallet with "${this.raw.source}" as its public key.`) - } - - if ((await this.needsNonInvokerSigningBy()).length) { - throw new NeedsMoreSignaturesError( - 'Transaction requires more signatures. See `needsNonInvokerSigningBy` for details.' - ) - } - - return await SentTransaction.init(this.options, this, secondsToWait); - } - - getStorageExpiration = async () => { - const entryRes = await this.server.getLedgerEntries( - new Contract(this.options.contractId).getFootprint() - ) - if ( - !entryRes.entries || - !entryRes.entries.length || - !entryRes.entries[0].liveUntilLedgerSeq - ) throw new Error('failed to get ledger entry') - return entryRes.entries[0].liveUntilLedgerSeq - } - - /** - * Get a list of accounts, other than the invoker of the simulation, that - * need to sign auth entries in this transaction. - * - * Soroban allows multiple people to sign a transaction. Someone needs to - * sign the final transaction envelope; this person/account is called the - * _invoker_, or _source_. Other accounts might need to sign individual auth - * entries in the transaction, if they're not also the invoker. - * - * This function returns a list of accounts that need to sign auth entries, - * assuming that the same invoker/source account will sign the final - * transaction envelope as signed the initial simulation. - * - * One at a time, for each public key in this array, you will need to - * serialize this transaction with `toJSON`, send to the owner of that key, - * deserialize the transaction with `txFromJson`, and call - * {@link signAuthEntries}. Then re-serialize and send to the next account - * in this list. - */ - needsNonInvokerSigningBy = async ({ - includeAlreadySigned = false, - }: { - /** - * Whether or not to include auth entries that have already been signed. Default: false - */ - includeAlreadySigned?: boolean - } = {}): Promise => { - if (!this.raw) { - throw new Error('Transaction has not yet been simulated') - } - - // We expect that any transaction constructed by these libraries has a - // single operation, which is an InvokeHostFunction operation. The host - // function being invoked is the contract method call. - if (!("operations" in this.raw)) { - throw new Error( - `Unexpected Transaction type; no operations: ${JSON.stringify(this.raw) - }` - ) - } - const rawInvokeHostFunctionOp = this.raw - .operations[0] as Operation.InvokeHostFunction - - return [...new Set((rawInvokeHostFunctionOp.auth ?? []).filter(entry => - entry.credentials().switch() === - xdr.SorobanCredentialsType.sorobanCredentialsAddress() && - ( - includeAlreadySigned || - entry.credentials().address().signature().switch().name === 'scvVoid' - ) - ).map(entry => StrKey.encodeEd25519PublicKey( - entry.credentials().address().address().accountId().ed25519() - )))] - } - - preImageFor( - entry: xdr.SorobanAuthorizationEntry, - signatureExpirationLedger: number - ): xdr.HashIdPreimage { - const addrAuth = entry.credentials().address() - return xdr.HashIdPreimage.envelopeTypeSorobanAuthorization( - new xdr.HashIdPreimageSorobanAuthorization({ - networkId: hash(Buffer.from(this.options.networkPassphrase)), - nonce: addrAuth.nonce(), - invocation: entry.rootInvocation(), - signatureExpirationLedger, - }), - ) - } - - /** - * If {@link needsNonInvokerSigningBy} returns a non-empty list, you can serialize - * the transaction with `toJSON`, send it to the owner of one of the public keys - * in the map, deserialize with `txFromJSON`, and call this method on their - * machine. Internally, this will use `signAuthEntry` function from connected - * `wallet` for each. - * - * Then, re-serialize the transaction and either send to the next - * `needsNonInvokerSigningBy` owner, or send it back to the original account - * who simulated the transaction so they can {@link sign} the transaction - * envelope and {@link send} it to the network. - * - * Sending to all `needsNonInvokerSigningBy` owners in parallel is not currently - * supported! - */ - signAuthEntries = async ( - /** - * When to set each auth entry to expire. Could be any number of blocks in - * the future. Can be supplied as a promise or a raw number. Default: - * contract's current `persistent` storage expiration date/ledger - * number/block. - */ - expiration: number | Promise = this.getStorageExpiration() - ): Promise => { - if (!this.raw) throw new Error('Transaction has not yet been assembled or simulated') - const needsNonInvokerSigningBy = await this.needsNonInvokerSigningBy() - - if (!needsNonInvokerSigningBy) throw new NoUnsignedNonInvokerAuthEntriesError('No unsigned non-invoker auth entries; maybe you already signed?') - const publicKey = await this.getPublicKey() - if (!publicKey) throw new Error('Could not get public key from wallet; maybe Freighter is not signed in?') - if (needsNonInvokerSigningBy.indexOf(publicKey) === -1) throw new Error(`No auth entries for public key "${publicKey}"`) - const wallet = await this.getWallet() - - const rawInvokeHostFunctionOp = this.raw - .operations[0] as Operation.InvokeHostFunction - - const authEntries = rawInvokeHostFunctionOp.auth ?? [] - - for (const [i, entry] of authEntries.entries()) { - if ( - entry.credentials().switch() !== - xdr.SorobanCredentialsType.sorobanCredentialsAddress() - ) { - // if the invoker/source account, then the entry doesn't need explicit - // signature, since the tx envelope is already signed by the source - // account, so only check for sorobanCredentialsAddress - continue - } - const pk = StrKey.encodeEd25519PublicKey( - entry.credentials().address().address().accountId().ed25519() - ) - - // this auth entry needs to be signed by a different account - // (or maybe already was!) - if (pk !== publicKey) continue - - authEntries[i] = await authorizeEntry( - entry, - async preimage => Buffer.from( - await wallet.signAuthEntry(preimage.toXDR('base64')), - 'base64' - ), - await expiration, - this.options.networkPassphrase - ) - } - } - - get isReadCall(): boolean { - const authsCount = this.simulationData.result.auth.length; - const writeLength = this.simulationData.transactionData.resources().footprint().readWrite().length - return (authsCount === 0) && (writeLength === 0); - } - - hasRealInvoker = async (): Promise => { - const account = await this.getAccount() - return account.accountId() !== NULL_ACCOUNT - } -} - -/** - * A transaction that has been sent to the Soroban network. This happens in two steps: - * - * 1. `sendTransaction`: initial submission of the transaction to the network. - * This step can run into problems, and will be retried with exponential - * backoff if it does. See all attempts in `sendTransactionResponseAll` and the - * most recent attempt in `sendTransactionResponse`. - * 2. `getTransaction`: once the transaction has been submitted to the network - * successfully, you need to wait for it to finalize to get the results of the - * transaction. This step can also run into problems, and will be retried with - * exponential backoff if it does. See all attempts in - * `getTransactionResponseAll` and the most recent attempt in - * `getTransactionResponse`. - */ -class SentTransaction { - public server: SorobanRpc.Server - public signed: Tx - public sendTransactionResponse?: SendTx - public sendTransactionResponseAll?: SendTx[] - public getTransactionResponse?: GetTx - public getTransactionResponseAll?: GetTx[] - - constructor(public options: AssembledTransactionOptions, public assembled: AssembledTransaction) { - this.server = new SorobanRpc.Server(this.options.rpcUrl, { - allowHttp: this.options.rpcUrl.startsWith("http://"), - }); - this.assembled = assembled - } - - static init = async ( - options: AssembledTransactionOptions, - assembled: AssembledTransaction, - secondsToWait: number = 10 - ): Promise> => { - const tx = new SentTransaction(options, assembled) - return await tx.send(secondsToWait) - } - - private send = async (secondsToWait: number = 10): Promise => { - const wallet = await this.assembled.getWallet() - - this.sendTransactionResponseAll = await withExponentialBackoff( - async (previousFailure) => { - if (previousFailure) { - // Increment transaction sequence number and resimulate before trying again - - // Soroban transaction can only have 1 operation - const op = this.assembled.raw.operations[0] as Operation.InvokeHostFunction; - - this.assembled.raw = new TransactionBuilder(await this.assembled.getAccount(), { - fee: this.assembled.raw.fee, - networkPassphrase: this.options.networkPassphrase, - }) - .setTimeout(TimeoutInfinite) - .addOperation( - Operation.invokeHostFunction({ ...op, auth: op.auth ?? [] }), - ) - .build() - - await this.assembled.simulate() - } - - const signature = await wallet.signTransaction(this.assembled.raw.toXDR(), { - networkPassphrase: this.options.networkPassphrase, - }); - - this.signed = TransactionBuilder.fromXDR( - signature, - this.options.networkPassphrase - ) as Tx - - return this.server.sendTransaction(this.signed) - }, - resp => resp.status !== "PENDING", - secondsToWait - ) - - this.sendTransactionResponse = this.sendTransactionResponseAll[this.sendTransactionResponseAll.length - 1] - - if (this.sendTransactionResponse.status !== "PENDING") { - throw new Error( - `Tried to resubmit transaction for ${secondsToWait - } seconds, but it's still failing. ` + - `All attempts: ${JSON.stringify( - this.sendTransactionResponseAll, - null, - 2 - )}` - ); - } - - const { hash } = this.sendTransactionResponse - - this.getTransactionResponseAll = await withExponentialBackoff( - () => this.server.getTransaction(hash), - resp => resp.status === SorobanRpc.Api.GetTransactionStatus.NOT_FOUND, - secondsToWait - ) - - this.getTransactionResponse = this.getTransactionResponseAll[this.getTransactionResponseAll.length - 1] - if (this.getTransactionResponse.status === SorobanRpc.Api.GetTransactionStatus.NOT_FOUND) { - console.error( - `Waited ${secondsToWait - } seconds for transaction to complete, but it did not. ` + - `Returning anyway. Check the transaction status manually. ` + - `Sent transaction: ${JSON.stringify( - this.sendTransactionResponse, - null, - 2 - )}\n` + - `All attempts to get the result: ${JSON.stringify( - this.getTransactionResponseAll, - null, - 2 - )}` - ); - } - - return this; - } - - get result(): T { - // 1. check if transaction was submitted and awaited with `getTransaction` - if ( - "getTransactionResponse" in this && - this.getTransactionResponse - ) { - // getTransactionResponse has a `returnValue` field unless it failed - if ("returnValue" in this.getTransactionResponse) { - return this.options.parseResultXdr(this.getTransactionResponse.returnValue!) - } - - // if "returnValue" not present, the transaction failed; return without parsing the result - throw new Error("Transaction failed! Cannot parse result.") - } - - // 2. otherwise, maybe it was merely sent with `sendTransaction` - if (this.sendTransactionResponse) { - const errorResult = this.sendTransactionResponse.errorResult?.result() - if (errorResult) { - throw new SendFailedError( - `Transaction simulation looked correct, but attempting to send the transaction failed. Check \`simulation\` and \`sendTransactionResponseAll\` to troubleshoot. Decoded \`sendTransactionResponse.errorResultXdr\`: ${errorResult}` - ) - } - throw new SendResultOnlyError( - `Transaction was sent to the network, but not yet awaited. No result to show. Await transaction completion with \`getTransaction(sendTransactionResponse.hash)\`` - ) - } - - // 3. finally, if neither of those are present, throw an error - throw new Error(`Sending transaction failed: ${JSON.stringify(this.assembled)}`) - } -} - -/** - * Keep calling a `fn` for `secondsToWait` seconds, if `keepWaitingIf` is true. - * Returns an array of all attempts to call the function. - */ -async function withExponentialBackoff( - fn: (previousFailure?: T) => Promise, - keepWaitingIf: (result: T) => boolean, - secondsToWait: number, - exponentialFactor = 1.5, - verbose = false, -): Promise { - const attempts: T[] = [] - - let count = 0 - attempts.push(await fn()) - if (!keepWaitingIf(attempts[attempts.length - 1])) return attempts - - const waitUntil = new Date(Date.now() + secondsToWait * 1000).valueOf() - let waitTime = 1000 - let totalWaitTime = waitTime - - while (Date.now() < waitUntil && keepWaitingIf(attempts[attempts.length - 1])) { - count++ - // Wait a beat - if (verbose) { - console.info(`Waiting ${waitTime}ms before trying again (bringing the total wait time to ${totalWaitTime}ms so far, of total ${secondsToWait * 1000}ms)`) - } - await new Promise(res => setTimeout(res, waitTime)) - // Exponential backoff - waitTime = waitTime * exponentialFactor; - if (new Date(Date.now() + waitTime).valueOf() > waitUntil) { - waitTime = waitUntil - Date.now() - if (verbose) { - console.info(`was gonna wait too long; new waitTime: ${waitTime}ms`) - } - } - totalWaitTime = waitTime + totalWaitTime - // Try again - attempts.push(await fn(attempts[attempts.length - 1])) - if (verbose && keepWaitingIf(attempts[attempts.length - 1])) { - console.info( - `${count}. Called ${fn}; ${attempts.length - } prev attempts. Most recent: ${JSON.stringify(attempts[attempts.length - 1], null, 2) - }` - ) - } - } - - return attempts -} diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/src/index.ts b/cmd/crates/soroban-spec-typescript/src/project_template/src/index.ts deleted file mode 100644 index f7ad0b66..00000000 --- a/cmd/crates/soroban-spec-typescript/src/project_template/src/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ContractSpec, Address } from '@stellar/stellar-sdk'; -import { Buffer } from "buffer"; -import { AssembledTransaction, Ok, Err } from './assembled-tx.js'; -import type { - u32, - i32, - u64, - i64, - u128, - i128, - u256, - i256, - Option, - Typepoint, - Duration, - Error_, - Result, -} from './assembled-tx.js'; -import type { ClassOptions, XDR_BASE64 } from './method-options.js'; - -export * from './assembled-tx.js'; -export * from './method-options.js'; - -if (typeof window !== 'undefined') { - //@ts-ignore Buffer exists - window.Buffer = window.Buffer || Buffer; -} diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/src/method-options.ts b/cmd/crates/soroban-spec-typescript/src/project_template/src/method-options.ts deleted file mode 100644 index d1ff142f..00000000 --- a/cmd/crates/soroban-spec-typescript/src/project_template/src/method-options.ts +++ /dev/null @@ -1,50 +0,0 @@ -// defined this way so typeahead shows full union, not named alias -let responseTypes: 'simulated' | 'full' | undefined -export type ResponseTypes = typeof responseTypes - -export type XDR_BASE64 = string - -export interface Wallet { - isConnected: () => Promise, - isAllowed: () => Promise, - getUserInfo: () => Promise<{ publicKey?: string }>, - signTransaction: (tx: XDR_BASE64, opts?: { - network?: string, - networkPassphrase?: string, - accountToSign?: string, - }) => Promise, - signAuthEntry: ( - entryXdr: XDR_BASE64, - opts?: { - accountToSign?: string; - } - ) => Promise -} - -export type ClassOptions = { - contractId: string - networkPassphrase: string - rpcUrl: string - errorTypes?: Record - /** - * A Wallet interface, such as Freighter, that has the methods `isConnected`, `isAllowed`, `getUserInfo`, and `signTransaction`. If not provided, will attempt to import and use Freighter. Example: - * - * @example - * ```ts - * import freighter from "@stellar/freighter-api"; - * import { Contract } from "INSERT_CONTRACT_NAME_HERE"; - * const contract = new Contract({ - * …, - * wallet: freighter, - * }) - * ``` - */ - wallet?: Wallet -} - -export type MethodOptions = { - /** - * The fee to pay for the transaction. Default: soroban-sdk's BASE_FEE ('100') - */ - fee?: number -} diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/tsconfig.json b/cmd/crates/soroban-spec-typescript/src/project_template/tsconfig.json deleted file mode 100644 index efd4c619..00000000 --- a/cmd/crates/soroban-spec-typescript/src/project_template/tsconfig.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - /* Language and Environment */ - "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - /* Modules */ - "module": "ESNext", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - /* Emit */ - "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./dist", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - // "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - // "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - /* Type Checking */ - // "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - }, - "include": [ - "src/*" - ] -} diff --git a/cmd/crates/soroban-spec-typescript/src/types.rs b/cmd/crates/soroban-spec-typescript/src/types.rs deleted file mode 100644 index 02511843..00000000 --- a/cmd/crates/soroban-spec-typescript/src/types.rs +++ /dev/null @@ -1,259 +0,0 @@ -use serde::Serialize; -use stellar_xdr::curr::{ - ScSpecEntry, ScSpecFunctionInputV0, ScSpecTypeDef, ScSpecUdtEnumCaseV0, - ScSpecUdtErrorEnumCaseV0, ScSpecUdtStructFieldV0, ScSpecUdtStructV0, ScSpecUdtUnionCaseV0, -}; - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct StructField { - pub doc: String, - pub name: String, - pub value: Type, -} - -impl From<&ScSpecUdtStructFieldV0> for StructField { - fn from(f: &ScSpecUdtStructFieldV0) -> Self { - StructField { - doc: f.doc.to_utf8_string_lossy(), - name: f.name.to_utf8_string_lossy(), - value: (&f.type_).into(), - } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct FunctionInput { - pub doc: String, - pub name: String, - pub value: Type, -} - -impl From<&ScSpecFunctionInputV0> for FunctionInput { - fn from(f: &ScSpecFunctionInputV0) -> Self { - FunctionInput { - doc: f.doc.to_utf8_string_lossy(), - name: f.name.to_utf8_string_lossy(), - value: (&f.type_).into(), - } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct UnionCase { - pub doc: String, - pub name: String, - pub values: Vec, -} - -impl From<&ScSpecUdtUnionCaseV0> for UnionCase { - fn from(c: &ScSpecUdtUnionCaseV0) -> Self { - let (doc, name, values) = match c { - ScSpecUdtUnionCaseV0::VoidV0(v) => ( - v.doc.to_utf8_string_lossy(), - v.name.to_utf8_string_lossy(), - vec![], - ), - ScSpecUdtUnionCaseV0::TupleV0(t) => ( - t.doc.to_utf8_string_lossy(), - t.name.to_utf8_string_lossy(), - t.type_.iter().map(Type::from).collect(), - ), - }; - UnionCase { doc, name, values } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct EnumCase { - pub doc: String, - pub name: String, - pub value: u32, -} - -impl From<&ScSpecUdtEnumCaseV0> for EnumCase { - fn from(c: &ScSpecUdtEnumCaseV0) -> Self { - EnumCase { - doc: c.doc.to_utf8_string_lossy(), - name: c.name.to_utf8_string_lossy(), - value: c.value, - } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct ErrorEnumCase { - pub doc: String, - pub name: String, - pub value: u32, -} - -impl From<&ScSpecUdtErrorEnumCaseV0> for ErrorEnumCase { - fn from(c: &ScSpecUdtErrorEnumCaseV0) -> Self { - ErrorEnumCase { - doc: c.doc.to_utf8_string_lossy(), - name: c.name.to_utf8_string_lossy(), - value: c.value, - } - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(tag = "type")] -#[serde(rename_all = "camelCase")] -pub enum Type { - Void, - Val, - U64, - I64, - U32, - I32, - U128, - I128, - U256, - I256, - Bool, - Symbol, - Bytes, - String, - Address, - Timepoint, - Duration, - Map { key: Box, value: Box }, - Option { value: Box }, - Result { value: Box, error: Box }, - Vec { element: Box }, - BytesN { n: u32 }, - Tuple { elements: Vec }, - Error { message: Option }, - Custom { name: String }, -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] -#[serde(tag = "type")] -#[serde(rename_all = "camelCase")] -pub enum Entry { - Function { - doc: String, - name: String, - inputs: Vec, - outputs: Vec, - }, - Struct { - doc: String, - name: String, - fields: Vec, - }, - TupleStruct { - doc: String, - name: String, - fields: Vec, - }, - Union { - doc: String, - name: String, - cases: Vec, - }, - Enum { - doc: String, - name: String, - cases: Vec, - }, - ErrorEnum { - doc: String, - name: String, - cases: Vec, - }, -} - -impl From<&ScSpecTypeDef> for Type { - fn from(spec: &ScSpecTypeDef) -> Self { - match spec { - ScSpecTypeDef::Map(map) => Type::Map { - key: Box::new(Type::from(map.key_type.as_ref())), - value: Box::new(Type::from(map.value_type.as_ref())), - }, - ScSpecTypeDef::Option(opt) => Type::Option { - value: Box::new(Type::from(opt.value_type.as_ref())), - }, - ScSpecTypeDef::Result(res) => Type::Result { - value: Box::new(Type::from(res.ok_type.as_ref())), - error: Box::new(Type::from(res.error_type.as_ref())), - }, - ScSpecTypeDef::Tuple(tuple) => Type::Tuple { - elements: tuple.value_types.iter().map(Type::from).collect(), - }, - ScSpecTypeDef::Vec(vec) => Type::Vec { - element: Box::new(Type::from(vec.element_type.as_ref())), - }, - ScSpecTypeDef::Udt(udt) => Type::Custom { - name: udt.name.to_utf8_string_lossy(), - }, - ScSpecTypeDef::BytesN(b) => Type::BytesN { n: b.n }, - ScSpecTypeDef::Val => Type::Val, - ScSpecTypeDef::U64 => Type::U64, - ScSpecTypeDef::I64 => Type::I64, - ScSpecTypeDef::U32 => Type::U32, - ScSpecTypeDef::I32 => Type::I32, - ScSpecTypeDef::U128 => Type::U128, - ScSpecTypeDef::I128 => Type::I128, - ScSpecTypeDef::U256 => Type::U256, - ScSpecTypeDef::I256 => Type::I256, - ScSpecTypeDef::Bool => Type::Bool, - ScSpecTypeDef::Symbol => Type::Symbol, - ScSpecTypeDef::Error => Type::Error { message: None }, - ScSpecTypeDef::Bytes => Type::Bytes, - ScSpecTypeDef::String => Type::String, - ScSpecTypeDef::Address => Type::Address, - ScSpecTypeDef::Void => Type::Void, - ScSpecTypeDef::Timepoint => Type::Timepoint, - ScSpecTypeDef::Duration => Type::Duration, - } - } -} - -impl From<&ScSpecEntry> for Entry { - fn from(spec: &ScSpecEntry) -> Self { - match spec { - ScSpecEntry::FunctionV0(f) => Entry::Function { - doc: f.doc.to_utf8_string_lossy(), - name: f.name.to_utf8_string_lossy(), - inputs: f.inputs.iter().map(Into::into).collect(), - outputs: f.outputs.iter().map(Into::into).collect(), - }, - ScSpecEntry::UdtStructV0(s) if is_tuple_strukt(s) => Entry::TupleStruct { - doc: s.doc.to_utf8_string_lossy(), - name: s.name.to_utf8_string_lossy(), - fields: s.fields.iter().map(|f| &f.type_).map(Into::into).collect(), - }, - ScSpecEntry::UdtStructV0(s) => Entry::Struct { - doc: s.doc.to_utf8_string_lossy(), - name: s.name.to_utf8_string_lossy(), - fields: s.fields.iter().map(Into::into).collect(), - }, - ScSpecEntry::UdtUnionV0(u) => Entry::Union { - doc: u.doc.to_utf8_string_lossy(), - name: u.name.to_utf8_string_lossy(), - cases: u.cases.iter().map(Into::into).collect(), - }, - ScSpecEntry::UdtEnumV0(e) => Entry::Enum { - doc: e.doc.to_utf8_string_lossy(), - name: e.name.to_utf8_string_lossy(), - cases: e.cases.iter().map(Into::into).collect(), - }, - ScSpecEntry::UdtErrorEnumV0(e) => Entry::ErrorEnum { - doc: e.doc.to_utf8_string_lossy(), - name: e.name.to_utf8_string_lossy(), - cases: e.cases.iter().map(Into::into).collect(), - }, - } - } -} - -fn is_tuple_strukt(s: &ScSpecUdtStructV0) -> bool { - !s.fields.is_empty() && s.fields[0].name.to_utf8_string_lossy() == "0" -} diff --git a/cmd/crates/soroban-spec-typescript/src/wrapper.rs b/cmd/crates/soroban-spec-typescript/src/wrapper.rs deleted file mode 100644 index d2a8d60a..00000000 --- a/cmd/crates/soroban-spec-typescript/src/wrapper.rs +++ /dev/null @@ -1,55 +0,0 @@ -use itertools::Itertools; - -use crate::types; - -pub fn type_to_js_xdr(value: &types::Type) -> String { - match value { - types::Type::Val => todo!(), - types::Type::U64 => "xdr.ScVal.scvU64(xdr.Uint64.fromString(i.toString()))".to_string(), - types::Type::I64 => "xdr.ScVal.scvI64(xdr.Int64.fromString(i.toString()))".to_string(), - types::Type::U32 => "xdr.ScVal.scvU32(i)".to_string(), - types::Type::I32 => "xdr.ScVal.scvI32(i)".to_string(), - types::Type::Bool => "xdr.ScVal.scvBool(i)".to_string(), - types::Type::Symbol => "xdr.ScVal.scvSymbol(i)".to_string(), - types::Type::Map { key, value } => format!( - "xdr.ScVal.scvMap(Array.from(i.entries()).map(([key, value]) => {{ - return new xdr.ScMapEntry({{ - key: ((i)=>{})(key), - val: ((i)=>{})(value)}}) - }}))", - type_to_js_xdr(key), - type_to_js_xdr(value) - ), - types::Type::Option { value } => format!( - "(!i) ? {} : {}", - type_to_js_xdr(&types::Type::Void), - type_to_js_xdr(value) - ), - types::Type::Result { value, .. } => type_to_js_xdr(value), - types::Type::Vec { element } => { - format!("xdr.ScVal.scvVec(i.map((i)=>{}))", type_to_js_xdr(element)) - } - types::Type::Tuple { elements } => { - let cases = elements - .iter() - .enumerate() - .map(|(i, e)| format!("((i) => {})(i[{i}])", type_to_js_xdr(e))) - .join(",\n "); - format!("xdr.ScVal.scvVec([{cases}])") - } - - types::Type::Custom { name } => format!("{name}ToXdr(i)"), - types::Type::BytesN { .. } | types::Type::Bytes => "xdr.ScVal.scvBytes(i)".to_owned(), - types::Type::Address => "addressToScVal(i)".to_owned(), - types::Type::Void => "xdr.ScVal.scvVoid()".to_owned(), - types::Type::U128 => "u128ToScVal(i)".to_owned(), - types::Type::I128 => "i128ToScVal(i)".to_owned(), - - types::Type::U256 | types::Type::I256 | types::Type::Timepoint | types::Type::Duration => { - "i".to_owned() - } - // This is case shouldn't happen since we only go xdr -> js for errors - types::Type::Error { .. } => "N/A".to_owned(), - types::Type::String => "xdr.ScVal.scvString(i)".to_owned(), - } -} diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/.env b/cmd/crates/soroban-spec-typescript/ts-tests/.env deleted file mode 100644 index 39b24548..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/.env +++ /dev/null @@ -1,2 +0,0 @@ -SOROBAN_NETWORK_PASSPHRASE="Standalone Network ; February 2017" -SOROBAN_RPC_URL="http://localhost:8000/soroban/rpc" diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/.eslintrc.cjs b/cmd/crates/soroban-spec-typescript/ts-tests/.eslintrc.cjs deleted file mode 100644 index 90af706b..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/.eslintrc.cjs +++ /dev/null @@ -1,11 +0,0 @@ -/* eslint-env node */ -module.exports = { - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], - parser: '@typescript-eslint/parser', - parserOptions: { project: './tsconfig.json' }, - plugins: ['@typescript-eslint'], - root: true, - rules: { - "@typescript-eslint/no-floating-promises": ["error"] - }, -}; diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/.gitignore b/cmd/crates/soroban-spec-typescript/ts-tests/.gitignore deleted file mode 100644 index 878823de..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -build -node_modules -yarn.lock -contract-*.txt diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/initialize.sh b/cmd/crates/soroban-spec-typescript/ts-tests/initialize.sh deleted file mode 100755 index 621be2bc..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/initialize.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/bash - -# read .env file, but prefer explicitly set environment variables -IFS=$'\n' -for l in $(cat .env); do - IFS='=' read -ra VARVAL <<< "$l" - # If variable with such name already exists, preserves its value - eval "export ${VARVAL[0]}=\${${VARVAL[0]}:-${VARVAL[1]}}" -done -unset IFS - -echo Network -echo " RPC: $SOROBAN_RPC_URL" -echo " Passphrase: \"$SOROBAN_NETWORK_PASSPHRASE\"" - -NETWORK_STATUS=$(curl -s -X POST "http://localhost:8000/soroban/rpc" -H "Content-Type: application/json" -d '{ "jsonrpc": "2.0", "id": 8675309, "method": "getHealth" }' | sed 's/.*"status":"\(.*\)".*/\1/') || { echo "Make sure you're running local RPC network on localhost:8000" && exit 1; } -echo " Status: $NETWORK_STATUS" - -if [[ "$NETWORK_STATUS" != "healthy" ]]; then - echo "Network is not healthy (not running?), exiting" - exit 1 -fi - -# Print command before executing, from https://stackoverflow.com/a/23342259/249801 -# Discussion: https://github.com/stellar/soroban-tools/pull/1034#pullrequestreview-1690667116 -exe() { echo"${@/eval/}" ; "$@" ; } - -function fund_all() { - exe eval "./soroban keys generate root" - exe eval "./soroban keys fund root" - exe eval "./soroban keys generate alice" - exe eval "./soroban keys fund alice" - exe eval "./soroban keys generate bob" - exe eval "./soroban keys fund bob" -} -function upload() { - exe eval "(./soroban contract $1 --source root --wasm $2 --ignore-checks) > $3" -} -function deploy() { - exe eval "(./soroban contract deploy --source root --wasm-hash $(cat $1) --ignore-checks) > $2" -} -function deploy_all() { - upload deploy ../../../../target/wasm32-unknown-unknown/test-wasms/test_custom_types.wasm contract-id-custom-types.txt - upload deploy ../../../../target/wasm32-unknown-unknown/test-wasms/test_hello_world.wasm contract-id-hello-world.txt - upload deploy ../../../../target/wasm32-unknown-unknown/test-wasms/test_swap.wasm contract-id-swap.txt - upload install ../../../../target/wasm32-unknown-unknown/test-wasms/test_token.wasm contract-token-hash.txt - deploy contract-token-hash.txt contract-id-token-a.txt - deploy contract-token-hash.txt contract-id-token-b.txt -} -function initialize() { - exe eval "./soroban contract invoke --source root --id $(cat $1) -- initialize --admin $(./soroban keys address root) --decimal 0 --name 'Token $2' --symbol '$2'" -} -function initialize_all() { - initialize contract-id-token-a.txt A - initialize contract-id-token-b.txt B -} -function bind() { - exe eval "./soroban contract bindings typescript --contract-id $(cat $1) --output-dir ./node_modules/$2 --overwrite" -} -function bind_all() { - bind contract-id-custom-types.txt test-custom-types - bind contract-id-hello-world.txt test-hello-world - bind contract-id-swap.txt test-swap - bind contract-id-token-a.txt token -} - -function mint() { - exe eval "./soroban contract invoke --source root --id $(cat $1) -- mint --amount 2000000 --to $(./soroban keys address $2)" -} -function mint_all() { - mint contract-id-token-a.txt alice - mint contract-id-token-b.txt bob -} - -fund_all -deploy_all -initialize_all -mint_all -bind_all diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/package-lock.json b/cmd/crates/soroban-spec-typescript/ts-tests/package-lock.json deleted file mode 100644 index 36f5cdd6..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/package-lock.json +++ /dev/null @@ -1,3405 +0,0 @@ -{ - "name": "ts-tests", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "hasInstallScript": true, - "devDependencies": { - "@ava/typescript": "^4.1.0", - "@stellar/stellar-sdk": "11.2.0", - "@types/node": "^20.4.9", - "@typescript-eslint/eslint-plugin": "^6.10.0", - "@typescript-eslint/parser": "^6.10.0", - "ava": "^5.3.1", - "dotenv": "^16.3.1", - "eslint": "^8.53.0", - "typescript": "^5.3.3" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ava/typescript": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@ava/typescript/-/typescript-4.1.0.tgz", - "integrity": "sha512-1iWZQ/nr9iflhLK9VN8H+1oDZqe93qxNnyYUz+jTzkYPAHc5fdZXBrqmNIgIfFhWYXK5OaQ5YtC7OmLeTNhVEg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^5.0.0", - "execa": "^7.1.1" - }, - "engines": { - "node": "^14.19 || ^16.15 || ^18 || ^20" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", - "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", - "dev": true - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@stellar/js-xdr": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@stellar/js-xdr/-/js-xdr-3.0.1.tgz", - "integrity": "sha512-dp5Eh7Nr1YjiIeqpdkj2cQYxfoPudDAH3ck8MWggp48Htw66Z/hUssNYUQG/OftLjEmHT90Z/dtey2Y77DOxIw==", - "dev": true - }, - "node_modules/@stellar/stellar-base": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@stellar/stellar-base/-/stellar-base-10.0.1.tgz", - "integrity": "sha512-BDbx7VHOEQh+4J3Q+gStNXgPaNckVFmD4aOlBBGwxlF6vPFmVnW8IoJdkX7T58zpX55eWI6DXvEhDBlrqTlhAQ==", - "dev": true, - "dependencies": { - "@stellar/js-xdr": "^3.0.1", - "base32.js": "^0.1.0", - "bignumber.js": "^9.1.2", - "buffer": "^6.0.3", - "sha.js": "^2.3.6", - "tweetnacl": "^1.0.3" - }, - "optionalDependencies": { - "sodium-native": "^4.0.1" - } - }, - "node_modules/@stellar/stellar-sdk": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@stellar/stellar-sdk/-/stellar-sdk-11.2.0.tgz", - "integrity": "sha512-qInRR+mLLl9O/AI6Q+Sr19RZeYJtlNoJQJi3pch5BYoMvVhjO8IU8AhHADP//Zmc2osyogwPuqXBiFdaGlfHWA==", - "dev": true, - "dependencies": { - "@stellar/stellar-base": "10.0.1", - "axios": "^1.6.5", - "bignumber.js": "^9.1.2", - "eventsource": "^2.0.2", - "randombytes": "^2.1.0", - "toml": "^3.0.0", - "urijs": "^1.19.1" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", - "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.14.0.tgz", - "integrity": "sha512-1ZJBykBCXaSHG94vMMKmiHoL0MhNHKSVlcHVYZNw+BKxufhqQVTOawNpwwI1P5nIFZ/4jLVop0mcY6mJJDFNaw==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.14.0", - "@typescript-eslint/type-utils": "6.14.0", - "@typescript-eslint/utils": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.14.0.tgz", - "integrity": "sha512-QjToC14CKacd4Pa7JK4GeB/vHmWFJckec49FR4hmIRf97+KXole0T97xxu9IFiPxVQ1DBWrQ5wreLwAGwWAVQA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.14.0", - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/typescript-estree": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.14.0.tgz", - "integrity": "sha512-VT7CFWHbZipPncAZtuALr9y3EuzY1b1t1AEkIq2bTXUPKw+pHoXflGNG5L+Gv6nKul1cz1VH8fz16IThIU0tdg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.14.0.tgz", - "integrity": "sha512-x6OC9Q7HfYKqjnuNu5a7kffIYs3No30isapRBJl1iCHLitD8O0lFbRcVGiOcuyN837fqXzPZ1NS10maQzZMKqw==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "6.14.0", - "@typescript-eslint/utils": "6.14.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.14.0.tgz", - "integrity": "sha512-uty9H2K4Xs8E47z3SnXEPRNDfsis8JO27amp2GNCnzGETEW3yTqEIVg5+AI7U276oGF/tw6ZA+UesxeQ104ceA==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.14.0.tgz", - "integrity": "sha512-yPkaLwK0yH2mZKFE/bXkPAkkFgOv15GJAUzgUVonAbv0Hr4PK/N2yaA/4XQbTZQdygiDkpt5DkxPELqHguNvyw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.14.0.tgz", - "integrity": "sha512-XwRTnbvRr7Ey9a1NT6jqdKX8y/atWG+8fAIu3z73HSP8h06i3r/ClMhmaF/RGWGW1tHJEwij1uEg2GbEmPYvYg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.14.0", - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/typescript-estree": "6.14.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.14.0.tgz", - "integrity": "sha512-fB5cw6GRhJUz03MrROVuj5Zm/Q+XWlVdIsFj+Zb1Hvqouc8t+XP2H5y53QYU/MGtd2dPg6/vJJlhoX3xc2ehfw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.14.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", - "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/aggregate-error": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", - "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", - "dev": true, - "dependencies": { - "clean-stack": "^4.0.0", - "indent-string": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/arrgv": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", - "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/arrify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", - "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/ava": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ava/-/ava-5.3.1.tgz", - "integrity": "sha512-Scv9a4gMOXB6+ni4toLuhAm9KYWEjsgBglJl+kMGI5+IVDt120CCDZyB5HNU9DjmLI2t4I0GbnxGLmmRfGTJGg==", - "dev": true, - "dependencies": { - "acorn": "^8.8.2", - "acorn-walk": "^8.2.0", - "ansi-styles": "^6.2.1", - "arrgv": "^1.0.2", - "arrify": "^3.0.0", - "callsites": "^4.0.0", - "cbor": "^8.1.0", - "chalk": "^5.2.0", - "chokidar": "^3.5.3", - "chunkd": "^2.0.1", - "ci-info": "^3.8.0", - "ci-parallel-vars": "^1.0.1", - "clean-yaml-object": "^0.1.0", - "cli-truncate": "^3.1.0", - "code-excerpt": "^4.0.0", - "common-path-prefix": "^3.0.0", - "concordance": "^5.0.4", - "currently-unhandled": "^0.4.1", - "debug": "^4.3.4", - "emittery": "^1.0.1", - "figures": "^5.0.0", - "globby": "^13.1.4", - "ignore-by-default": "^2.1.0", - "indent-string": "^5.0.0", - "is-error": "^2.2.2", - "is-plain-object": "^5.0.0", - "is-promise": "^4.0.0", - "matcher": "^5.0.0", - "mem": "^9.0.2", - "ms": "^2.1.3", - "p-event": "^5.0.1", - "p-map": "^5.5.0", - "picomatch": "^2.3.1", - "pkg-conf": "^4.0.0", - "plur": "^5.1.0", - "pretty-ms": "^8.0.0", - "resolve-cwd": "^3.0.0", - "stack-utils": "^2.0.6", - "strip-ansi": "^7.0.1", - "supertap": "^3.0.1", - "temp-dir": "^3.0.0", - "write-file-atomic": "^5.0.1", - "yargs": "^17.7.2" - }, - "bin": { - "ava": "entrypoints/cli.mjs" - }, - "engines": { - "node": ">=14.19 <15 || >=16.15 <17 || >=18" - }, - "peerDependencies": { - "@ava/typescript": "*" - }, - "peerDependenciesMeta": { - "@ava/typescript": { - "optional": true - } - } - }, - "node_modules/ava/node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "dev": true, - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ava/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.15.4", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base32.js": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz", - "integrity": "sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/blueimp-md5": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", - "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/callsites": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.1.0.tgz", - "integrity": "sha512-aBMbD1Xxay75ViYezwT40aQONfr+pSXTHwNKvIXhXD6+LY3F1dLIcceoC5OZKBVHbXcysz1hL9D2w0JJIMXpUw==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "dev": true, - "dependencies": { - "nofilter": "^3.1.0" - }, - "engines": { - "node": ">=12.19" - } - }, - "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chunkd": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", - "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", - "dev": true - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/ci-parallel-vars": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", - "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", - "dev": true - }, - "node_modules/clean-stack": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", - "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clean-yaml-object": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", - "integrity": "sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cli-truncate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", - "dev": true, - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/code-excerpt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", - "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", - "dev": true, - "dependencies": { - "convert-to-spaces": "^2.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/concordance": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.4.tgz", - "integrity": "sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==", - "dev": true, - "dependencies": { - "date-time": "^3.1.0", - "esutils": "^2.0.3", - "fast-diff": "^1.2.0", - "js-string-escape": "^1.0.1", - "lodash": "^4.17.15", - "md5-hex": "^3.0.1", - "semver": "^7.3.2", - "well-known-symbols": "^2.0.0" - }, - "engines": { - "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14" - } - }, - "node_modules/convert-to-spaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", - "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", - "dev": true, - "dependencies": { - "array-find-index": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/date-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", - "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", - "dev": true, - "dependencies": { - "time-zone": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/emittery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-1.0.1.tgz", - "integrity": "sha512-2ID6FdrMD9KDLldGesP6317G78K7km/kMcwItRtVFva7I/cSEOIaLpewaUb+YLXVwdAp3Ctfxh/V5zIl1sj7dQ==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", - "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.55.0", - "@humanwhocodes/config-array": "^0.11.13", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eventsource": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", - "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", - "dev": true, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/figures": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", - "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^5.0.0", - "is-unicode-supported": "^1.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-by-default": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.1.0.tgz", - "integrity": "sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==", - "dev": true, - "engines": { - "node": ">=10 <11 || >=12 <13 || >=14" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/irregular-plurals": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", - "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-error": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", - "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", - "dev": true - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "dev": true - }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-string-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/load-json-file": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-7.0.1.tgz", - "integrity": "sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "dependencies": { - "p-defer": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/matcher": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz", - "integrity": "sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/md5-hex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", - "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", - "dev": true, - "dependencies": { - "blueimp-md5": "^2.10.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mem": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/mem/-/mem-9.0.2.tgz", - "integrity": "sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==", - "dev": true, - "dependencies": { - "map-age-cleaner": "^0.1.3", - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sindresorhus/mem?sponsor=1" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/node-gyp-build": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz", - "integrity": "sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==", - "dev": true, - "optional": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "dev": true, - "engines": { - "node": ">=12.19" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-event": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", - "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", - "dev": true, - "dependencies": { - "p-timeout": "^5.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", - "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", - "dev": true, - "dependencies": { - "aggregate-error": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-timeout": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", - "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module/node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-ms": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-3.0.0.tgz", - "integrity": "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-conf": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-4.0.0.tgz", - "integrity": "sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==", - "dev": true, - "dependencies": { - "find-up": "^6.0.0", - "load-json-file": "^7.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-conf/node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dev": true, - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-conf/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-conf/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-conf/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-conf/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/pkg-conf/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/plur": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz", - "integrity": "sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==", - "dev": true, - "dependencies": { - "irregular-plurals": "^3.3.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/pretty-ms": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-8.0.0.tgz", - "integrity": "sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==", - "dev": true, - "dependencies": { - "parse-ms": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/sodium-native": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.0.4.tgz", - "integrity": "sha512-faqOKw4WQKK7r/ybn6Lqo1F9+L5T6NlBJJYvpxbZPetpWylUVqz449mvlwIBKBqxEHbWakWuOlUt8J3Qpc4sWw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build": "^4.6.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supertap": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz", - "integrity": "sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==", - "dev": true, - "dependencies": { - "indent-string": "^5.0.0", - "js-yaml": "^3.14.1", - "serialize-error": "^7.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/supertap/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/supertap/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/temp-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", - "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", - "dev": true, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/time-zone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", - "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toml": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", - "dev": true - }, - "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", - "dev": true, - "engines": { - "node": ">=16.13.0" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urijs": { - "version": "1.19.11", - "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", - "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", - "dev": true - }, - "node_modules/well-known-symbols": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", - "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/write-file-atomic/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/package.json b/cmd/crates/soroban-spec-typescript/ts-tests/package.json deleted file mode 100644 index c06446de..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "private": true, - "type": "module", - "scripts": { - "lint": "eslint src/*", - "postinstall": "./initialize.sh", - "test": "npm run lint && ava" - }, - "devDependencies": { - "@ava/typescript": "^4.1.0", - "@types/node": "^20.4.9", - "@typescript-eslint/eslint-plugin": "^6.10.0", - "@typescript-eslint/parser": "^6.10.0", - "ava": "^5.3.1", - "dotenv": "^16.3.1", - "eslint": "^8.53.0", - "@stellar/stellar-sdk": "11.2.0", - "typescript": "^5.3.3" - }, - "ava": { - "typescript": { - "rewritePaths": { - "src/": "build/" - }, - "compile": "tsc" - }, - "require": [ - "dotenv/config" - ] - } -} diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/soroban b/cmd/crates/soroban-spec-typescript/ts-tests/soroban deleted file mode 100755 index d98f247c..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/soroban +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -cargo run --quiet -p soroban-cli -- "$@" diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/src/test-custom-types.ts b/cmd/crates/soroban-spec-typescript/ts-tests/src/test-custom-types.ts deleted file mode 100644 index 3b07dc3d..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/src/test-custom-types.ts +++ /dev/null @@ -1,187 +0,0 @@ -import test from 'ava' -import { root, rpcUrl, wallet } from './util.js' -import { Contract, Ok, Err, networks } from 'test-custom-types' - -const publicKey = root.keypair.publicKey(); - -const contract = new Contract({ ...networks.standalone, rpcUrl, wallet }); - -test('hello', async t => { - const { result } = await contract.hello({ hello: 'tests' }) - t.is(result, 'tests') -}) - -test('woid', async t => { - t.is((await contract.woid()).result, undefined) -}) - -test('u32_fail_on_even', async t => { - t.deepEqual( - (await contract.u32FailOnEven({ u32_: 1 })).result, - new Ok(1) - ) - t.deepEqual( - (await contract.u32FailOnEven({ u32_: 0 })).result, - new Err({ message: "Please provide an odd number" }) - ) -}) - -test('u32', async t => { - t.is((await contract.u32({ u32_: 1 })).result, 1) -}) - -test('i32', async t => { - t.is((await contract.i32({ i32_: 1 })).result, 1) -}) - -test('i64', async t => { - t.is((await contract.i64({ i64_: 1n })).result, 1n) -}) - -test("strukt_hel", async (t) => { - const test = { a: 0, b: true, c: "world" } - t.deepEqual((await contract.struktHel({ strukt: test })).result, ["Hello", "world"]) -}) - -test("strukt", async (t) => { - const test = { a: 0, b: true, c: "hello" } - t.deepEqual((await contract.strukt({ strukt: test })).result, test) -}) - -test('simple first', async t => { - const arg = { tag: 'First', values: undefined } as const - const ret = { tag: 'First' } - t.deepEqual((await contract.simple({ simple: arg })).result, ret) -}) - -test('simple second', async t => { - const arg = { tag: 'Second', values: undefined } as const - const ret = { tag: 'Second' } - t.deepEqual((await contract.simple({ simple: arg })).result, ret) -}) - -test('simple third', async t => { - const arg = { tag: 'Third', values: undefined } as const - const ret = { tag: 'Third' } - t.deepEqual((await contract.simple({ simple: arg })).result, ret) -}) - -test('complex with struct', async t => { - const arg = { tag: 'Struct', values: [{ a: 0, b: true, c: 'hello' }] } as const - const ret = { tag: 'Struct', values: [{ a: 0, b: true, c: 'hello' }] } - t.deepEqual((await contract.complex({ complex: arg })).result, ret) -}) - -test('complex with tuple', async t => { - const arg = { tag: 'Tuple', values: [[{ a: 0, b: true, c: 'hello' }, { tag: 'First', values: undefined }]] } as const - const ret = { tag: 'Tuple', values: [[{ a: 0, b: true, c: 'hello' }, { tag: 'First' }]] } - t.deepEqual((await contract.complex({ complex: arg })).result, ret) -}) - -test('complex with enum', async t => { - const arg = { tag: 'Enum', values: [{ tag: 'First', values: undefined }] } as const - const ret = { tag: 'Enum', values: [{ tag: 'First' }] } - t.deepEqual((await contract.complex({ complex: arg })).result, ret) -}) - -test('complex with asset', async t => { - const arg = { tag: 'Asset', values: [publicKey, 1n] } as const - const ret = { tag: 'Asset', values: [publicKey, 1n] } - t.deepEqual((await contract.complex({ complex: arg })).result, ret) -}) - -test('complex with void', async t => { - const arg = { tag: 'Void', values: undefined } as const - const ret = { tag: 'Void' } - t.deepEqual((await contract.complex({ complex: arg })).result, ret) -}) - -test('addresse', async t => { - t.deepEqual((await contract.addresse({ addresse: publicKey })).result, publicKey) -}) - -test('bytes', async t => { - const bytes = Buffer.from('hello') - t.deepEqual((await contract.bytes({ bytes })).result, bytes) -}) - -test('bytes_n', async t => { - const bytes_n = Buffer.from('123456789') // what's the correct way to construct bytes_n? - t.deepEqual((await contract.bytesN({ bytes_n })).result, bytes_n) -}) - -test('card', async t => { - const card = 11 - t.is((await contract.card({ card })).result, card) -}) - -test('boolean', async t => { - t.is((await contract.boolean({ boolean: true })).result, true) -}) - -test('not', async t => { - t.is((await contract.not({ boolean: true })).result, false) -}) - -test('i128', async t => { - t.is((await contract.i128({ i128: -1n })).result, -1n) -}) - -test('u128', async t => { - t.is((await contract.u128({ u128: 1n })).result, 1n) -}) - -test('multi_args', async t => { - t.is((await contract.multiArgs({ a: 1, b: true })).result, 1) - t.is((await contract.multiArgs({ a: 1, b: false })).result, 0) -}) - -test('map', async t => { - const map = new Map() - map.set(1, true) - map.set(2, false) - // map.set(3, 'hahaha') // should throw an error - const ret = Array.from(map.entries()) - t.deepEqual((await contract.map({ map })).result, ret) -}) - -test('vec', async t => { - const vec = [1, 2, 3] - t.deepEqual((await contract.vec({ vec })).result, vec) -}) - -test('tuple', async t => { - const tuple = ['hello', 1] as const - t.deepEqual((await contract.tuple({ tuple })).result, tuple) -}) - -test('option', async t => { - // this makes sense - t.deepEqual((await contract.option({ option: 1 })).result, 1) - - // this passes but shouldn't - t.deepEqual((await contract.option({ option: undefined })).result, undefined) - - // this is the behavior we probably want, but fails - // t.deepEqual(await contract.option(), undefined) // typing and implementation require the object - // t.deepEqual((await contract.option({})).result, undefined) // typing requires argument; implementation would be fine with this - // t.deepEqual((await contract.option({ option: undefined })).result, undefined) -}) - -test('u256', async t => { - t.is((await contract.u256({ u256: 1n })).result, 1n) -}) - -test('i256', async t => { - t.is((await contract.i256({ i256: -1n })).result, -1n) -}) - -test('string', async t => { - t.is((await contract.string({ string: 'hello' })).result, 'hello') -}) - -test('tuple_strukt', async t => { - const arg = [{ a: 0, b: true, c: 'hello' }, { tag: 'First', values: undefined }] as const - const res = [{ a: 0, b: true, c: 'hello' }, { tag: 'First' }] - t.deepEqual((await contract.tupleStrukt({ tuple_strukt: arg })).result, res) -}) diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/src/test-deserialized-transaction.ts b/cmd/crates/soroban-spec-typescript/ts-tests/src/test-deserialized-transaction.ts deleted file mode 100644 index f6152d2c..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/src/test-deserialized-transaction.ts +++ /dev/null @@ -1,16 +0,0 @@ -import test from "ava" -import { wallet, rpcUrl } from "./util.js" -import { Contract, networks } from "test-hello-world" - -const contract = new Contract({ ...networks.standalone, rpcUrl, wallet }) - -test("has correctly-typed result", async (t) => { - const initial = await contract.hello({ world: "tests" }) - t.is(initial.result[0], "Hello") - t.is(initial.result[1], "tests") - - const serialized = initial.toJSON() - const deserialized = contract.fromJSON.hello(serialized) - t.is(deserialized.result[0], "Hello") // throws TS error if `result` is of type `unknown` - t.is(deserialized.result[1], "tests") // throws TS error if `result` is of type `unknown` -}); diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/src/test-hello-world.ts b/cmd/crates/soroban-spec-typescript/ts-tests/src/test-hello-world.ts deleted file mode 100644 index e658c455..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/src/test-hello-world.ts +++ /dev/null @@ -1,26 +0,0 @@ -import test from "ava"; -import { root, wallet, rpcUrl } from "./util.js"; -import { Contract, networks } from "test-hello-world"; - -const contract = new Contract({ ...networks.standalone, rpcUrl, wallet }); - -test("hello", async (t) => { - t.deepEqual((await contract.hello({ world: "tests" })).result, ["Hello", "tests"]); -}); - -test("auth", async (t) => { - t.deepEqual( - (await contract.auth({ - addr: root.keypair.publicKey(), - world: 'lol' - })).result, - root.keypair.publicKey() - ) -}); - -test("inc", async (t) => { - const { result: startingBalance } = await contract.getCount() - const inc = await contract.inc() - t.is((await inc.signAndSend()).result, startingBalance + 1) - t.is((await contract.getCount()).result, startingBalance + 1) -}); diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/src/test-methods-as-args.ts b/cmd/crates/soroban-spec-typescript/ts-tests/src/test-methods-as-args.ts deleted file mode 100644 index afa3b651..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/src/test-methods-as-args.ts +++ /dev/null @@ -1,12 +0,0 @@ -import test from "ava"; -import { wallet, rpcUrl } from "./util.js"; -import { Contract, networks } from "test-hello-world"; - -const contract = new Contract({ ...networks.standalone, rpcUrl, wallet }); - -// this test checks that apps can pass methods as arguments to other methods and have them still work -const hello = contract.hello - -test("hello", async (t) => { - t.deepEqual((await hello({ world: "tests" })).result, ["Hello", "tests"]); -}); diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/src/test-swap.ts b/cmd/crates/soroban-spec-typescript/ts-tests/src/test-swap.ts deleted file mode 100644 index a473cb4d..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/src/test-swap.ts +++ /dev/null @@ -1,134 +0,0 @@ -import test from "ava" -import { SorobanRpc, xdr } from '@stellar/stellar-sdk' -import { wallet, rpcUrl, alice, bob, networkPassphrase, root, Wallet } from "./util.js" -import { Contract as Token } from "token" -import { Contract as Swap, networks, NeedsMoreSignaturesError } from "test-swap" -import fs from "node:fs" - -const tokenAId = fs.readFileSync(new URL("../contract-id-token-a.txt", import.meta.url), "utf8").trim() -const tokenBId = fs.readFileSync(new URL("../contract-id-token-b.txt", import.meta.url), "utf8").trim() - -// `root` is the invoker of all contracts -const tokenA = new Token({ - contractId: tokenAId, - networkPassphrase, - rpcUrl, - wallet, -}) -const tokenB = new Token({ - contractId: tokenBId, - networkPassphrase, - rpcUrl, - wallet, -}) -function swapContractAs(invoker: typeof root | typeof alice | typeof bob) { - return new Swap({ - ...networks.standalone, - rpcUrl, - wallet: new Wallet(invoker.keypair.publicKey()), - }) -} - -const amountAToSwap = 2n -const amountBToSwap = 1n -const alicePk = alice.keypair.publicKey() -const bobPk = bob.keypair.publicKey() - -test('calling `signAndSend()` too soon throws descriptive error', async t => { - const swapContract = swapContractAs(root) - const tx = await swapContract.swap({ - a: alicePk, - b: bobPk, - token_a: tokenAId, - token_b: tokenBId, - amount_a: amountAToSwap, - min_a_for_b: amountAToSwap, - amount_b: amountBToSwap, - min_b_for_a: amountBToSwap, - }) - const error = await t.throwsAsync(tx.signAndSend()) - t.true(error instanceof NeedsMoreSignaturesError, `error is not of type 'NeedsMoreSignaturesError'; instead it is of type '${error?.constructor.name}'`) - if (error) t.regex(error.message, /needsNonInvokerSigningBy/) -}) - -test('alice swaps bob 10 A for 1 B', async t => { - const swapContractAsRoot = swapContractAs(root) - const [ - { result: aliceStartingABalance }, - { result: aliceStartingBBalance }, - { result: bobStartingABalance }, - { result: bobStartingBBalance }, - ] = await Promise.all([ - tokenA.balance({ id: alicePk }), - tokenB.balance({ id: alicePk }), - tokenA.balance({ id: bobPk }), - tokenB.balance({ id: bobPk }), - ]) - t.true(aliceStartingABalance >= amountAToSwap, `alice does not have enough Token A! aliceStartingABalance: ${aliceStartingABalance}`) - t.true(bobStartingBBalance >= amountBToSwap, `bob does not have enough Token B! bobStartingBBalance: ${bobStartingBBalance}`) - - const tx = await swapContractAsRoot.swap({ - a: alicePk, - b: bobPk, - token_a: tokenAId, - token_b: tokenBId, - amount_a: amountAToSwap, - min_a_for_b: amountAToSwap, - amount_b: amountBToSwap, - min_b_for_a: amountBToSwap, - }) - - const needsNonInvokerSigningBy = await tx.needsNonInvokerSigningBy() - t.is(needsNonInvokerSigningBy.length, 2) - t.is(needsNonInvokerSigningBy.indexOf(alicePk), 0, 'needsNonInvokerSigningBy does not have alice\'s public key!') - t.is(needsNonInvokerSigningBy.indexOf(bobPk), 1, 'needsNonInvokerSigningBy does not have bob\'s public key!') - - - // root serializes & sends to alice - const jsonFromRoot = tx.toJSON() - const txAlice = swapContractAs(alice).fromJSON.swap(jsonFromRoot) - await txAlice.signAuthEntries() - - // alice serializes & sends to bob - const jsonFromAlice = txAlice.toJSON() - const txBob = swapContractAs(bob).fromJSON.swap(jsonFromAlice) - await txBob.signAuthEntries() - - // bob serializes & sends back to root - const jsonFromBob = txBob.toJSON() - const txRoot = swapContractAsRoot.fromJSON.swap(jsonFromBob) - const result = await txRoot.signAndSend() - - t.truthy(result.sendTransactionResponse, `tx failed: ${JSON.stringify(result, null, 2)}`) - t.is(result.sendTransactionResponse!.status, 'PENDING', `tx failed: ${JSON.stringify(result, null, 2)}`) - t.truthy(result.getTransactionResponseAll?.length, `tx failed: ${JSON.stringify(result.getTransactionResponseAll, null, 2)}`) - t.not(result.getTransactionResponse!.status, 'FAILED', `tx failed: ${JSON.stringify( - ((result.getTransactionResponse as SorobanRpc.Api.GetFailedTransactionResponse) - .resultXdr.result().value() as xdr.OperationResult[] - ).map(op => - op.value()?.value().switch() - ), null, 2)}` - ) - t.is( - result.getTransactionResponse!.status, - SorobanRpc.Api.GetTransactionStatus.SUCCESS, - `tx failed: ${JSON.stringify(result.getTransactionResponse, null, 2)}` - ) - - t.is( - (await tokenA.balance({ id: alicePk })).result, - aliceStartingABalance - amountAToSwap - ) - t.is( - (await tokenB.balance({ id: alicePk })).result, - aliceStartingBBalance + amountBToSwap - ) - t.is( - (await tokenA.balance({ id: bobPk })).result, - bobStartingABalance + amountAToSwap - ) - t.is( - (await tokenB.balance({ id: bobPk })).result, - bobStartingBBalance - amountBToSwap - ) -}) diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/src/util.ts b/cmd/crates/soroban-spec-typescript/ts-tests/src/util.ts deleted file mode 100644 index d5539fd1..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/src/util.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { spawnSync } from "node:child_process"; -import { Keypair, TransactionBuilder, hash } from "@stellar/stellar-sdk"; -import { Address } from 'test-custom-types' - -const rootKeypair = Keypair.fromSecret(spawnSync("./soroban", ["keys", "show", "root"], { shell: true, encoding: "utf8" }).stdout.trim()); -const aliceKeypair = Keypair.fromSecret(spawnSync("./soroban", ["keys", "show", "alice"], { shell: true, encoding: "utf8" }).stdout.trim()); -const bobKeypair = Keypair.fromSecret(spawnSync("./soroban", ["keys", "show", "bob"], { shell: true, encoding: "utf8" }).stdout.trim()); - -export const root = { - keypair: rootKeypair, - address: Address.fromString(rootKeypair.publicKey()), -} - -export const alice = { - keypair: aliceKeypair, - address: Address.fromString(aliceKeypair.publicKey()), -} - -export const bob = { - keypair: bobKeypair, - address: Address.fromString(bobKeypair.publicKey()), -} - -function getKeypair(pk: string): Keypair { - return Keypair.fromSecret({ - [root.keypair.publicKey()]: root.keypair.secret(), - [alice.keypair.publicKey()]: alice.keypair.secret(), - [bob.keypair.publicKey()]: bob.keypair.secret(), - }[pk]) -} - -export const rpcUrl = process.env.SOROBAN_RPC_URL ?? "http://localhost:8000/"; -export const networkPassphrase = process.env.SOROBAN_NETWORK_PASSPHRASE ?? "Standalone Network ; February 2017"; - -export class Wallet { - constructor(private publicKey: string) {} - isConnected = () => Promise.resolve(true) - isAllowed = () => Promise.resolve(true) - getUserInfo = () => Promise.resolve({ publicKey: this.publicKey }) - signTransaction = async (tx: string) => { - const t = TransactionBuilder.fromXDR(tx, networkPassphrase); - t.sign(getKeypair(this.publicKey)); - return t.toXDR(); - } - signAuthEntry = async ( - entryXdr: string, - opts?: { - accountToSign?: string, - } - ): Promise => { - return getKeypair(opts?.accountToSign ?? this.publicKey) - .sign(hash(Buffer.from(entryXdr, "base64"))) - .toString('base64') - } -} - -export const wallet = new Wallet(root.keypair.publicKey()) diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/tsconfig.json b/cmd/crates/soroban-spec-typescript/ts-tests/tsconfig.json deleted file mode 100644 index 119437bc..00000000 --- a/cmd/crates/soroban-spec-typescript/ts-tests/tsconfig.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - /* Language and Environment */ - "target": "esnext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - /* Modules */ - "module": "nodenext", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "nodenext", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ - // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ - // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ - // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./build", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -}