diff --git a/.config/dictionaries/project.dic b/.config/dictionaries/project.dic index 1812da14af..7d0d4d2fd8 100644 --- a/.config/dictionaries/project.dic +++ b/.config/dictionaries/project.dic @@ -80,6 +80,7 @@ junitreport Keyhash keyserver lcov +lerp Leshiy libapp libavcodec @@ -179,6 +180,7 @@ vkeywitness voteplan voteplans wallclock +wasmtime Werror xcassets xcconfig @@ -188,4 +190,12 @@ xcodeproj xctest xctestrun xcworkspace -yoroi \ No newline at end of file +yoroi +multiplatform +Multiplatform +Easterling +lovelace +lovelaces +pinenacl +dtscalac +vkeys diff --git a/.gitignore b/.gitignore index 515ebe4db1..d6aba0034f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,6 @@ # Icon must end with two \r Icon - # Thumbnails ._* @@ -103,4 +102,8 @@ dev-catalyst-voice-9f78f27c6bc5.json /docs/site/ # Rust -Cargo.lock \ No newline at end of file + +# By default ignore Cargo.lock +# Specifically exclude it in the directory it appears, if its required. +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock diff --git a/Earthfile b/Earthfile index 9fa6990e1b..0f94987112 100644 --- a/Earthfile +++ b/Earthfile @@ -1,31 +1,34 @@ -# Set the Earthly version to 0.7 +VERSION 0.8 + +IMPORT github.com/input-output-hk/catalyst-ci/earthly/mdlint:v3.00.0 AS mdlint-ci +IMPORT github.com/input-output-hk/catalyst-ci/earthly/cspell:v3.00.0 AS cspell-ci +IMPORT github.com/input-output-hk/catalyst-ci/earthly/postgresql:v3.00.0 AS postgresql-ci -VERSION 0.7 FROM debian:stable-slim # cspell: words livedocs sitedocs # check-markdown markdown check using catalyst-ci. check-markdown: - DO github.com/input-output-hk/catalyst-ci/earthly/mdlint:v2.11.1+CHECK + DO mdlint-ci+CHECK # markdown-check-fix markdown check and fix using catalyst-ci. markdown-check-fix: LOCALLY - DO github.com/input-output-hk/catalyst-ci/earthly/mdlint:v2.11.1+MDLINT_LOCALLY --src=$(echo ${PWD}) --fix=--fix + DO mdlint-ci+MDLINT_LOCALLY --src=$(echo ${PWD}) --fix=--fix # check-spelling Check spelling in this repo inside a container. check-spelling: - DO github.com/input-output-hk/catalyst-ci/earthly/cspell:v2.11.1+CHECK + DO cspell-ci+CHECK # check if the sql files are properly formatted and pass lint quality checks. check-sqlfluff: - FROM github.com/input-output-hk/catalyst-ci/earthly/postgresql:v2.11.1+postgres-base + FROM postgresql-ci+postgres-base COPY . . - DO github.com/input-output-hk/catalyst-ci/earthly/postgresql:v2.11.1+CHECK + DO postgresql-ci+CHECK repo-docs: # Create artifacts of extra files we embed inside the documentation when its built. diff --git a/athena/.gitignore b/athena/.gitignore index aa901d56da..8afaf0c8eb 100644 --- a/athena/.gitignore +++ b/athena/.gitignore @@ -4,12 +4,8 @@ debug/ target/ -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - # These are backup files generated by rustfmt **/*.rs.bk # MSVC Windows builds of rustc generate these, which store debugging information -*.pdb \ No newline at end of file +*.pdb diff --git a/catalyst-gateway/.gitignore b/catalyst-gateway/.gitignore index c1b3e69689..92e534b054 100644 --- a/catalyst-gateway/.gitignore +++ b/catalyst-gateway/.gitignore @@ -8,4 +8,8 @@ target/ **/*.rs.bk # MSVC Windows builds of rustc generate these, which store debugging information -*.pdb \ No newline at end of file +*.pdb + +# Build artifacts +cat-gateway.coverage-report.info +cat-gateway.junit-report.xml diff --git a/catalyst-gateway/Cargo.lock b/catalyst-gateway/Cargo.lock deleted file mode 100644 index 63edbb0a74..0000000000 --- a/catalyst-gateway/Cargo.lock +++ /dev/null @@ -1,4338 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "abnf" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33741baa462d86e43fdec5e8ffca7c6ac82847ad06cbfb382c1bdbf527de9e6b" -dependencies = [ - "abnf-core", - "nom", -] - -[[package]] -name = "abnf-core" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c44e09c43ae1c368fb91a03a566472d0087c26cf7e1b9e8e289c14ede681dd7d" -dependencies = [ - "nom", -] - -[[package]] -name = "abnf_to_pest" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "939d59666dd9a7964a3a5312b9d24c9c107630752ee64f2dd5038189a23fe331" -dependencies = [ - "abnf", - "indexmap 1.9.3", - "itertools 0.10.5", - "pretty", -] - -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" - -[[package]] -name = "anstyle-parse" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - -[[package]] -name = "anyhow" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" - -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "async-compression" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a116f46a969224200a0a97f29cfd4c50e7534e4b4826bd23ea2c3c533039c82c" -dependencies = [ - "brotli", - "flate2", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "async-stream" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "async-trait" -version = "0.1.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.28", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base16" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" - -[[package]] -name = "base58" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" - -[[package]] -name = "base64-url" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb9fb9fb058cc3063b5fc88d9a21eefa2735871498a04e1650da76ed511c8569" -dependencies = [ - "base64 0.21.7", -] - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bb8" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7c2093d15d6a1d33b1f972e1c5ea3177748742b97a5f392aa83a65262c6780" -dependencies = [ - "async-trait", - "futures-channel", - "futures-util", - "parking_lot", - "tokio", -] - -[[package]] -name = "bb8-postgres" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ac82c42eb30889b5c4ee4763a24b8c566518171ebea648cd7e3bc532c60680" -dependencies = [ - "async-trait", - "bb8", - "tokio", - "tokio-postgres", -] - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "binary-layout" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5845e3504cf59b9588fff324710f27ee519515b8a8a9f1207042da9a9e64f819" -dependencies = [ - "doc-comment", - "paste", -] - -[[package]] -name = "bip39" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" -dependencies = [ - "bitcoin_hashes", - "rand_core", - "serde", - "unicode-normalization", -] - -[[package]] -name = "bitcoin_hashes" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "borsh" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" -dependencies = [ - "borsh-derive", - "cfg_aliases", -] - -[[package]] -name = "borsh-derive" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" -dependencies = [ - "once_cell", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.53", - "syn_derive", -] - -[[package]] -name = "brotli" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bumpalo" -version = "3.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" - -[[package]] -name = "bytecheck" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" - -[[package]] -name = "cardano-chain-follower" -version = "0.0.1" -source = "git+https://github.com/input-output-hk/hermes.git#145bfee76048f8efcd9ce5e16bf01ed72b5809f1" -dependencies = [ - "pallas", - "pallas-hardano", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "cat-gateway" -version = "0.0.1" -dependencies = [ - "anyhow", - "bb8", - "bb8-postgres", - "cardano-chain-follower", - "cddl", - "chrono", - "ciborium", - "clap 4.5.3", - "cpu-time", - "cryptoxide", - "dotenvy", - "ed25519-dalek", - "gethostname", - "handlebars", - "hex", - "lazy_static", - "local-ip-address", - "pallas", - "panic-message", - "poem", - "poem-extensions", - "poem-openapi", - "prometheus", - "rust-embed", - "rust_decimal", - "serde", - "serde_json", - "thiserror", - "tokio", - "tokio-postgres", - "tracing", - "tracing-subscriber", - "ulid", - "url", - "uuid", -] - -[[package]] -name = "cc" -version = "1.0.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" - -[[package]] -name = "cddl" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc18488a72cef88de14f00d3db73f57a9511d53ae8dd72204a4bf8bc19309d7" -dependencies = [ - "abnf_to_pest", - "base16", - "base64-url", - "chrono", - "ciborium", - "clap 3.2.25", - "codespan-reporting", - "console_error_panic_hook", - "crossterm", - "data-encoding", - "displaydoc", - "hexf-parse", - "itertools 0.11.0", - "lexical-core", - "log", - "pest_meta", - "pest_vm", - "regex", - "regex-syntax 0.7.5", - "serde", - "serde-wasm-bindgen", - "serde_json", - "simplelog", - "uriparse", - "wasm-bindgen", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - -[[package]] -name = "chrono" -version = "0.4.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "serde", - "wasm-bindgen", - "windows-targets 0.52.4", -] - -[[package]] -name = "ciborium" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" - -[[package]] -name = "ciborium-ll" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" -dependencies = [ - "ciborium-io", - "half 2.4.0", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_derive 3.2.25", - "clap_lex 0.2.4", - "indexmap 1.9.3", - "once_cell", - "strsim 0.10.0", - "termcolor", - "textwrap", -] - -[[package]] -name = "clap" -version = "4.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" -dependencies = [ - "clap_builder", - "clap_derive 4.5.3", -] - -[[package]] -name = "clap_builder" -version = "4.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" -dependencies = [ - "anstream", - "anstyle", - "clap_lex 0.7.0", - "strsim 0.11.0", -] - -[[package]] -name = "clap_derive" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" -dependencies = [ - "heck 0.4.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "clap_derive" -version = "4.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "clap_lex" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8" -dependencies = [ - "aes-gcm", - "base64 0.21.7", - "hkdf", - "hmac", - "percent-encoding", - "rand", - "sha2", - "subtle", - "time", - "version_check", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "cpu-time" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e393a7668fe1fad3075085b86c781883000b4ede868f43627b34a87c8b7ded" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "cpufeatures" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" -dependencies = [ - "libc", -] - -[[package]] -name = "crc" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - -[[package]] -name = "crc32fast" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossterm" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" -dependencies = [ - "bitflags 2.4.2", - "crossterm_winapi", - "libc", - "mio", - "parking_lot", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm_winapi" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" -dependencies = [ - "winapi", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "rand_core", - "typenum", -] - -[[package]] -name = "cryptoxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "382ce8820a5bb815055d3553a610e8cb542b2d767bbacea99038afda96cd760d" - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest", - "fiat-crypto", - "platforms", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "darling" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 2.0.53", -] - -[[package]] -name = "darling_macro" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "data-encoding" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" - -[[package]] -name = "der" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", - "serde", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 1.0.109", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "displaydoc" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "doc-comment" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" - -[[package]] -name = "dotenvy" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8", - "signature", -] - -[[package]] -name = "ed25519-bip32" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb588f93c0d91b2f668849fd6d030cddb0b2e31f105963be189da5acdf492a21" -dependencies = [ - "cryptoxide", -] - -[[package]] -name = "ed25519-dalek" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" -dependencies = [ - "curve25519-dalek", - "ed25519", - "serde", - "sha2", - "subtle", - "zeroize", -] - -[[package]] -name = "either" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" - -[[package]] -name = "encoding_rs" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "fiat-crypto" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e" - -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "flate2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-macro", - "futures-sink", - "futures-task", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "gethostname" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" -dependencies = [ - "libc", - "windows-targets 0.48.5", -] - -[[package]] -name = "getrandom" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "ghash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.2.5", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "h2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 1.1.0", - "indexmap 2.2.5", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "half" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" - -[[package]] -name = "half" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e" -dependencies = [ - "cfg-if", - "crunchy", -] - -[[package]] -name = "handlebars" -version = "5.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" -dependencies = [ - "log", - "pest", - "pest_derive", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" - -[[package]] -name = "headers" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" -dependencies = [ - "base64 0.21.7", - "bytes", - "headers-core", - "http 1.1.0", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" -dependencies = [ - "http 1.1.0", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hexf-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "http-body" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" -dependencies = [ - "bytes", - "http 1.1.0", -] - -[[package]] -name = "http-body-util" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" -dependencies = [ - "bytes", - "futures-core", - "http 1.1.0", - "http-body 1.0.0", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "0.14.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "h2 0.4.4", - "http 1.1.0", - "http-body 1.0.0", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper 0.14.28", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "hyper-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" -dependencies = [ - "bytes", - "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "hyper 1.2.0", - "pin-project-lite", - "socket2", - "tokio", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" -dependencies = [ - "equivalent", - "hashbrown 0.14.3", - "serde", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lexical-core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46" -dependencies = [ - "lexical-parse-float", - "lexical-parse-integer", - "lexical-util", - "lexical-write-float", - "lexical-write-integer", -] - -[[package]] -name = "lexical-parse-float" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f" -dependencies = [ - "lexical-parse-integer", - "lexical-util", - "static_assertions", -] - -[[package]] -name = "lexical-parse-integer" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9" -dependencies = [ - "lexical-util", - "static_assertions", -] - -[[package]] -name = "lexical-util" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5255b9ff16ff898710eb9eb63cb39248ea8a5bb036bea8085b1a767ff6c4e3fc" -dependencies = [ - "static_assertions", -] - -[[package]] -name = "lexical-write-float" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accabaa1c4581f05a3923d1b4cfd124c329352288b7b9da09e766b0668116862" -dependencies = [ - "lexical-util", - "lexical-write-integer", - "static_assertions", -] - -[[package]] -name = "lexical-write-integer" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b6f3d1f4422866b68192d62f77bc5c700bee84f3069f2469d7bc8c77852446" -dependencies = [ - "lexical-util", - "static_assertions", -] - -[[package]] -name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - -[[package]] -name = "local-ip-address" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612ed4ea9ce5acfb5d26339302528a5e1e59dfed95e9e11af3c083236ff1d15d" -dependencies = [ - "libc", - "neli", - "thiserror", - "windows-sys 0.48.0", -] - -[[package]] -name = "lock_api" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "md-5" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" -dependencies = [ - "cfg-if", - "digest", -] - -[[package]] -name = "memchr" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "minicbor" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d15f4203d71fdf90903c2696e55426ac97a363c67b218488a73b534ce7aca10" -dependencies = [ - "half 1.8.3", - "minicbor-derive", -] - -[[package]] -name = "minicbor-derive" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1154809406efdb7982841adb6311b3d095b46f78342dd646736122fe6b19e267" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "multer" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15d522be0a9c3e46fd2632e272d178f56387bdb5c9fbb3a36c649062e9b5219" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http 1.1.0", - "httparse", - "log", - "memchr", - "mime", - "spin", - "tokio", - "version_check", -] - -[[package]] -name = "multimap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - -[[package]] -name = "neli" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1100229e06604150b3becd61a4965d5c70f3be1759544ea7274166f4be41ef43" -dependencies = [ - "byteorder", - "libc", - "log", - "neli-proc-macros", -] - -[[package]] -name = "neli-proc-macros" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4" -dependencies = [ - "either", - "proc-macro2", - "quote", - "serde", - "syn 1.0.109", -] - -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.4.2", - "cfg-if", - "libc", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-bigint" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "opentelemetry" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e32339a5dc40459130b3bd269e9892439f55b33e772d2a9d402a789baaf4e8a" -dependencies = [ - "futures-core", - "futures-sink", - "indexmap 2.2.5", - "js-sys", - "once_cell", - "pin-project-lite", - "thiserror", - "urlencoding", -] - -[[package]] -name = "opentelemetry-prometheus" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8f082da115b0dcb250829e3ed0b8792b8f963a1ad42466e48422fbe6a079bd" -dependencies = [ - "once_cell", - "opentelemetry", - "opentelemetry_sdk", - "prometheus", - "protobuf", -] - -[[package]] -name = "opentelemetry_sdk" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f16aec8a98a457a52664d69e0091bac3a0abd18ead9b641cb00202ba4e0efe4" -dependencies = [ - "async-trait", - "futures-channel", - "futures-executor", - "futures-util", - "glob", - "once_cell", - "opentelemetry", - "ordered-float", - "thiserror", -] - -[[package]] -name = "ordered-float" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" -dependencies = [ - "num-traits", -] - -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "pallas" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "pallas-addresses", - "pallas-applying", - "pallas-codec", - "pallas-configs", - "pallas-crypto", - "pallas-network", - "pallas-primitives", - "pallas-traverse", - "pallas-txbuilder", - "pallas-utxorpc", -] - -[[package]] -name = "pallas-addresses" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "base58", - "bech32", - "crc", - "cryptoxide", - "hex", - "pallas-codec", - "pallas-crypto", - "thiserror", -] - -[[package]] -name = "pallas-applying" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "hex", - "pallas-addresses", - "pallas-codec", - "pallas-crypto", - "pallas-primitives", - "pallas-traverse", - "rand", -] - -[[package]] -name = "pallas-codec" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "hex", - "minicbor", - "serde", - "thiserror", -] - -[[package]] -name = "pallas-configs" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "base64 0.22.0", - "hex", - "num-rational", - "pallas-addresses", - "pallas-codec", - "pallas-crypto", - "pallas-primitives", - "serde", - "serde_json", - "serde_with", -] - -[[package]] -name = "pallas-crypto" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "cryptoxide", - "hex", - "pallas-codec", - "rand_core", - "serde", - "thiserror", -] - -[[package]] -name = "pallas-hardano" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "binary-layout", - "pallas-network", - "pallas-traverse", - "tap", - "thiserror", - "tracing", -] - -[[package]] -name = "pallas-network" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "byteorder", - "hex", - "itertools 0.12.1", - "pallas-codec", - "pallas-crypto", - "rand", - "socket2", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "pallas-primitives" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "base58", - "bech32", - "hex", - "log", - "pallas-codec", - "pallas-crypto", - "serde", - "serde_json", -] - -[[package]] -name = "pallas-traverse" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "hex", - "pallas-addresses", - "pallas-codec", - "pallas-crypto", - "pallas-primitives", - "paste", - "serde", - "thiserror", -] - -[[package]] -name = "pallas-txbuilder" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "hex", - "pallas-addresses", - "pallas-codec", - "pallas-crypto", - "pallas-primitives", - "pallas-traverse", - "pallas-wallet", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "pallas-utxorpc" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "pallas-codec", - "pallas-primitives", - "pallas-traverse", - "utxorpc-spec", -] - -[[package]] -name = "pallas-wallet" -version = "0.25.0" -source = "git+https://github.com/input-output-hk/catalyst-pallas.git?rev=709acb19c52c6b789279ecc4bc8793b5d8b5abe9#709acb19c52c6b789279ecc4bc8793b5d8b5abe9" -dependencies = [ - "bech32", - "bip39", - "cryptoxide", - "ed25519-bip32", - "pallas-crypto", - "rand", - "thiserror", -] - -[[package]] -name = "panic-message" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384e52fd8fbd4cbe3c317e8216260c21a0f9134de108cea8a4dd4e7e152c472d" - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.48.5", -] - -[[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "pbjson" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1030c719b0ec2a2d25a5df729d6cff1acf3cc230bf766f4f97833591f7577b90" -dependencies = [ - "base64 0.21.7", - "serde", -] - -[[package]] -name = "pbjson-build" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2580e33f2292d34be285c5bc3dba5259542b083cfad6037b6d70345f24dcb735" -dependencies = [ - "heck 0.4.1", - "itertools 0.11.0", - "prost", - "prost-types", -] - -[[package]] -name = "pbjson-types" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18f596653ba4ac51bdecbb4ef6773bc7f56042dc13927910de1684ad3d32aa12" -dependencies = [ - "bytes", - "chrono", - "pbjson", - "pbjson-build", - "prost", - "prost-build", - "serde", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pest" -version = "2.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "pest_meta" -version = "2.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" -dependencies = [ - "once_cell", - "pest", - "sha2", -] - -[[package]] -name = "pest_vm" -version = "2.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d61488db5be4105b24ccbced8cf1d59408503589998a8593e692393e0af8d29" -dependencies = [ - "pest", - "pest_meta", -] - -[[package]] -name = "petgraph" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" -dependencies = [ - "fixedbitset", - "indexmap 2.2.5", -] - -[[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" -dependencies = [ - "phf_shared", -] - -[[package]] -name = "phf_shared" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "platforms" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" - -[[package]] -name = "poem" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec6f0033707ce6eb76240e39a592e7eac2f702768636cb03969293227ca8e642" -dependencies = [ - "async-compression", - "async-trait", - "bytes", - "chrono", - "cookie", - "futures-util", - "headers", - "hex", - "http 1.1.0", - "http-body-util", - "hyper 1.2.0", - "hyper-util", - "mime", - "mime_guess", - "multer", - "nix", - "opentelemetry", - "opentelemetry-prometheus", - "parking_lot", - "percent-encoding", - "pin-project-lite", - "poem-derive", - "prometheus", - "quick-xml", - "regex", - "rfc7239", - "rust-embed", - "serde", - "serde_json", - "serde_urlencoded", - "serde_yaml", - "smallvec", - "sync_wrapper", - "tempfile", - "thiserror", - "time", - "tokio", - "tokio-stream", - "tokio-util", - "tracing", - "wildmatch", -] - -[[package]] -name = "poem-derive" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4826d63b6760f8e5d24be9f738a5e38a43d726f32a3c2cc9388b1cc66e587f5c" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "poem-extensions" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cb723d94d93e11c68e5f9c1e0968948b1174a0e218115006add692da7d32fcb" -dependencies = [ - "poem", - "poem-extensions-macro", - "poem-openapi", -] - -[[package]] -name = "poem-extensions-macro" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f20d894749b3a96f5eeadc20d947a214969b000b0c68824d868576d5dd6e62d" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.53", - "thiserror", -] - -[[package]] -name = "poem-openapi" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41a6bbb99ef0046e3214b0be463d68f5716e752f6b04dba06ba4a5d54d159d2" -dependencies = [ - "base64 0.21.7", - "bytes", - "chrono", - "derive_more", - "futures-util", - "indexmap 2.2.5", - "mime", - "num-traits", - "poem", - "poem-openapi-derive", - "quick-xml", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "serde_yaml", - "thiserror", - "tokio", - "url", - "uuid", -] - -[[package]] -name = "poem-openapi-derive" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb2131050ed98d61c903123ab6e4bed5f4fe7f4623f770cb017f0baa632fae5" -dependencies = [ - "darling", - "http 1.1.0", - "indexmap 2.2.5", - "mime", - "proc-macro-crate", - "proc-macro2", - "quote", - "regex", - "syn 2.0.53", - "thiserror", -] - -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "postgres" -version = "0.19.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7915b33ed60abc46040cbcaa25ffa1c7ec240668e0477c4f3070786f5916d451" -dependencies = [ - "bytes", - "fallible-iterator", - "futures-util", - "log", - "tokio", - "tokio-postgres", -] - -[[package]] -name = "postgres-protocol" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" -dependencies = [ - "base64 0.21.7", - "byteorder", - "bytes", - "fallible-iterator", - "hmac", - "md-5", - "memchr", - "rand", - "sha2", - "stringprep", -] - -[[package]] -name = "postgres-types" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" -dependencies = [ - "bytes", - "chrono", - "fallible-iterator", - "postgres-protocol", - "serde", - "serde_json", - "time", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "pretty" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83f3aa1e3ca87d3b124db7461265ac176b40c277f37e503eaa29c9c75c037846" -dependencies = [ - "arrayvec 0.5.2", - "log", - "typed-arena", - "unicode-segmentation", -] - -[[package]] -name = "prettyplease" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" -dependencies = [ - "proc-macro2", - "syn 2.0.53", -] - -[[package]] -name = "proc-macro-crate" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prometheus" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" -dependencies = [ - "cfg-if", - "fnv", - "lazy_static", - "memchr", - "parking_lot", - "protobuf", - "thiserror", -] - -[[package]] -name = "prost" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" -dependencies = [ - "bytes", - "heck 0.5.0", - "itertools 0.10.5", - "log", - "multimap", - "once_cell", - "petgraph", - "prettyplease", - "prost", - "prost-types", - "regex", - "syn 2.0.53", - "tempfile", -] - -[[package]] -name = "prost-derive" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "prost-types" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3235c33eb02c1f1e212abdbe34c78b264b038fb58ca612664343271e36e55ffe" -dependencies = [ - "prost", -] - -[[package]] -name = "protobuf" -version = "2.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" - -[[package]] -name = "ptr_meta" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "quick-xml" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "regex" -version = "1.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax 0.8.2", -] - -[[package]] -name = "regex-automata" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.2", -] - -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "rend" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" -dependencies = [ - "bytecheck", -] - -[[package]] -name = "rfc7239" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "087317b3cf7eb481f13bd9025d729324b7cd068d6f470e2d76d049e191f5ba47" -dependencies = [ - "uncased", -] - -[[package]] -name = "rkyv" -version = "0.7.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" -dependencies = [ - "bitvec", - "bytecheck", - "bytes", - "hashbrown 0.12.3", - "ptr_meta", - "rend", - "rkyv_derive", - "seahash", - "tinyvec", - "uuid", -] - -[[package]] -name = "rkyv_derive" -version = "0.7.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "rust-embed" -version = "8.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb78f46d0066053d16d4ca7b898e9343bc3530f71c61d5ad84cd404ada068745" -dependencies = [ - "rust-embed-impl", - "rust-embed-utils", - "walkdir", -] - -[[package]] -name = "rust-embed-impl" -version = "8.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91ac2a3c6c0520a3fb3dd89321177c3c692937c4eb21893378219da10c44fc8" -dependencies = [ - "proc-macro2", - "quote", - "rust-embed-utils", - "syn 2.0.53", - "walkdir", -] - -[[package]] -name = "rust-embed-utils" -version = "8.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f69089032567ffff4eada41c573fc43ff466c7db7c5688b2e7969584345581" -dependencies = [ - "sha2", - "walkdir", -] - -[[package]] -name = "rust_decimal" -version = "1.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39449a79f45e8da28c57c341891b69a183044b29518bb8f86dbac9df60bb7df" -dependencies = [ - "arrayvec 0.7.4", - "borsh", - "bytes", - "num-traits", - "postgres", - "rand", - "rkyv", - "serde", - "serde_json", - "tokio-postgres", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" -dependencies = [ - "bitflags 2.4.2", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - -[[package]] -name = "ryu" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "seahash" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" - -[[package]] -name = "semver" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" - -[[package]] -name = "serde" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-wasm-bindgen" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "serde_derive" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "serde_json" -version = "1.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_with" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" -dependencies = [ - "base64 0.22.0", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.2.5", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "serde_yaml" -version = "0.9.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0623d197252096520c6f2a5e1171ee436e5af99a5d7caa2891e55e61950e6d9" -dependencies = [ - "indexmap 2.2.5", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-mio" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" -dependencies = [ - "libc", - "mio", - "signal-hook", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "rand_core", -] - -[[package]] -name = "simdutf8" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" - -[[package]] -name = "simplelog" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16257adbfaef1ee58b1363bdc0664c9b8e1e30aed86049635fb5f147d065a9c0" -dependencies = [ - "log", - "termcolor", - "time", -] - -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" - -[[package]] -name = "socket2" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "stringprep" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" -dependencies = [ - "finl_unicode", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "strsim" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" - -[[package]] -name = "subtle" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -dependencies = [ - "futures-core", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "textwrap" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" - -[[package]] -name = "thiserror" -version = "1.0.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "time" -version = "0.3.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" -dependencies = [ - "deranged", - "itoa", - "libc", - "num-conv", - "num_threads", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "time-macros" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "tokio-postgres" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" -dependencies = [ - "async-trait", - "byteorder", - "bytes", - "fallible-iterator", - "futures-channel", - "futures-util", - "log", - "parking_lot", - "percent-encoding", - "phf", - "pin-project-lite", - "postgres-protocol", - "postgres-types", - "rand", - "socket2", - "tokio", - "tokio-util", - "whoami", -] - -[[package]] -name = "tokio-stream" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "toml_datetime" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" - -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.2.5", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tonic" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64 0.21.7", - "bytes", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.28", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost", - "tokio", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.53", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-serde" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" -dependencies = [ - "serde", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "nu-ansi-term", - "serde", - "serde_json", - "sharded-slab", - "smallvec", - "thread_local", - "time", - "tracing-core", - "tracing-log", - "tracing-serde", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typed-arena" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - -[[package]] -name = "ulid" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34778c17965aa2a08913b57e1f34db9b4a63f5de31768b55bf20d2795f921259" -dependencies = [ - "getrandom", - "rand", - "serde", - "uuid", - "web-time", -] - -[[package]] -name = "uncased" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - -[[package]] -name = "uriparse" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" -dependencies = [ - "fnv", - "lazy_static", -] - -[[package]] -name = "url" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "urlencoding" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "utxorpc-spec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ed1da9027ea2010458a9aa5da7d896518176165d630f0325ad2c994f69772b" -dependencies = [ - "bytes", - "futures-core", - "pbjson", - "pbjson-types", - "prost", - "serde", - "tonic", -] - -[[package]] -name = "uuid" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" -dependencies = [ - "getrandom", - "serde", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" - -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.53", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.53", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "web-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "whoami" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" -dependencies = [ - "redox_syscall", - "wasite", - "web-sys", -] - -[[package]] -name = "wildmatch" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "939e59c1bc731542357fdaad98b209ef78c8743d652bb61439d16b16a79eb025" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.4", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.4", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" -dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "zeroize" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/catalyst-gateway/Cargo.toml b/catalyst-gateway/Cargo.toml index 3b175c68fb..7b85571ab8 100644 --- a/catalyst-gateway/Cargo.toml +++ b/catalyst-gateway/Cargo.toml @@ -21,9 +21,8 @@ tracing = "0.1.37" tracing-subscriber = "0.3.16" serde = "1.0" serde_json = "1.0" -poem = "2.0.0" -poem-openapi = "4.0.0" -poem-extensions = "0.8.0" +poem = "3.0.0" +poem-openapi = "5.0.0" prometheus = "0.13.0" cryptoxide = "0.4.4" uuid = "1" @@ -42,7 +41,7 @@ bb8-postgres = "0.8.1" tokio-postgres = "0.7.10" tokio = "1" dotenvy = "0.15" -local-ip-address = "0.5.7" +local-ip-address = "0.6.1" gethostname = "0.4.3" hex = "0.4.3" handlebars = "5.1.2" diff --git a/catalyst-gateway/Earthfile b/catalyst-gateway/Earthfile index 305ec8cb11..84597480cb 100644 --- a/catalyst-gateway/Earthfile +++ b/catalyst-gateway/Earthfile @@ -1,10 +1,13 @@ -VERSION --try --global-cache 0.7 +VERSION 0.8 + +IMPORT github.com/input-output-hk/catalyst-ci/earthly/rust:v3.00.0 AS rust-ci +IMPORT github.com/input-output-hk/catalyst-ci/earthly/mithril_snapshot:v3.00.0 AS mithril-snapshot-ci #cspell: words rustfmt toolsets USERARCH -# Set up our target toolchains, and copy our files. +# builder : Set up our target toolchains, and copy our files. builder: - DO github.com/input-output-hk/catalyst-ci/earthly/rust:v2.11.1+SETUP + DO rust-ci+SETUP COPY --dir .cargo .config Cargo.* clippy.toml deny.toml rustfmt.toml bin crates . @@ -14,39 +17,45 @@ builder: ## ## These targets are discovered and executed automatically by CI. -# Run check using the most efficient host tooling +# check : Run check using the most efficient host tooling # CI Automated Entry point. check: FROM +builder - RUN /scripts/std_checks.py + DO rust-ci+EXECUTE --cmd="/scripts/std_checks.py" -# Test which runs check with all supported host tooling. Needs qemu or rosetta to run. +# all-hosts-check : Test which runs check with all supported host tooling. Needs qemu or rosetta to run. # Only used to validate tooling is working across host toolsets. all-hosts-check: BUILD --platform=linux/amd64 --platform=linux/arm64 +check +# build : Build the catalyst-gateway service build: # Build the service FROM +builder - TRY - RUN /scripts/std_build.py \ - --cov_report="coverage-report.info" \ - --bins="cat-gateway/cat-gateway" - FINALLY - SAVE ARTIFACT --if-exists target/nextest/ci/junit.xml AS LOCAL cat-gateway.junit-report.xml - SAVE ARTIFACT --if-exists coverage-report.info AS LOCAL cat-gateway.coverage-report.info - END - RUN ./target/$TARGETARCH/release/cat-gateway docs ./target/$TARGETARCH/doc/cat-gateway-api.json - SAVE ARTIFACT target/$TARGETARCH/doc doc - SAVE ARTIFACT target/$TARGETARCH/release/cat-gateway cat-gateway - -# Test which runs check with all supported host tooling. Needs qemu or rosetta to run. + DO rust-ci+EXECUTE \ + --cmd="/scripts/std_build.py" \ + --args1="--bins=cat-gateway/cat-gateway" \ + --args2="--cov_report=$HOME/coverage-report.info" \ + --args3="--verbose" \ + --output="release/cat-gateway" \ + --junit="cat-gateway.junit-report.xml" \ + --coverage="cat-gateway.coverage-report.info" \ + --docs="true" + + # Generate the OpenAPI doc from the cat-gateway executable itself. + RUN ./target/release/cat-gateway docs ./target/doc/cat-gateway-api.json + + SAVE ARTIFACT target/doc doc + SAVE ARTIFACT target/release/cat-gateway cat-gateway + +# all-hosts-build : Test which runs check with all supported host tooling. Needs qemu or rosetta to run. # Only used to validate tooling is working across host toolsets. all-hosts-build: BUILD --platform=linux/amd64 --platform=linux/arm64 +build +# package-cat-gateway : Create a deployable container for catalyst-gateway package-cat-gateway: ARG tag="latest" @@ -61,13 +70,15 @@ package-cat-gateway: ENTRYPOINT ./entry.sh SAVE IMAGE cat-gateway:$tag +# package-cat-gateway : Create a deployable container for catalyst-gateway +# And bundle a Mithril snapshot of cardano preprod package-cat-gateway-with-preprod-snapshot: ARG tag="latest" FROM +package-cat-gateway # copy preprod mithril snapshot to /tmp/preprod dir - COPY github.com/input-output-hk/catalyst-ci/earthly/mithril_snapshot:v2.11.1+package-preprod-snapshot/snapshot /tmp/preprod + COPY mithril-snapshot-ci+package-preprod-snapshot/snapshot /tmp/preprod SAVE IMAGE cat-gateway:$tag diff --git a/catalyst-gateway/bin/Cargo.toml b/catalyst-gateway/bin/Cargo.toml index 6c4ff37820..f08b2b7a71 100644 --- a/catalyst-gateway/bin/Cargo.toml +++ b/catalyst-gateway/bin/Cargo.toml @@ -48,7 +48,6 @@ poem-openapi = { workspace = true, features = [ "url", "chrono", ] } -poem-extensions = { workspace = true } prometheus = { workspace = true } cryptoxide = { workspace = true } uuid = { workspace = true, features = ["v4", "serde"] } diff --git a/catalyst-gateway/bin/src/cardano/util.rs b/catalyst-gateway/bin/src/cardano/util.rs index db0e099229..fb54d3217a 100644 --- a/catalyst-gateway/bin/src/cardano/util.rs +++ b/catalyst-gateway/bin/src/cardano/util.rs @@ -23,7 +23,6 @@ pub type StakeCredentialKey = String; pub(crate) const BLAKE_2B_256_HASH_SIZE: usize = 256 / 8; /// Helper function to generate the `blake2b_256` hash of a byte slice -#[allow(dead_code)] pub(crate) fn hash(bytes: &[u8]) -> [u8; BLAKE_2B_256_HASH_SIZE] { let mut digest = [0u8; BLAKE_2B_256_HASH_SIZE]; let mut context = Blake2b::new(BLAKE_2B_256_HASH_SIZE); @@ -54,7 +53,7 @@ pub struct PolicyAsset { } /// Extract assets -pub fn parse_policy_assets(assets: &[MultiEraPolicyAssets<'_>]) -> Vec { +pub(crate) fn parse_policy_assets(assets: &[MultiEraPolicyAssets<'_>]) -> Vec { assets .iter() .map(|asset| { @@ -67,7 +66,7 @@ pub fn parse_policy_assets(assets: &[MultiEraPolicyAssets<'_>]) -> Vec Vec { +fn parse_child_assets(assets: &[MultiEraAsset]) -> Vec { assets .iter() .filter_map(|asset| { diff --git a/catalyst-gateway/bin/src/cli.rs b/catalyst-gateway/bin/src/cli.rs index 586af14b0e..aae2367fd3 100644 --- a/catalyst-gateway/bin/src/cli.rs +++ b/catalyst-gateway/bin/src/cli.rs @@ -6,7 +6,8 @@ use tracing::{error, info}; use crate::{ cardano::start_followers, - logger, service, + logger, + service::{self, started}, settings::{DocsSettings, ServiceSettings}, state::State, }; @@ -54,13 +55,14 @@ impl Cli { } }); - start_followers( + let followers_fut = start_followers( event_db.clone(), settings.follower_settings.check_config_tick, settings.follower_settings.data_refresh_tick, machine_id, - ) - .await?; + ); + started(); + followers_fut.await?; Ok(()) }, diff --git a/catalyst-gateway/bin/src/event_db/legacy/queries/search.rs b/catalyst-gateway/bin/src/event_db/legacy/queries/search.rs index e21e15c2fe..4c0f0dfb3a 100644 --- a/catalyst-gateway/bin/src/event_db/legacy/queries/search.rs +++ b/catalyst-gateway/bin/src/event_db/legacy/queries/search.rs @@ -38,9 +38,7 @@ impl EventDB { where_clause.push_str( format!( "WHERE {0}.{1} LIKE '%{2}%'", - table, - filter.column.to_string(), - filter.search + table, filter.column, filter.search ) .as_str(), ); @@ -48,9 +46,7 @@ impl EventDB { where_clause.push_str( format!( "AND {0}.{1} LIKE '%{2}%'", - table, - filter.column.to_string(), - filter.search + table, filter.column, filter.search ) .as_str(), ); @@ -66,24 +62,12 @@ impl EventDB { if let Some(order_by) = order_by_iter.next() { let order_type = if order_by.descending { "DESC" } else { "ASC" }; order_by_clause.push_str( - format!( - "ORDER BY {0}.{1} {2}", - table, - order_by.column.to_string(), - order_type - ) - .as_str(), + format!("ORDER BY {0}.{1} {2}", table, order_by.column, order_type).as_str(), ); for order_by in order_by_iter { let order_type = if order_by.descending { "DESC" } else { "ASC" }; order_by_clause.push_str( - format!( - ", {0}.{1} LIKE '%{2}%'", - table, - order_by.column.to_string(), - order_type - ) - .as_str(), + format!(", {0}.{1} LIKE '%{2}%'", table, order_by.column, order_type).as_str(), ); } } diff --git a/catalyst-gateway/bin/src/event_db/legacy/types/search.rs b/catalyst-gateway/bin/src/event_db/legacy/types/search.rs index bd28c888e6..a044b92a2f 100644 --- a/catalyst-gateway/bin/src/event_db/legacy/types/search.rs +++ b/catalyst-gateway/bin/src/event_db/legacy/types/search.rs @@ -1,4 +1,6 @@ //! Search Queries +use std::fmt::Display; + use super::{event::EventSummary, objective::ObjectiveSummary, proposal::ProposalSummary}; #[allow(clippy::module_name_repetitions)] @@ -37,14 +39,14 @@ pub(crate) enum SearchColumn { Funds, } -impl ToString for SearchColumn { - fn to_string(&self) -> String { +impl Display for SearchColumn { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - SearchColumn::Title => "title".to_string(), - SearchColumn::Type => "type".to_string(), - SearchColumn::Description => "description".to_string(), - SearchColumn::Author => "author".to_string(), - SearchColumn::Funds => "funds".to_string(), + SearchColumn::Title => write!(f, "title"), + SearchColumn::Type => write!(f, "type"), + SearchColumn::Description => write!(f, "description"), + SearchColumn::Author => write!(f, "author"), + SearchColumn::Funds => write!(f, "funds"), } } } diff --git a/catalyst-gateway/bin/src/event_db/legacy/types/voting_status.rs b/catalyst-gateway/bin/src/event_db/legacy/types/voting_status.rs index 51d7dc0256..53d38e0154 100644 --- a/catalyst-gateway/bin/src/event_db/legacy/types/voting_status.rs +++ b/catalyst-gateway/bin/src/event_db/legacy/types/voting_status.rs @@ -1,13 +1,15 @@ //! Voting Status -use super::objective::ObjectiveId; -/// A voting status -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct VotingStatus { - /// The objective ID - pub(crate) objective_id: ObjectiveId, - /// The voting status - pub(crate) open: bool, - /// The settings - pub(crate) settings: Option, -} +// Not currently used +// use super::objective::ObjectiveId; +// +// A voting status +// #[derive(Debug, Clone, PartialEq, Eq)] +// pub(crate) struct VotingStatus { +// The objective ID +// pub(crate) objective_id: ObjectiveId, +// The voting status +// pub(crate) open: bool, +// The settings +// pub(crate) settings: Option, +// } diff --git a/catalyst-gateway/bin/src/service/api/cardano/date_time_to_slot_number_get.rs b/catalyst-gateway/bin/src/service/api/cardano/date_time_to_slot_number_get.rs index fb053fd812..bc9738e8f0 100644 --- a/catalyst-gateway/bin/src/service/api/cardano/date_time_to_slot_number_get.rs +++ b/catalyst-gateway/bin/src/service/api/cardano/date_time_to_slot_number_get.rs @@ -1,7 +1,6 @@ //! Implementation of the GET `/date_time_to_slot_number` endpoint -use poem_extensions::{response, UniResponse::T200}; -use poem_openapi::payload::Json; +use poem_openapi::{payload::Json, ApiResponse}; use crate::{ event_db::{ @@ -13,22 +12,21 @@ use crate::{ network::Network, slot_info::{Slot, SlotInfo}, }, - responses::{ - resp_2xx::OK, - resp_4xx::ApiValidationError, - resp_5xx::{handle_5xx_response, ServerError, ServiceUnavailable}, - }, + responses::WithErrorResponses, }, state::State, }; -/// # All Responses -pub(crate) type AllResponses = response! { - 200: OK>, - 400: ApiValidationError, - 500: ServerError, - 503: ServiceUnavailable, -}; +/// Endpoint responses. +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// Returns the slot info. + #[oai(status = 200)] + Ok(Json), +} + +/// All responses. +pub(crate) type AllResponses = WithErrorResponses; /// # GET `/date_time_to_slot_number` #[allow(clippy::unused_async)] @@ -71,20 +69,21 @@ pub(crate) async fn endpoint( let current = match process_slot_info_result(current) { Ok(current) => current, - Err(err) => return handle_5xx_response!(err), + Err(err) => return AllResponses::handle_error(&err), }; let previous = match process_slot_info_result(previous) { Ok(current) => current, - Err(err) => return handle_5xx_response!(err), + Err(err) => return AllResponses::handle_error(&err), }; let next = match process_slot_info_result(next) { Ok(current) => current, - Err(err) => return handle_5xx_response!(err), + Err(err) => return AllResponses::handle_error(&err), }; - T200(OK(Json(SlotInfo { + Responses::Ok(Json(SlotInfo { previous, current, next, - }))) + })) + .into() } diff --git a/catalyst-gateway/bin/src/service/api/cardano/mod.rs b/catalyst-gateway/bin/src/service/api/cardano/mod.rs index 680a67c328..727d2b1bed 100644 --- a/catalyst-gateway/bin/src/service/api/cardano/mod.rs +++ b/catalyst-gateway/bin/src/service/api/cardano/mod.rs @@ -40,14 +40,6 @@ impl CardanoApi { /// /// This endpoint returns the total Cardano's staked ada amount to the corresponded /// user's stake address. - /// - /// ## Responses - /// * 200 OK - Returns the staked ada amount. - /// * 400 Bad Request. - /// * 404 Not Found. - /// * 500 Server Error - If anything within this function fails unexpectedly. - /// * 503 Service Unavailable - Service is not ready, requests to other - /// endpoints should not be sent until the service becomes ready. async fn staked_ada_get( &self, data: Data<&Arc>, /// The stake address of the user. @@ -80,14 +72,6 @@ impl CardanoApi { /// /// This endpoint returns the registration info followed by the [CIP-36](https://cips.cardano.org/cip/CIP-36/) to the /// corresponded user's stake address. - /// - /// ## Responses - /// * 200 OK - Returns the registration info. - /// * 400 Bad Request. - /// * 404 Not Found. - /// * 500 Server Error - If anything within this function fails unexpectedly. - /// * 503 Service Unavailable - Service is not ready, requests to other - /// endpoints should not be sent until the service becomes ready. async fn registration_get( &self, data: Data<&Arc>, /// The stake address of the user. @@ -119,14 +103,6 @@ impl CardanoApi { /// Get Cardano follower's sync state. /// /// This endpoint returns the current cardano follower's sync state info. - /// - /// ## Responses - /// * 200 OK - Returns the follower's sync state. - /// * 400 Bad Request. - /// * 404 Not Found. - /// * 500 Server Error - If anything within this function fails unexpectedly. - /// * 503 Service Unavailable - Service is not ready, requests to other - /// endpoints should not be sent until the service becomes ready. async fn sync_state_get( &self, data: Data<&Arc>, /// Cardano network type. @@ -149,13 +125,6 @@ impl CardanoApi { /// /// This endpoint returns the closest cardano slot info to the provided /// date-time. - /// - /// ## Responses - /// * 200 OK - Returns the slot info. - /// * 400 Bad Request. - /// * 500 Server Error - If anything within this function fails unexpectedly. - /// * 503 Service Unavailable - Service is not ready, requests to other - /// endpoints should not be sent until the service becomes ready. async fn date_time_to_slot_number_get( &self, data: Data<&Arc>, /// The date-time for which the slot number should be calculated. diff --git a/catalyst-gateway/bin/src/service/api/cardano/registration_get.rs b/catalyst-gateway/bin/src/service/api/cardano/registration_get.rs index a6d3e0f11f..86f284dfbf 100644 --- a/catalyst-gateway/bin/src/service/api/cardano/registration_get.rs +++ b/catalyst-gateway/bin/src/service/api/cardano/registration_get.rs @@ -1,10 +1,6 @@ //! Implementation of the GET `/registration` endpoint -use poem_extensions::{ - response, - UniResponse::{T200, T400, T404}, -}; -use poem_openapi::payload::Json; +use poem_openapi::{payload::Json, ApiResponse}; use crate::{ event_db::{cardano::chain_state::SlotNumber, error::NotFoundError}, @@ -13,26 +9,27 @@ use crate::{ objects::cardano::{ network::Network, registration_info::RegistrationInfo, stake_address::StakeAddress, }, - responses::{ - resp_2xx::OK, - resp_4xx::{ApiValidationError, NotFound}, - resp_5xx::{handle_5xx_response, ServerError, ServiceUnavailable}, - }, + responses::WithErrorResponses, }, utilities::check_network, }, state::State, }; -/// # All Responses -#[allow(dead_code)] -pub(crate) type AllResponses = response! { - 200: OK>, - 400: ApiValidationError, - 404: NotFound, - 500: ServerError, - 503: ServiceUnavailable, -}; +/// Endpoint responses +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// The registration information for the stake address queried. + #[oai(status = 200)] + Ok(Json), + /// No valid registration found for the provided stake address + /// and provided slot number. + #[oai(status = 404)] + NotFound, +} + +/// All responses +pub(crate) type AllResponses = WithErrorResponses; /// # GET `/registration` pub(crate) async fn endpoint( @@ -45,7 +42,7 @@ pub(crate) async fn endpoint( let stake_credential = stake_address.payload().as_hash().to_vec(); let network = match check_network(stake_address.network(), provided_network) { Ok(network) => network, - Err(err) => return T400(err), + Err(err) => return AllResponses::handle_error(&err), }; // get the total utxo amount from the database @@ -54,14 +51,15 @@ pub(crate) async fn endpoint( .await { Ok((tx_id, payment_address, voting_info, nonce)) => { - T200(OK(Json(RegistrationInfo::new( + Responses::Ok(Json(RegistrationInfo::new( tx_id, &payment_address, voting_info, nonce, - )))) + ))) + .into() }, - Err(err) if err.is::() => T404(NotFound), - Err(err) => handle_5xx_response!(err), + Err(err) if err.is::() => Responses::NotFound.into(), + Err(err) => AllResponses::handle_error(&err), } } diff --git a/catalyst-gateway/bin/src/service/api/cardano/staked_ada_get.rs b/catalyst-gateway/bin/src/service/api/cardano/staked_ada_get.rs index c06fca9d92..7e039c3f5a 100644 --- a/catalyst-gateway/bin/src/service/api/cardano/staked_ada_get.rs +++ b/catalyst-gateway/bin/src/service/api/cardano/staked_ada_get.rs @@ -1,10 +1,6 @@ //! Implementation of the GET `/staked_ada` endpoint -use poem_extensions::{ - response, - UniResponse::{T200, T400, T404}, -}; -use poem_openapi::payload::Json; +use poem_openapi::{payload::Json, ApiResponse}; use crate::{ event_db::{cardano::chain_state::SlotNumber, error::NotFoundError}, @@ -13,25 +9,26 @@ use crate::{ objects::cardano::{ network::Network, stake_address::StakeAddress, stake_info::StakeInfo, }, - responses::{ - resp_2xx::OK, - resp_4xx::{ApiValidationError, NotFound}, - resp_5xx::{handle_5xx_response, ServerError, ServiceUnavailable}, - }, + responses::WithErrorResponses, }, utilities::check_network, }, state::State, }; -/// # All Responses -pub(crate) type AllResponses = response! { - 200: OK>, - 400: ApiValidationError, - 404: NotFound, - 500: ServerError, - 503: ServiceUnavailable, -}; +/// Endpoint responses. +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// The amount of ADA staked by the queried stake address, as at the indicated slot. + #[oai(status = 200)] + Ok(Json), + /// The queried stake address was not found at the requested slot number. + #[oai(status = 404)] + NotFound, +} + +/// All responses. +pub(crate) type AllResponses = WithErrorResponses; /// # GET `/staked_ada` pub(crate) async fn endpoint( @@ -45,7 +42,7 @@ pub(crate) async fn endpoint( let network = match check_network(stake_address.network(), provided_network) { Ok(network) => network, - Err(err) => return T400(err), + Err(err) => return AllResponses::handle_error(&err), }; // get the total utxo amount from the database @@ -54,12 +51,13 @@ pub(crate) async fn endpoint( .await { Ok((amount, slot_number)) => { - T200(OK(Json(StakeInfo { + Responses::Ok(Json(StakeInfo { amount, slot_number, - }))) + })) + .into() }, - Err(err) if err.is::() => T404(NotFound), - Err(err) => handle_5xx_response!(err), + Err(err) if err.is::() => Responses::NotFound.into(), + Err(err) => AllResponses::handle_error(&err), } } diff --git a/catalyst-gateway/bin/src/service/api/cardano/sync_state_get.rs b/catalyst-gateway/bin/src/service/api/cardano/sync_state_get.rs index c8abdae323..e80e2a3b60 100644 --- a/catalyst-gateway/bin/src/service/api/cardano/sync_state_get.rs +++ b/catalyst-gateway/bin/src/service/api/cardano/sync_state_get.rs @@ -1,32 +1,29 @@ //! Implementation of the GET `/sync_state` endpoint -use poem_extensions::{ - response, - UniResponse::{T200, T404}, -}; -use poem_openapi::payload::Json; +use poem_openapi::{payload::Json, ApiResponse}; use crate::{ event_db::error::NotFoundError, service::common::{ objects::cardano::{network::Network, sync_state::SyncState}, - responses::{ - resp_2xx::OK, - resp_4xx::{ApiValidationError, NotFound}, - resp_5xx::{handle_5xx_response, ServerError, ServiceUnavailable}, - }, + responses::WithErrorResponses, }, state::State, }; -/// # All Responses -pub(crate) type AllResponses = response! { - 200: OK>, - 400: ApiValidationError, - 404: NotFound, - 500: ServerError, - 503: ServiceUnavailable, -}; +/// Endpoint responses. +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// The synchronisation state of the blockchain with the catalyst gateway service. + #[oai(status = 200)] + Ok(Json), + /// The network is unknown. Catalyst gateway is not syncing the queried network. + #[oai(status = 404)] + NotFound, +} + +/// All responses. +pub(crate) type AllResponses = WithErrorResponses; /// # GET `/sync_state` #[allow(clippy::unused_async)] @@ -37,13 +34,14 @@ pub(crate) async fn endpoint(state: &State, network: Option) -> AllResp match event_db.last_updated_state(network.into()).await { Ok((slot_number, block_hash, last_updated)) => { - T200(OK(Json(SyncState { + Responses::Ok(Json(SyncState { slot_number, block_hash: block_hash.into(), last_updated, - }))) + })) + .into() }, - Err(err) if err.is::() => T404(NotFound), - Err(err) => handle_5xx_response!(err), + Err(err) if err.is::() => Responses::NotFound.into(), + Err(err) => AllResponses::handle_error(&err), } } diff --git a/catalyst-gateway/bin/src/service/api/health/live_get.rs b/catalyst-gateway/bin/src/service/api/health/live_get.rs index db198f8c6e..3acf18bf27 100644 --- a/catalyst-gateway/bin/src/service/api/health/live_get.rs +++ b/catalyst-gateway/bin/src/service/api/health/live_get.rs @@ -1,21 +1,38 @@ //! Implementation of the GET /health/live endpoint -use poem_extensions::{response, UniResponse::T204}; -use tracing::{error, info, warn}; - -use crate::service::common::responses::{ - resp_2xx::NoContent, - resp_4xx::ApiValidationError, - resp_5xx::{ServerError, ServiceUnavailable}, -}; - -/// All responses -pub(crate) type AllResponses = response! { - 204: NoContent, - 400: ApiValidationError, - 500: ServerError, - 503: ServiceUnavailable, -}; +use std::sync::atomic::{AtomicBool, Ordering}; + +use poem_openapi::ApiResponse; + +use crate::service::common::responses::WithErrorResponses; + +/// Flag to determine if the service has started +static IS_LIVE: AtomicBool = AtomicBool::new(true); + +/// Set the started flag to `true` +#[allow(dead_code)] +pub(crate) fn set_live(flag: bool) { + IS_LIVE.store(flag, Ordering::Release); +} +/// Get the started flag +#[allow(dead_code)] +fn is_live() -> bool { + IS_LIVE.load(Ordering::Acquire) +} + +/// Endpoint responses. +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// Service is OK and can keep running. + #[oai(status = 204)] + NoContent, + /// Service is possibly not running reliably. + #[oai(status = 503)] + ServiceUnavailable, +} + +/// All responses. +pub(crate) type AllResponses = WithErrorResponses; /// # GET /health/live /// @@ -26,24 +43,11 @@ pub(crate) type AllResponses = response! { /// /// In this service, liveness is assumed unless there are multiple panics generated /// by an endpoint in a short window. -/// -/// ## Responses -/// -/// * 204 No Content - Service is OK and can keep running. -/// * 400 API Validation Error -/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible -/// but unlikely) -/// * 503 Service Unavailable - Service is possibly not running reliably. #[allow(clippy::unused_async)] pub(crate) async fn endpoint() -> AllResponses { - // TODO: Detect if too many panics have occurred in a defined window. - // If so, return a 503 - // T503(ServiceUnavailable) - - info!("liveness check"); - warn!("liveness check - warn"); - error!("liveness check - error"); - - // otherwise everything seems to be A-OK - T204(NoContent) + if is_live() { + Responses::NoContent.into() + } else { + Responses::ServiceUnavailable.into() + } } diff --git a/catalyst-gateway/bin/src/service/api/health/mod.rs b/catalyst-gateway/bin/src/service/api/health/mod.rs index 9a7b190c46..0e886a474a 100644 --- a/catalyst-gateway/bin/src/service/api/health/mod.rs +++ b/catalyst-gateway/bin/src/service/api/health/mod.rs @@ -10,6 +10,8 @@ mod live_get; mod ready_get; mod started_get; +pub(crate) use started_get::started; + /// Health API Endpoints pub(crate) struct HealthApi; @@ -25,13 +27,6 @@ impl HealthApi { /// /// *This endpoint is for internal use of the service deployment infrastructure. /// It may not be exposed publicly.* - /// - /// ## Responses - /// - /// * 204 No Content - Service is Started and can serve requests. - /// * 500 Server Error - If anything within this function fails unexpectedly. - /// * 503 Service Unavailable - Service has not started, do not send other requests - /// yet. async fn started_get(&self) -> started_get::AllResponses { started_get::endpoint().await } @@ -46,13 +41,6 @@ impl HealthApi { /// /// *This endpoint is for internal use of the service deployment infrastructure. /// It may not be exposed publicly.* - /// - /// ## Responses - /// - /// * 204 No Content - Service is Ready and can serve requests. - /// * 500 Server Error - If anything within this function fails unexpectedly. - /// * 503 Service Unavailable - Service is not ready, requests to other - /// endpoints should not be sent until the service becomes ready. async fn ready_get(&self, state: Data<&Arc>) -> ready_get::AllResponses { ready_get::endpoint(state).await } @@ -66,13 +54,6 @@ impl HealthApi { /// /// *This endpoint is for internal use of the service deployment infrastructure. /// It may not be exposed publicly. Refer to []* - /// - /// ## Responses - /// - /// * 204 No Content - Service is OK and can keep running. - /// * 500 Server Error - If anything within this function fails unexpectedly. - /// (Possible but unlikely) - /// * 503 Service Unavailable - Service is possibly not running reliably. async fn live_get(&self) -> live_get::AllResponses { live_get::endpoint().await } diff --git a/catalyst-gateway/bin/src/service/api/health/ready_get.rs b/catalyst-gateway/bin/src/service/api/health/ready_get.rs index 99abdbeeb7..cdf1d2ebb2 100644 --- a/catalyst-gateway/bin/src/service/api/health/ready_get.rs +++ b/catalyst-gateway/bin/src/service/api/health/ready_get.rs @@ -3,28 +3,26 @@ use std::sync::Arc; use poem::web::Data; -use poem_extensions::{ - response, - UniResponse::{T204, T503}, -}; +use poem_openapi::ApiResponse; use crate::{ - event_db::schema_check::MismatchedSchemaError, - service::common::responses::{ - resp_2xx::NoContent, - resp_4xx::ApiValidationError, - resp_5xx::{handle_5xx_response, ServerError, ServiceUnavailable}, - }, + event_db::schema_check::MismatchedSchemaError, service::common::responses::WithErrorResponses, state::State, }; -/// All responses -pub(crate) type AllResponses = response! { - 204: NoContent, - 400: ApiValidationError, - 500: ServerError, - 503: ServiceUnavailable, -}; +/// Endpoint responses. +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// Service is Started and can serve requests. + #[oai(status = 204)] + NoContent, + /// Service is not ready, do not send other requests. + #[oai(status = 503)] + ServiceUnavailable, +} + +/// All responses. +pub(crate) type AllResponses = WithErrorResponses; /// # GET /health/ready /// @@ -43,24 +41,16 @@ pub(crate) type AllResponses = response! { /// and is not able to properly service requests while it is occurring. /// This would let the load balancer shift traffic to other instances of this /// service that are ready. -/// -/// ## Responses -/// -/// * 204 No Content - Service is Ready to serve requests. -/// * 400 API Validation Error -/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible -/// but unlikely) -/// * 503 Service Unavailable - Service is not ready, do not send other requests. pub(crate) async fn endpoint(state: Data<&Arc>) -> AllResponses { match state.event_db().schema_version_check().await { Ok(_) => { tracing::debug!("DB schema version status ok"); - T204(NoContent) + Responses::NoContent.into() }, Err(err) if err.is::() => { tracing::error!("{err}"); - T503(ServiceUnavailable) + Responses::ServiceUnavailable.into() }, - Err(err) => handle_5xx_response!(err), + Err(err) => AllResponses::handle_error(&err), } } diff --git a/catalyst-gateway/bin/src/service/api/health/started_get.rs b/catalyst-gateway/bin/src/service/api/health/started_get.rs index 981d4788c0..c2a990a584 100644 --- a/catalyst-gateway/bin/src/service/api/health/started_get.rs +++ b/catalyst-gateway/bin/src/service/api/health/started_get.rs @@ -1,20 +1,36 @@ //! Implementation of the GET /health/started endpoint -use poem_extensions::{response, UniResponse::T204}; - -use crate::service::common::responses::{ - resp_2xx::NoContent, - resp_4xx::ApiValidationError, - resp_5xx::{ServerError, ServiceUnavailable}, -}; - -/// All responses -pub(crate) type AllResponses = response! { - 204: NoContent, - 400: ApiValidationError, - 500: ServerError, - 503: ServiceUnavailable, -}; +use std::sync::atomic::{AtomicBool, Ordering}; + +use poem_openapi::ApiResponse; + +use crate::service::common::responses::WithErrorResponses; + +/// Flag to determine if the service has started +static IS_STARTED: AtomicBool = AtomicBool::new(false); + +/// Set the started flag to `true` +pub(crate) fn started() { + IS_STARTED.store(true, Ordering::Release); +} +/// Get the started flag +fn is_started() -> bool { + IS_STARTED.load(Ordering::Acquire) +} + +/// Endpoint responses. +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// Service is Started and can serve requests. + #[oai(status = 204)] + NoContent, + /// Service is not ready, do not send other requests. + #[oai(status = 503)] + ServiceUnavailable, +} + +/// All responses. +pub(crate) type AllResponses = WithErrorResponses; /// # GET /health/started /// @@ -33,16 +49,11 @@ pub(crate) type AllResponses = response! { /// into memory or processed in some way before the API can return valid /// responses. In that scenario this endpoint would return 503 until that /// startup processing was fully completed. -/// -/// ## Responses -/// -/// * 204 No Content - Service is Started and can serve requests. -/// * 400 API Validation Error -/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible -/// but unlikely) -/// * 503 Service Unavailable - Service has not started, do not send other requests. #[allow(clippy::unused_async)] pub(crate) async fn endpoint() -> AllResponses { - // otherwise everything seems to be A-OK - T204(NoContent) + if is_started() { + Responses::NoContent.into() + } else { + Responses::ServiceUnavailable.into() + } } diff --git a/catalyst-gateway/bin/src/service/api/legacy/registration/mod.rs b/catalyst-gateway/bin/src/service/api/legacy/registration/mod.rs index 73c4047fc6..398c68c1c4 100644 --- a/catalyst-gateway/bin/src/service/api/legacy/registration/mod.rs +++ b/catalyst-gateway/bin/src/service/api/legacy/registration/mod.rs @@ -2,12 +2,11 @@ use std::sync::Arc; use poem::web::Data; -use poem_extensions::{response, UniResponse::T200}; use poem_openapi::{ param::{Path, Query}, payload::Json, types::Example, - OpenApi, + ApiResponse, OpenApi, }; use crate::{ @@ -17,11 +16,7 @@ use crate::{ event_id::EventId, voter_registration::VoterRegistration, voting_public_key::VotingPublicKey, }, - responses::{ - resp_2xx::OK, - resp_4xx::{BadRequest, NotFound}, - resp_5xx::{ServerError, ServiceUnavailable}, - }, + responses::WithErrorResponses, tags::ApiTags, }, utilities::middleware::schema_validation::schema_version_validation, @@ -32,6 +27,17 @@ use crate::{ /// Registration API Endpoints pub(crate) struct RegistrationApi; +/// Endpoint responses +#[derive(ApiResponse)] +enum Responses { + /// Voter's registration info + #[oai(status = 200)] + Ok(Json), +} + +/// All responses +type AllResponses = WithErrorResponses; + #[OpenApi(prefix_path = "/registration", tag = "ApiTags::Registration")] impl RegistrationApi { #[oai( @@ -67,13 +73,7 @@ impl RegistrationApi { /// in the response. Otherwise, it will be omitted. #[oai(default)] with_delegators: Query, - ) -> response! { - 200: OK>, - 400: BadRequest>, - 404: NotFound, - 500: ServerError, - 503: ServiceUnavailable, - } { - T200(OK(Json(VoterRegistration::example()))) + ) -> AllResponses { + Responses::Ok(Json(VoterRegistration::example())).into() } } diff --git a/catalyst-gateway/bin/src/service/api/legacy/v0/message_post.rs b/catalyst-gateway/bin/src/service/api/legacy/v0/message_post.rs index 762f763ea8..5e04ea3e77 100644 --- a/catalyst-gateway/bin/src/service/api/legacy/v0/message_post.rs +++ b/catalyst-gateway/bin/src/service/api/legacy/v0/message_post.rs @@ -1,42 +1,33 @@ //! Implementation of the POST /message endpoint -use poem_extensions::{response, UniResponse::T200}; -use poem_openapi::payload::{Binary, Json}; +use poem_openapi::{ + payload::{Binary, Json}, + ApiResponse, +}; use crate::service::common::{ objects::legacy::fragments_processing_summary::FragmentsProcessingSummary, - responses::{ - resp_2xx::OK, - resp_4xx::BadRequest, - resp_5xx::{ServerError, ServiceUnavailable}, - }, + responses::WithErrorResponses, }; +/// Endpoint responses +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// Contains information about accepted and rejected fragments. + #[oai(status = 200)] + Ok(Json), +} + /// All responses -pub(crate) type AllResponses = response! { - 200: OK>, - 400: BadRequest>, - 500: ServerError, - 503: ServiceUnavailable, -}; +pub(crate) type AllResponses = WithErrorResponses; /// # POST /message /// /// Message post endpoint. /// /// When successful, returns a summary of fragments accepted and rejected. -/// -/// ## Responses -/// -/// * 200 JSON Fragments Processing Summary - Contains information about accepted and -/// rejected fragments. -/// * 400 JSON Fragments Processing Summary - Contains information about accepted and -/// rejected fragments. -/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible -/// but unlikely) -/// * 503 Service Unavailable - Service has not started, do not send other requests. #[allow(clippy::unused_async)] pub(crate) async fn endpoint(_message: Binary>) -> AllResponses { // otherwise everything seems to be A-OK - T200(OK(Json(FragmentsProcessingSummary::default()))) + Responses::Ok(Json(FragmentsProcessingSummary::default())).into() } diff --git a/catalyst-gateway/bin/src/service/api/legacy/v0/plans_get.rs b/catalyst-gateway/bin/src/service/api/legacy/v0/plans_get.rs index a8b523fce8..8f7c600d88 100644 --- a/catalyst-gateway/bin/src/service/api/legacy/v0/plans_get.rs +++ b/catalyst-gateway/bin/src/service/api/legacy/v0/plans_get.rs @@ -3,43 +3,28 @@ use std::sync::Arc; use poem::web::Data; -use poem_extensions::{response, UniResponse::T200}; -use poem_openapi::payload::Json; +use poem_openapi::{payload::Json, ApiResponse}; use crate::{ - service::common::{ - objects::legacy::vote_plan::VotePlan, - responses::{ - resp_2xx::OK, - resp_4xx::BadRequest, - resp_5xx::{ServerError, ServiceUnavailable}, - }, - }, + service::common::{objects::legacy::vote_plan::VotePlan, responses::WithErrorResponses}, state::State, }; +/// Endpoint responses +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// JSON array with the list of vote plans with their respective data. + #[oai(status = 200)] + Ok(Json>), +} + /// All responses -pub(crate) type AllResponses = response! { - 200: OK>>, - 400: BadRequest>>, - 500: ServerError, - 503: ServiceUnavailable, -}; +pub(crate) type AllResponses = WithErrorResponses; /// GET /v0/vote/active/plans /// /// Get all active vote plans endpoint. -/// -/// ## Responses -/// -/// * 200 with a JSON array with the list of vote plans with their respective data. -/// * 400 Bad request with a JSON array with the list of vote plans with their respective -/// data. -/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible -/// but unlikely) -/// * 503 Service Unavailable - Service has not started, do not send other requests. #[allow(clippy::unused_async)] pub(crate) async fn endpoint(_state: Data<&Arc>) -> AllResponses { - // otherwise everything seems to be A-OK - T200(OK(Json(Vec::new()))) + Responses::Ok(Json(Vec::new())).into() } diff --git a/catalyst-gateway/bin/src/service/api/legacy/v1/account_votes_get.rs b/catalyst-gateway/bin/src/service/api/legacy/v1/account_votes_get.rs index 80fd340d53..70dea8d4d2 100644 --- a/catalyst-gateway/bin/src/service/api/legacy/v1/account_votes_get.rs +++ b/catalyst-gateway/bin/src/service/api/legacy/v1/account_votes_get.rs @@ -3,28 +3,26 @@ use std::sync::Arc; use poem::web::Data; -use poem_extensions::{response, UniResponse::T200}; -use poem_openapi::{param::Path, payload::Json}; +use poem_openapi::{param::Path, payload::Json, ApiResponse}; use crate::{ service::common::{ objects::legacy::account_votes::{AccountId, AccountVote}, - responses::{ - resp_2xx::OK, - resp_4xx::BadRequest, - resp_5xx::{ServerError, ServiceUnavailable}, - }, + responses::WithErrorResponses, }, state::State, }; +/// Endpoint responses +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// JSON array of the number of voted proposals in a plan. + #[oai(status = 200)] + Ok(Json>), +} + /// All responses -pub(crate) type AllResponses = response! { - 200: OK>>, - 400: BadRequest>>, - 500: ServerError, - 503: ServiceUnavailable, -}; +pub(crate) type AllResponses = WithErrorResponses; /// GET /v1/votes/plans/account-votes/:account_id /// @@ -32,18 +30,9 @@ pub(crate) type AllResponses = response! { /// /// For each active vote plan, this endpoint returns an array /// with the proposal index number that the account voted for. -/// -/// ## Responses -/// -/// * 200 with a JSON array of the number of voted proposals in a plan. -/// * 400 Bad request with a JSON array of the number of voted proposals in a plan -/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible -/// but unlikely) -/// * 503 Service Unavailable - Service has not started, do not send other requests. #[allow(clippy::unused_async)] pub(crate) async fn endpoint( _state: Data<&Arc>, _account_id: Path, ) -> AllResponses { - // otherwise everything seems to be A-OK - T200(OK(Json(Vec::new()))) + Responses::Ok(Json(Vec::new())).into() } diff --git a/catalyst-gateway/bin/src/service/api/legacy/v1/fragments_post.rs b/catalyst-gateway/bin/src/service/api/legacy/v1/fragments_post.rs index fe245c4cb4..50b8041c6d 100644 --- a/catalyst-gateway/bin/src/service/api/legacy/v1/fragments_post.rs +++ b/catalyst-gateway/bin/src/service/api/legacy/v1/fragments_post.rs @@ -1,39 +1,29 @@ //! Implementation of the GET /fragments endpoint -use poem_extensions::{response, UniResponse::T200}; -use poem_openapi::payload::Json; +use poem_openapi::{payload::Json, ApiResponse}; use crate::service::common::{ objects::legacy::{ fragments_batch::FragmentsBatch, fragments_processing_summary::FragmentsProcessingSummary, }, - responses::{ - resp_2xx::OK, - resp_4xx::BadRequest, - resp_5xx::{ServerError, ServiceUnavailable}, - }, + responses::WithErrorResponses, }; +/// Endpoint responses +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// Fragments processing summary + #[oai(status = 200)] + Ok(Json), +} + /// All responses -pub(crate) type AllResponses = response! { - 200: OK>, - 400: BadRequest>, - 500: ServerError, - 503: ServiceUnavailable, -}; +pub(crate) type AllResponses = WithErrorResponses; /// # GET /fragments /// /// Process a fragments batch. -/// -/// ## Responses -/// -/// * 200 No Content - Service is OK and can keep running. -/// * 400 Bad Request -/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible -/// but unlikely) -/// * 503 Service Unavailable - Service is possibly not running reliably. #[allow(clippy::unused_async)] pub(crate) async fn endpoint(_fragments_batch: FragmentsBatch) -> AllResponses { - T200(OK(Json(FragmentsProcessingSummary::default()))) + Responses::Ok(Json(FragmentsProcessingSummary::default())).into() } diff --git a/catalyst-gateway/bin/src/service/api/legacy/v1/fragments_statuses.rs b/catalyst-gateway/bin/src/service/api/legacy/v1/fragments_statuses.rs index b27a3e1ab5..1dd86ed9a2 100644 --- a/catalyst-gateway/bin/src/service/api/legacy/v1/fragments_statuses.rs +++ b/catalyst-gateway/bin/src/service/api/legacy/v1/fragments_statuses.rs @@ -2,38 +2,28 @@ use std::collections::HashMap; -use poem_extensions::{response, UniResponse::T200}; -use poem_openapi::payload::Json; +use poem_openapi::{payload::Json, ApiResponse}; use crate::service::common::{ objects::legacy::{fragment_status::FragmentStatus, fragments_processing_summary::FragmentId}, - responses::{ - resp_2xx::OK, - resp_4xx::BadRequest, - resp_5xx::{ServerError, ServiceUnavailable}, - }, + responses::WithErrorResponses, }; +/// Endpoint responses +#[derive(ApiResponse)] +pub(crate) enum Responses { + /// Statuses of the fragments by id. + #[oai(status = 200)] + Ok(Json>), +} + /// All responses -pub(crate) type AllResponses = response! { - 200: OK>>, - 400: BadRequest>>, - 500: ServerError, - 503: ServiceUnavailable, -}; +pub(crate) type AllResponses = WithErrorResponses; /// # GET /fragments/statuses /// /// Get fragments statuses endpoint. -/// -/// ## Responses -/// -/// * 200 Fragments Statuses - Statuses of the fragments by id. -/// * 400 Bad Request -/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible -/// but unlikely) -/// * 503 Service Unavailable - Service is possibly not running reliably. #[allow(clippy::unused_async)] pub(crate) async fn endpoint(_fragment_ids: Vec) -> AllResponses { - T200(OK(Json(HashMap::new()))) + Responses::Ok(Json(HashMap::new())).into() } diff --git a/catalyst-gateway/bin/src/service/api/mod.rs b/catalyst-gateway/bin/src/service/api/mod.rs index d99c66cc66..0af519e048 100644 --- a/catalyst-gateway/bin/src/service/api/mod.rs +++ b/catalyst-gateway/bin/src/service/api/mod.rs @@ -9,7 +9,6 @@ use health::HealthApi; use legacy::LegacyApi; use local_ip_address::list_afinet_netifas; use poem_openapi::{ContactObject, LicenseObject, OpenApiService, ServerObject}; -use test_endpoints::TestApi; use self::cardano::CardanoApi; use crate::settings::{DocsSettings, API_URL_PREFIX}; @@ -17,7 +16,8 @@ use crate::settings::{DocsSettings, API_URL_PREFIX}; mod cardano; mod health; mod legacy; -mod test_endpoints; + +pub(crate) use health::started; /// The name of the API const API_TITLE: &str = "Catalyst Gateway"; @@ -60,10 +60,9 @@ const TERMS_OF_SERVICE: &str = /// Create the `OpenAPI` definition pub(crate) fn mk_api( hosts: Vec, settings: &DocsSettings, -) -> OpenApiService<(TestApi, HealthApi, CardanoApi, LegacyApi), ()> { +) -> OpenApiService<(HealthApi, CardanoApi, LegacyApi), ()> { let mut service = OpenApiService::new( ( - TestApi, HealthApi, CardanoApi, (legacy::RegistrationApi, legacy::V0Api, legacy::V1Api), diff --git a/catalyst-gateway/bin/src/service/api/test_endpoints/mod.rs b/catalyst-gateway/bin/src/service/api/test_endpoints/mod.rs deleted file mode 100644 index ac3966f1ba..0000000000 --- a/catalyst-gateway/bin/src/service/api/test_endpoints/mod.rs +++ /dev/null @@ -1,121 +0,0 @@ -//! These endpoints are not part of the API, and are for testing features of -//! Poem before integration with the real API endpoints. - -mod test_get; -mod test_post; - -use std::sync::Arc; - -use poem::web::Data; -use poem_openapi::{ - param::{Path, Query}, - OpenApi, -}; - -use crate::{ - service::{ - common::tags::ApiTags, utilities::middleware::schema_validation::schema_version_validation, - }, - state::State, -}; - -/// Test API Endpoints -pub(crate) struct TestApi; - -#[OpenApi(prefix_path = "/test", tag = "ApiTags::Test")] -impl TestApi { - #[oai( - path = "/test/:id/test/:action", - method = "get", - operation_id = "testGet", - transform = "schema_version_validation", - deprecated - )] - /// Test Get API - /// - /// An Endpoint to test validation of get endpoints. - /// - /// ## Note - /// - /// *This is not a real endpoint, for test and demo purposes only. To be removed.* - async fn test_get( - &self, - /// Get the state, not part of the path, but supplied by Poem. - data: Data<&Arc>, - #[oai(validator( - multiple_of = "5", - minimum(value = "5"), - maximum(value = "21", exclusive) - ))] - /// The ID of the test. - /// - /// This comment ends up in the documentation. - /// - /// * 5 will print an info log - /// * 10 will print a warn log - /// * 15 will print a error log - /// * 20 will panic which should generate a 500 - id: Path, - #[oai(validator( - pattern = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", - max_length = "36" - ))] - /// The action just needs to be any valid UUID. - /// - /// # Make sure its a UUID - action: Path, - #[oai(validator(min_items = 0, max_items = 3, unique_items))] - /// List your favorite pets, in order of preference - pet: Query>>, - ) -> test_get::AllResponses { - test_get::endpoint(data.clone(), *id, &action, &pet).await - } - - #[oai( - path = "/test/:id/test/:action", - method = "post", - operation_id = "testPost", - tag = "ApiTags::TestTag2", - deprecated - )] - /// Test Post API - /// - /// An Endpoint to test validation of get endpoints. - /// - /// ## Responses - /// - /// * 204 No Content - Service is Started and can serve requests. - /// * 500 Server Error - If anything within this function fails unexpectedly. - /// * 503 Service Unavailable - Service has not started, do not send other requests - /// yet. - /// - /// ## Note - /// - /// *This is not a real endpoint, for test and demo purposes only. To be removed.* - async fn test_post( - &self, - #[oai(validator( - multiple_of = "5", - minimum(value = "5"), - maximum(value = "21", exclusive) - ))] - /// The ID of the test. - /// - /// * 5 will print an info log - /// * 10 will print a warn log - /// * 15 will print a error log - /// * 20 will panic which should generate a 500 - id: Path, - #[oai(validator( - pattern = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", - max_length = "36", - min_length = "36" - ))] - /// The action just needs to be any valid UUID. - /// - /// # Make sure its a UUID - action: Path, - ) -> test_post::AllResponses { - test_post::endpoint(*id, &action).await - } -} diff --git a/catalyst-gateway/bin/src/service/api/test_endpoints/test_get.rs b/catalyst-gateway/bin/src/service/api/test_endpoints/test_get.rs deleted file mode 100644 index e970ae8d0e..0000000000 --- a/catalyst-gateway/bin/src/service/api/test_endpoints/test_get.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! Test validation in a GET endpoint - -use std::sync::Arc; - -use poem_extensions::{ - response, - UniResponse::{T204, T503}, -}; -use tracing::{error, info, warn}; - -use crate::{ - service::common::responses::{ - resp_2xx::NoContent, - resp_4xx::ApiValidationError, - resp_5xx::{ServerError, ServiceUnavailable}, - }, - state::State, -}; - -/// # All Responses -pub(crate) type AllResponses = response! { - 204: NoContent, - 400: ApiValidationError, - 500: ServerError, - 503: ServiceUnavailable, -}; - -#[derive(::poem_openapi::Enum, Debug, Eq, PartialEq, Hash, Clone)] -/// A query parameter that is one of these animals. -pub(crate) enum Animals { - /// Preferred pet is dogs - Dogs, - /// Preferred pet is cats - Cats, - /// Preferred pet is rabbits - Rabbits, -} - -/// # GET /test/test -/// -/// Just a test endpoint. -/// -/// Always logs at info level. -/// If the id parameter is 10, it will log at warn level. -/// If the id parameter is 15, it will log at error level, and return a 503. -/// If the id parameter is 20, it will panic. -/// -/// ## Responses -/// -/// * 204 No Content - Service is OK and can keep running. -/// * 400 API Validation Error -/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible -/// but unlikely) -/// * 503 Service Unavailable - Service is possibly not running reliably. -#[allow(clippy::unused_async, clippy::panic)] -pub(crate) async fn endpoint( - _state: Arc, id: i32, action: &String, pet: &Option>, -) -> AllResponses { - info!("id: {id:?}, action: {action:?} pet: {pet:?}"); - let response: AllResponses = match id { - 10 => { - warn!("id: {id:?}, action: {action:?}"); - T204(NoContent) - }, - 15 => { - error!("id: {id:?}, action: {action:?}"); - T503(ServiceUnavailable) - }, - 20 => { - // Intentional panic for testing purposes - Allowed above. - panic!("id: {id:?}, action: {action:?}"); - }, - _ => T204(NoContent), - }; - - response -} diff --git a/catalyst-gateway/bin/src/service/api/test_endpoints/test_post.rs b/catalyst-gateway/bin/src/service/api/test_endpoints/test_post.rs deleted file mode 100644 index 5e4283f2c1..0000000000 --- a/catalyst-gateway/bin/src/service/api/test_endpoints/test_post.rs +++ /dev/null @@ -1,44 +0,0 @@ -//! Test validation of a json body of a POST Endpoint. - -use poem_extensions::{response, UniResponse::T204}; -use tracing::info; - -use crate::service::common::responses::{ - resp_2xx::NoContent, - resp_4xx::ApiValidationError, - resp_5xx::{ServerError, ServiceUnavailable}, -}; - -/// All responses -pub(crate) type AllResponses = response! { - 204: NoContent, - 400: ApiValidationError, - 500: ServerError, - 503: ServiceUnavailable, -}; - -/// # POST /test/test -/// -/// Liveness endpoint. -/// -/// Kubernetes (and others) use this endpoint to determine if the service is able -/// to keep running. -/// -/// In this service, liveness is assumed unless there are multiple panics generated -/// by an endpoint in a short window. -/// -/// ## Responses -/// -/// * 204 No Content - Service is OK and can keep running. -/// * 400 API Validation Error. -/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible -/// but unlikely) -/// * 503 Service Unavailable - Service is possibly not running reliably. -#[allow(clippy::unused_async)] -pub(crate) async fn endpoint(id: i32, action: &String) -> AllResponses { - let response: AllResponses = { - info!("id: {id:?}, action: {action:?}"); - T204(NoContent) - }; - response -} diff --git a/catalyst-gateway/bin/src/service/common/objects/cardano/slot_info.rs b/catalyst-gateway/bin/src/service/common/objects/cardano/slot_info.rs index 2578d8e38a..f4d2215726 100644 --- a/catalyst-gateway/bin/src/service/common/objects/cardano/slot_info.rs +++ b/catalyst-gateway/bin/src/service/common/objects/cardano/slot_info.rs @@ -45,12 +45,15 @@ impl Example for Slot { #[oai(example = true)] pub(crate) struct SlotInfo { /// Previous slot info. + #[oai(skip_serializing_if_is_none)] pub(crate) previous: Option, /// Current slot info. + #[oai(skip_serializing_if_is_none)] pub(crate) current: Option, /// Next slot info. + #[oai(skip_serializing_if_is_none)] pub(crate) next: Option, } diff --git a/catalyst-gateway/bin/src/service/common/objects/mod.rs b/catalyst-gateway/bin/src/service/common/objects/mod.rs index 43d72a084a..8a52583b35 100644 --- a/catalyst-gateway/bin/src/service/common/objects/mod.rs +++ b/catalyst-gateway/bin/src/service/common/objects/mod.rs @@ -2,3 +2,5 @@ pub(crate) mod cardano; pub(crate) mod legacy; +pub(crate) mod server_error; +pub(crate) mod validation_error; diff --git a/catalyst-gateway/bin/src/service/common/objects/server_error.rs b/catalyst-gateway/bin/src/service/common/objects/server_error.rs new file mode 100644 index 0000000000..980f4329c6 --- /dev/null +++ b/catalyst-gateway/bin/src/service/common/objects/server_error.rs @@ -0,0 +1,52 @@ +//! Define `ServerError` type. + +use poem_openapi::{types::Example, Object}; +use url::Url; +use uuid::Uuid; + +/// While using macro-vis lib, you will get the `uncommon_codepoints` warning, so you will +/// probably want to place this in your crate root +use crate::settings::generate_github_issue_url; + +#[derive(Debug, Object)] +#[oai(example, skip_serializing_if_is_none)] +/// Server Error response to a Bad request. +pub(crate) struct ServerError { + /// Unique ID of this Server Error so that it can be located easily for debugging. + id: Uuid, + /// *Optional* SHORT Error message. + /// Will not contain sensitive information, internal details or backtraces. + // TODO(bkioshn): https://github.com/input-output-hk/catalyst-voices/issues/239 + #[oai(validator(max_length = "100", pattern = "^[0-9a-zA-Z].*$"))] + msg: String, + /// A URL to report an issue. + // TODO(bkioshn): https://github.com/input-output-hk/catalyst-voices/issues/239 + #[oai(validator(max_length = "1000"))] + issue: Option, +} + +impl ServerError { + /// Create a new Server Error Response Payload. + pub(crate) fn new(msg: Option) -> Self { + let msg = msg.unwrap_or( + "Internal Server Error. Please report the issue to the service owner.".to_string(), + ); + let id = Uuid::new_v4(); + let issue_title = format!("Internal Server Error - {id}"); + let issue = generate_github_issue_url(&issue_title); + + Self { id, msg, issue } + } + + /// Get the id of this Server Error. + pub(crate) fn id(&self) -> Uuid { + self.id + } +} + +impl Example for ServerError { + /// Example for the Server Error Payload. + fn example() -> Self { + Self::new(Some("Server Error".to_string())) + } +} diff --git a/catalyst-gateway/bin/src/service/common/objects/validation_error.rs b/catalyst-gateway/bin/src/service/common/objects/validation_error.rs new file mode 100644 index 0000000000..9d6932f0c5 --- /dev/null +++ b/catalyst-gateway/bin/src/service/common/objects/validation_error.rs @@ -0,0 +1,19 @@ +//! Define `ValidationError` type. + +use poem_openapi::Object; + +/// Common error message type. +/// It has failed to pass validation, as specified by the `OpenAPI` schema. +#[derive(Object)] +pub(crate) struct ValidationError { + /// Error message + #[oai(validator(max_length = "1000"))] + message: String, +} + +impl ValidationError { + /// Create a new `ValidationError` + pub(crate) fn new(message: String) -> Self { + Self { message } + } +} diff --git a/catalyst-gateway/bin/src/service/common/responses/mod.rs b/catalyst-gateway/bin/src/service/common/responses/mod.rs index 02680991ae..fce647e085 100644 --- a/catalyst-gateway/bin/src/service/common/responses/mod.rs +++ b/catalyst-gateway/bin/src/service/common/responses/mod.rs @@ -1,6 +1,141 @@ //! Generic Responses are all contained in their own modules, grouped by response codes. -#[macro_use] -pub(crate) mod resp_2xx; -pub(crate) mod resp_4xx; -pub(crate) mod resp_5xx; +use std::{ + collections::HashSet, + hash::{Hash, Hasher}, +}; + +use poem::IntoResponse; +use poem_openapi::{ + payload::Json, + registry::{MetaResponse, MetaResponses, Registry}, + ApiResponse, +}; + +use super::objects::{server_error::ServerError, validation_error::ValidationError}; +use crate::service::utilities::NetworkValidationError; + +/// Default error responses +#[derive(ApiResponse)] +pub(crate) enum ErrorResponses { + /// ## Content validation error. + /// + /// This error means that the request was malformed. + /// It has failed to pass validation, as specified by the `OpenAPI` schema. + #[oai(status = 400)] + BadRequest(Json), + /// ## Internal Server Error. + /// + /// An internal server error occurred. + /// + /// *The contents of this response should be reported to the projects issue tracker.* + #[oai(status = 500)] + ServerError(Json), + /// ## Service Unavailable + /// + /// The service is not available, do not send other requests. + /// + /// *This is returned when the service either has not started, + /// or has become unavailable.* + #[oai(status = 503)] + ServiceUnavailable, +} + +/// Combine provided responses type with the default responses under one type. +pub(crate) enum WithErrorResponses { + /// Provided responses + With(T), + /// Error responses + Error(ErrorResponses), +} + +impl WithErrorResponses { + /// Handle a 5xx or 4xx response. + /// Returns a Server Error, a Bad Request or a Service Unavailable response. + pub(crate) fn handle_error(err: &anyhow::Error) -> Self { + match err { + err if err.is::() => { + WithErrorResponses::Error(ErrorResponses::BadRequest(Json(ValidationError::new( + err.to_string(), + )))) + }, + err if err.is::() => { + WithErrorResponses::Error(ErrorResponses::ServiceUnavailable) + }, + err => { + let error = crate::service::common::objects::server_error::ServerError::new(None); + let id = error.id(); + tracing::error!(id = format!("{id}"), "{}", err); + WithErrorResponses::Error(ErrorResponses::ServerError(Json(error))) + }, + } + } +} + +impl From for WithErrorResponses { + fn from(val: T) -> Self { + Self::With(val) + } +} + +impl ApiResponse for WithErrorResponses { + const BAD_REQUEST_HANDLER: bool = true; + + fn meta() -> MetaResponses { + let t_meta = T::meta(); + let default_meta = ErrorResponses::meta(); + + let mut responses = HashSet::new(); + responses.extend( + t_meta + .responses + .into_iter() + .map(FilteredByStatusCodeResponse), + ); + responses.extend( + default_meta + .responses + .into_iter() + .map(FilteredByStatusCodeResponse), + ); + + let responses = responses.into_iter().map(|val| val.0).collect(); + MetaResponses { responses } + } + + fn register(registry: &mut Registry) { + ErrorResponses::register(registry); + T::register(registry); + } + + fn from_parse_request_error(err: poem::Error) -> Self { + Self::Error(ErrorResponses::BadRequest(Json(ValidationError::new( + err.to_string(), + )))) + } +} + +impl IntoResponse for WithErrorResponses { + fn into_response(self) -> poem::Response { + match self { + Self::With(t) => t.into_response(), + Self::Error(default) => default.into_response(), + } + } +} + +/// `FilteredByStatusCodeResponse` is used to filter out duplicate responses by status +/// code. +struct FilteredByStatusCodeResponse(MetaResponse); + +impl PartialEq for FilteredByStatusCodeResponse { + fn eq(&self, other: &Self) -> bool { + self.0.status.eq(&other.0.status) + } +} +impl Eq for FilteredByStatusCodeResponse {} +impl Hash for FilteredByStatusCodeResponse { + fn hash(&self, state: &mut H) { + self.0.status.hash(state); + } +} diff --git a/catalyst-gateway/bin/src/service/common/responses/resp_2xx.rs b/catalyst-gateway/bin/src/service/common/responses/resp_2xx.rs deleted file mode 100644 index 7c538b0af3..0000000000 --- a/catalyst-gateway/bin/src/service/common/responses/resp_2xx.rs +++ /dev/null @@ -1,19 +0,0 @@ -//! This module contains common and re-usable responses with a 2xx response code. - -use poem::IntoResponse; -use poem_extensions::OneResponse; -use poem_openapi::payload::Payload; - -#[derive(OneResponse)] -#[oai(status = 200)] -/// ## OK, success status response code indicates that the request has succeeded -pub(crate) struct OK(pub(crate) T); - -#[derive(OneResponse)] -#[oai(status = 204)] -/// ## NO CONTENT -/// -/// The operation completed successfully, but there is no data to return. -/// -/// #### NO DATA BODY IS RETURNED FOR THIS RESPONSE -pub(crate) struct NoContent; diff --git a/catalyst-gateway/bin/src/service/common/responses/resp_4xx.rs b/catalyst-gateway/bin/src/service/common/responses/resp_4xx.rs deleted file mode 100644 index c2317d79c3..0000000000 --- a/catalyst-gateway/bin/src/service/common/responses/resp_4xx.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! This module contains common and re-usable responses with a 4xx response code. - -use poem::IntoResponse; -use poem_extensions::OneResponse; -use poem_openapi::payload::{Payload, PlainText}; - -#[derive(OneResponse)] -#[oai(status = 400)] -/// ## Bad Request -pub(crate) struct BadRequest(T); - -#[derive(OneResponse)] -#[oai(status = 400)] -/// This error means that the request was malformed. -/// It has failed to pass validation, as specified by the `OpenAPI` schema. -pub(crate) struct ApiValidationError(PlainText); - -impl ApiValidationError { - /// Create new `ApiValidationError` - pub(crate) fn new(error: String) -> Self { - Self(PlainText(error)) - } -} - -#[derive(OneResponse)] -#[oai(status = 401)] -/// ## Unauthorized -pub(crate) struct Unauthorized; - -#[derive(OneResponse)] -#[oai(status = 403)] -/// ## Forbidden -pub(crate) struct Forbidden; - -#[derive(OneResponse)] -#[oai(status = 404)] -/// ## Content not found -pub(crate) struct NotFound; - -#[derive(OneResponse)] -#[oai(status = 405)] -/// ## Method not allowed -pub(crate) struct MethodNotAllowed; - -#[derive(OneResponse)] -#[oai(status = 406)] -/// ## Not acceptable -pub(crate) struct NotAcceptable; - -#[derive(OneResponse)] -#[oai(status = 422)] -/// Common automatically produced validation error for every endpoint. -/// Is generated automatically when any of the `OpenAPI` validation rules fail. -/// Can also be generated manually. -pub(crate) struct ValidationError; diff --git a/catalyst-gateway/bin/src/service/common/responses/resp_5xx.rs b/catalyst-gateway/bin/src/service/common/responses/resp_5xx.rs deleted file mode 100644 index 29d1310c0f..0000000000 --- a/catalyst-gateway/bin/src/service/common/responses/resp_5xx.rs +++ /dev/null @@ -1,111 +0,0 @@ -//! This module contains common and re-usable responses with a 4xx response code. -use poem::{error::ResponseError, http::StatusCode}; -use poem_extensions::OneResponse; -use poem_openapi::{payload::Json, types::Example, Object}; -use url::Url; -use uuid::Uuid; - -/// While using macro-vis lib, you will get the `uncommon_codepoints` warning, so you will -/// probably want to place this in your crate root -use crate::settings::generate_github_issue_url; - -/// Handle a 5xx response. -/// Returns a Server Error or a Service Unavailable response. -/// Logging error message. -/// Argument must be `anyhow::Error` type. -macro_rules! handle_5xx_response { - ($err:ident) => {{ - if $err.is::>() { - poem_extensions::UniResponse::T503(ServiceUnavailable) - } else { - let error = crate::service::common::responses::resp_5xx::ServerError::new(None); - let id = error.id(); - tracing::error!(id = format!("{id}"), "{}", $err); - poem_extensions::UniResponse::T500(error) - } - }}; -} -pub(crate) use handle_5xx_response; - -#[derive(Debug, Object)] -#[oai(example, skip_serializing_if_is_none)] -/// Response payload to a Bad request. -struct ServerErrorPayload { - /// Unique ID of this Server Error so that it can be located easily for debugging. - id: Uuid, - /// *Optional* SHORT Error message. - /// Will not contain sensitive information, internal details or backtraces. - // TODO(bkioshn): https://github.com/input-output-hk/catalyst-voices/issues/239 - #[oai(validator(max_length = "100", pattern = "^[0-9a-zA-Z].*$"))] - msg: Option, - /// A URL to report an issue. - // TODO(bkioshn): https://github.com/input-output-hk/catalyst-voices/issues/239 - #[oai(validator(max_length = "1000"))] - issue: Option, -} - -impl ServerErrorPayload { - /// Create a new Server Error Response Payload. - pub(crate) fn new(msg: Option) -> Self { - let id = Uuid::new_v4(); - let issue_title = format!("Internal Server Error - {id}"); - let issue = generate_github_issue_url(&issue_title); - - Self { id, msg, issue } - } -} - -impl Example for ServerErrorPayload { - /// Example for the Server Error Payload. - fn example() -> Self { - Self::new(Some("Server Error".to_string())) - } -} - -#[derive(OneResponse)] -#[oai(status = 500)] -/// ## Internal Server Error -/// -/// An internal server error occurred. -/// -/// *The contents of this response should be reported to the projects issue tracker.* -pub(crate) struct ServerError(Json); - -impl ServerError { - /// Create a new Server Error Response. - pub(crate) fn new(msg: Option) -> Self { - let msg = msg.unwrap_or( - "Internal Server Error. Please report the issue to the service owner.".to_string(), - ); - Self(Json(ServerErrorPayload::new(Some(msg)))) - } - - /// Get the id of this Server Error. - pub(crate) fn id(&self) -> Uuid { - self.0.id - } -} - -impl ResponseError for ServerError { - fn status(&self) -> StatusCode { - StatusCode::INTERNAL_SERVER_ERROR - } -} - -#[derive(OneResponse, Debug)] -#[oai(status = 503)] -/// ## Service Unavailable -/// -/// The service is not available. -/// -/// *This is returned when the service either has not started, -/// or has become unavailable.* -/// -/// #### NO DATA BODY IS RETURNED FOR THIS RESPONSE -pub(crate) struct ServiceUnavailable; - -impl ResponseError for ServiceUnavailable { - fn status(&self) -> StatusCode { - StatusCode::SERVICE_UNAVAILABLE - } -} diff --git a/catalyst-gateway/bin/src/service/common/tags.rs b/catalyst-gateway/bin/src/service/common/tags.rs index e8fee66635..7b9fbb3ee2 100644 --- a/catalyst-gateway/bin/src/service/common/tags.rs +++ b/catalyst-gateway/bin/src/service/common/tags.rs @@ -13,10 +13,6 @@ pub(crate) enum ApiTags { /// Information relating to Voter Registration, Delegations and Calculated Voting /// Power. Registration, - /// Test Endpoints (Not part of the API) - Test, - /// Test Endpoints (Not part of the API) - TestTag2, /// API Version 0 Endpoints V0, /// API Version 1 Endpoints diff --git a/catalyst-gateway/bin/src/service/docs/mod.rs b/catalyst-gateway/bin/src/service/docs/mod.rs index 575bb26197..c3c521bb20 100644 --- a/catalyst-gateway/bin/src/service/docs/mod.rs +++ b/catalyst-gateway/bin/src/service/docs/mod.rs @@ -1,4 +1,6 @@ //! Stoplight Elements `OpenAPI` UI +#![allow(clippy::indexing_slicing)] // TODO: remove this when https://github.com/pyrossh/rust-embed/issues/243 is resolved positively + mod stoplight_elements; use poem::{endpoint::EmbeddedFileEndpoint, get, Route}; use poem_openapi::{OpenApi, OpenApiService, Webhook}; diff --git a/catalyst-gateway/bin/src/service/mod.rs b/catalyst-gateway/bin/src/service/mod.rs index 85d172a603..30aa724ffc 100644 --- a/catalyst-gateway/bin/src/service/mod.rs +++ b/catalyst-gateway/bin/src/service/mod.rs @@ -6,12 +6,12 @@ use crate::{settings::DocsSettings, state::State}; // These Modules contain endpoints mod api; mod docs; - // These modules are utility or common types/functions mod common; mod poem_service; mod utilities; +pub(crate) use api::started; pub(crate) use poem_service::get_app_docs; /// # Run Catalyst Gateway Service. diff --git a/catalyst-gateway/bin/src/service/utilities/catch_panic.rs b/catalyst-gateway/bin/src/service/utilities/catch_panic.rs index 06001c7522..08f32fc9e8 100644 --- a/catalyst-gateway/bin/src/service/utilities/catch_panic.rs +++ b/catalyst-gateway/bin/src/service/utilities/catch_panic.rs @@ -1,13 +1,13 @@ //! Handle catching panics created by endpoints, logging them and properly responding. use std::{any::Any, backtrace::Backtrace, cell::RefCell}; -// use tracing::Level; use chrono::prelude::*; use panic_message::panic_message; -use poem::middleware::PanicHandler; +use poem::{http::StatusCode, middleware::PanicHandler, IntoResponse}; +use poem_openapi::payload::Json; use serde_json::json; -use crate::service::common::responses::resp_5xx::ServerError; +use crate::service::common::objects::server_error::ServerError; /// Customized Panic handler. /// Catches all panics, and turns them into 500. @@ -44,15 +44,15 @@ pub(crate) fn set_panic_hook() { } impl PanicHandler for ServicePanicHandler { - type Response = ServerError; + type Response = poem::Response; /// Handle a panic. /// Log the panic and respond with a 500 with appropriate data. - fn get_response(&self, err: Box) -> ServerError { - let response = ServerError::new(None); + fn get_response(&self, err: Box) -> Self::Response { + let server_err = ServerError::new(None); // Get the unique identifier for this panic, so we can find it in the logs. - let panic_identifier = response.id().to_string(); + let panic_identifier = server_err.id().to_string(); // Get the message from the panic as best we can. let err_msg = panic_message(&err); @@ -85,6 +85,8 @@ impl PanicHandler for ServicePanicHandler { println!("{json_log}"); - response + let mut resp = Json(server_err).into_response(); + resp.set_status(StatusCode::INTERNAL_SERVER_ERROR); + resp } } diff --git a/catalyst-gateway/bin/src/service/utilities/middleware/schema_validation.rs b/catalyst-gateway/bin/src/service/utilities/middleware/schema_validation.rs index c889dd9f6a..8279731ef1 100644 --- a/catalyst-gateway/bin/src/service/utilities/middleware/schema_validation.rs +++ b/catalyst-gateway/bin/src/service/utilities/middleware/schema_validation.rs @@ -9,9 +9,9 @@ use std::sync::Arc; -use poem::{web::Data, Endpoint, EndpointExt, Middleware, Request, Result}; +use poem::{http::StatusCode, web::Data, Endpoint, EndpointExt, Middleware, Request, Result}; -use crate::{service::common::responses::resp_5xx::ServiceUnavailable, state::State}; +use crate::state::State; /// A middleware that raises an error with `ServiceUnavailable` and 503 status code /// if a DB schema version mismatch is found the existing `State`. @@ -31,18 +31,15 @@ pub(crate) struct SchemaVersionValidationImpl { ep: E, } -#[poem::async_trait] impl Endpoint for SchemaVersionValidationImpl { type Output = E::Output; async fn call(&self, req: Request) -> Result { if let Some(state) = req.data::>>() { // Check if the inner schema version status is set to `Mismatch`, - // if so, return the `ServiceUnavailable` error, which implements - // `ResponseError`, with status code `503`. - // Otherwise, return the endpoint as usual. + // if so, return the `StatusCode::SERVICE_UNAVAILABLE` code. if state.event_db().schema_version_check().await.is_err() { - return Err(ServiceUnavailable.into()); + return Err(StatusCode::SERVICE_UNAVAILABLE.into()); } } // Calls the endpoint with the request, and returns the response. diff --git a/catalyst-gateway/bin/src/service/utilities/middleware/tracing_mw.rs b/catalyst-gateway/bin/src/service/utilities/middleware/tracing_mw.rs index 1015e77586..b31d140ddd 100644 --- a/catalyst-gateway/bin/src/service/utilities/middleware/tracing_mw.rs +++ b/catalyst-gateway/bin/src/service/utilities/middleware/tracing_mw.rs @@ -294,7 +294,6 @@ async fn mk_request_span(req: &Request) -> (Span, String, String, String) { (span, uri_path, method, client_id) } -#[poem::async_trait] impl Endpoint for TracingEndpoint { type Output = Response; diff --git a/catalyst-gateway/bin/src/service/utilities/mod.rs b/catalyst-gateway/bin/src/service/utilities/mod.rs index bc06324bfd..7765b0064b 100644 --- a/catalyst-gateway/bin/src/service/utilities/mod.rs +++ b/catalyst-gateway/bin/src/service/utilities/mod.rs @@ -5,26 +5,37 @@ pub(crate) mod middleware; use pallas::ledger::addresses::Network as PallasNetwork; use poem_openapi::types::ToJSON; -use crate::service::common::{ - objects::cardano::network::Network, responses::resp_4xx::ApiValidationError, -}; +use crate::service::common::objects::cardano::network::Network; /// Convert bytes to hex string with the `0x` prefix pub(crate) fn to_hex_with_prefix(bytes: &[u8]) -> String { format!("0x{}", hex::encode(bytes)) } +/// Network validation error +#[derive(thiserror::Error, Debug)] +pub(crate) enum NetworkValidationError { + /// Provided network type does not match stake address + #[error("Provided network type {0} does not match stake address network type {1}")] + NetworkMismatch(String, String), + /// Unknown address network type + #[error("Unknown address network type {0}")] + UnknownNetwork(u8), +} + /// Check the provided network type with the encoded inside the stake address pub(crate) fn check_network( address_network: PallasNetwork, provided_network: Option, -) -> Result { +) -> anyhow::Result { match address_network { PallasNetwork::Mainnet => { if let Some(network) = provided_network { if !matches!(&network, Network::Mainnet) { - return Err(ApiValidationError::new(format!( - "Provided network type {} does not match stake address network type Mainnet", network.to_json_string() - ))); + return Err(NetworkValidationError::NetworkMismatch( + network.to_json_string(), + "Mainnet".to_string(), + ) + .into()); } } Ok(Network::Mainnet) @@ -39,17 +50,17 @@ pub(crate) fn check_network( network, Network::Testnet | Network::Preprod | Network::Preview ) { - return Err(ApiValidationError::new(format!( - "Provided network type {} does not match stake address network type Testnet", network.to_json_string() - ))); + return Err(NetworkValidationError::NetworkMismatch( + network.to_json_string(), + "Testnet".to_string(), + ) + .into()); } Ok(network) } else { Ok(Network::Testnet) } }, - PallasNetwork::Other(x) => { - Err(ApiValidationError::new(format!("Unknown network type {x}"))) - }, + PallasNetwork::Other(x) => Err(NetworkValidationError::UnknownNetwork(x).into()), } } diff --git a/catalyst-gateway/deny.toml b/catalyst-gateway/deny.toml index 608eb845c8..adb9434268 100644 --- a/catalyst-gateway/deny.toml +++ b/catalyst-gateway/deny.toml @@ -1,108 +1,66 @@ -# This template contains all of the possible sections and their default values +# cspell: words msvc, wasip, RUSTSEC, rustls, libssh, reqwest, tinyvec, Leay, webpki -# cspell: words rustc RUSTSEC dotgraphs reqwest rustls pemfile webpki - -# Note that all fields that take a lint level have these possible values: -# * deny - An error will be produced and the check will fail -# * warn - A warning will be produced, but the check will not fail -# * allow - No warning or error will be produced, though in some cases a note -# will be - -# The values provided in this template are the default values that will be used -# when any section or field is not specified in your own configuration - -# Root options - -# If 1 or more target triples (and optionally, target_features) are specified, -# only the specified targets will be checked when running `cargo deny check`. -# This means, if a particular package is only ever used as a target specific -# dependency, such as, for example, the `nix` crate only being used via the -# `target_family = "unix"` configuration, that only having windows targets in -# this list would mean the nix crate, as well as any of its exclusive -# dependencies not shared by any other crates, would be ignored, as the target -# list here is effectively saying which targets you are building for. +[graph] +# cargo-deny is really only ever intended to run on the "normal" tier-1 targets targets = [ - # The triple can be any string, but only the target triples built in to - # rustc (as of 1.40) can be checked against actual config expressions - #{ triple = "x86_64-unknown-linux-musl" }, - # You can also specify which target_features you promise are enabled for a - # particular target. target_features are currently not validated against - # the actual valid features supported by the target architecture. - #{ triple = "wasm32-unknown-unknown", features = ["atomics"] }, + "x86_64-unknown-linux-gnu", + "aarch64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", + "aarch64-apple-darwin", + "x86_64-apple-darwin", + "x86_64-pc-windows-msvc", + "wasm32-unknown-unknown", + "wasm32-wasip1", + "wasm32-wasip2", ] -# When creating the dependency graph used as the source of truth when checks are -# executed, this field can be used to prune crates from the graph, removing them -# from the view of cargo-deny. This is an extremely heavy hammer, as if a crate -# is pruned from the graph, all of its dependencies will also be pruned unless -# they are connected to another crate in the graph that hasn't been pruned, -# so it should be used with care. The identifiers are [Package ID Specifications] -# (https://doc.rust-lang.org/cargo/reference/pkgid-spec.html) -#exclude = [] -# If true, metadata will be collected with `--all-features`. Note that this can't -# be toggled off if true, if you want to conditionally enable `--all-features` it -# is recommended to pass `--all-features` on the cmd line instead -all-features = false -# If true, metadata will be collected with `--no-default-features`. The same -# caveat with `all-features` applies -no-default-features = false -# If set, these feature will be enabled when collecting metadata. If `--features` -# is specified on the cmd line they will take precedence over this option. -#features = [] -# When outputting inclusion graphs in diagnostics that include features, this -# option can be used to specify the depth at which feature edges will be added. -# This option is included since the graphs can be quite large and the addition -# of features from the crate(s) to all of the graph roots can be far too verbose. -# This option can be overridden via `--feature-depth` on the cmd line -feature-depth = 1 +all-features = true -# This section is considered when running `cargo deny check advisories` -# More documentation for the advisories section can be found here: -# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html [advisories] -# The path where the advisory database is cloned/fetched into -db-path = "~/.cargo/advisory-db" -# The url(s) of the advisory databases to use -db-urls = ["https://github.com/rustsec/advisory-db"] -# The lint level for security vulnerabilities -vulnerability = "deny" -# The lint level for unmaintained crates -unmaintained = "warn" -# The lint level for crates that have been yanked from their source registry -yanked = "warn" -# The lint level for crates with security notices. -notice = "warn" -# A list of advisory IDs to ignore. Note that ignored advisories will still -# output a note when they are encountered. +version = 2 ignore = [ - #"RUSTSEC-0000-0000", + { id = "RUSTSEC-2020-0168", reason = "`mach` is used by wasmtime and we have no control over that." }, + { id = "RUSTSEC-2021-0145", reason = "we don't target windows, and don;t use a custom global allocator." }, ] -# Threshold for security vulnerabilities, any vulnerability with a CVSS score -# lower than the range specified will be ignored. Note that ignored advisories -# will still output a note when they are encountered. -# * None - CVSS Score 0.0 -# * Low - CVSS Score 0.1 - 3.9 -# * Medium - CVSS Score 4.0 - 6.9 -# * High - CVSS Score 7.0 - 8.9 -# * Critical - CVSS Score 9.0 - 10.0 -#severity-threshold = -# If this is true, then cargo deny will use the git executable to fetch advisory database. -# If this is false, then it uses a built-in git library. -# Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support. -# See Git Authentication for more information about setting up git authentication. -#git-fetch-with-cli = true +[bans] +multiple-versions = "warn" +wildcards = 'deny' +deny = [ + # { crate = "git2", use-instead = "gix" }, + { crate = "openssl", use-instead = "rustls" }, + { crate = "openssl-sys", use-instead = "rustls" }, + "libssh2-sys", + # { crate = "cmake", use-instead = "cc" }, + { crate = "windows", reason = "bloated and unnecessary", use-instead = "ideally inline bindings, practically, windows-sys" }, +] +skip = [ + # { crate = "bitflags@1.3.2", reason = "https://github.com/seanmonstar/reqwest/pull/2130 should be in the next version" }, + # { crate = "winnow@0.5.40", reason = "gix 0.59 was yanked, see https://github.com/Byron/gitoxide/issues/1309" }, + # { crate = "heck@0.4.1", reason = "strum_macros uses this old version" }, + # { crate = "base64@0.21.7", reason = "gix-transport pulls in this old version, as well as a newer version via reqwest" }, + # { crate = "byte-array-literalsase64@0.21.7", reason = "gix-transport pulls in this old version, as well as a newer version via reqwest" }, +] +skip-tree = [ + { crate = "windows-sys@0.48.0", reason = "a foundational crate for many that bumps far too frequently to ever have a shared version" }, +] + +[sources] +unknown-registry = "deny" +unknown-git = "deny" + +# List of URLs for allowed Git repositories +allow-git = [ + "https://github.com/input-output-hk/hermes.git", + "https://github.com/input-output-hk/catalyst-pallas.git", + "https://github.com/bytecodealliance/wasmtime" +] -# This section is considered when running `cargo deny check licenses` -# More documentation for the licenses section can be found here: -# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html [licenses] -# The lint level for crates which do not have a detectable license -unlicensed = "deny" +version = 2 # Don't warn if a listed license isn't found unused-allowed-license="allow" -# List of explicitly allowed licenses -# See https://spdx.org/licenses/ for list of possible licenses -# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. +# We want really high confidence when inferring licenses from text +confidence-threshold = 0.93 allow = [ "MIT", "Apache-2.0", @@ -113,171 +71,34 @@ allow = [ "Apache-2.0 WITH LLVM-exception", "CC0-1.0" ] -# List of explicitly disallowed licenses -# See https://spdx.org/licenses/ for list of possible licenses -# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. -deny = [ - #"Nokia", -] -# Lint level for licenses considered copyleft -copyleft = "deny" - -# Blanket approval or denial for OSI-approved or FSF Free/Libre licenses -# * both - The license will be approved if it is both OSI-approved *AND* FSF -# * either - The license will be approved if it is either OSI-approved *OR* FSF -# * osi - The license will be approved if it is OSI approved -# * fsf - The license will be approved if it is FSF Free -# * osi-only - The license will be approved if it is OSI-approved *AND NOT* FSF -# * fsf-only - The license will be approved if it is FSF *AND NOT* OSI-approved -# * neither - This predicate is ignored and the default lint level is used -allow-osi-fsf-free = "neither" -# Lint level used when no other predicates are matched -# 1. License isn't in the allow or deny lists -# 2. License isn't copyleft -# 3. License isn't OSI/FSF, or allow-osi-fsf-free = "neither" -default = "deny" -# The confidence threshold for detecting a license from license text. -# The higher the value, the more closely the license text must be to the -# canonical license text of a valid SPDX license file. -# [possible values: any between 0.0 and 1.0]. -confidence-threshold = 0.8 -# Allow 1 or more licenses on a per-crate basis, so that particular licenses -# aren't accepted for every possible crate as with the normal allow list exceptions = [ - # Each entry is the crate and version constraint, and its specific allow - # list - #{ allow = ["Zlib"], name = "adler32", version = "*" }, + #{ allow = ["Zlib"], crate = "tinyvec" }, + #{ allow = ["Unicode-DFS-2016"], crate = "unicode-ident" }, + #{ allow = ["OpenSSL"], crate = "ring" }, ] -# Some crates don't have (easily) machine readable licensing information, -# adding a clarification entry for it allows you to manually specify the -# licensing information -#[[licenses.clarify]] -# The name of the crate the clarification applies to -#name = "ring" -# The optional version constraint for the crate -#version = "*" -# The SPDX expression for the license requirements of the crate -#expression = "MIT AND ISC AND OpenSSL" -# One or more files in the crate's source used as the "source of truth" for -# the license expression. If the contents match, the clarification will be used -# when running the license check, otherwise the clarification will be ignored -# and the crate will be checked normally, which may produce warnings or errors -# depending on the rest of your configuration -#license-files = [ - # Each entry is a crate relative path, and the (opaque) hash of its contents - #{ path = "LICENSE", hash = 0xbd0eed23 } -#] +[[licenses.clarify]] +crate = "byte-array-literals" +expression = "Apache-2.0 WITH LLVM-exception" +license-files = [{ path = "../../../LICENSE", hash = 0x001c7e6c }] + +# SPDX considers OpenSSL to encompass both the OpenSSL and SSLeay licenses +# https://spdx.org/licenses/OpenSSL.html +# ISC - Both BoringSSL and ring use this for their new files +# MIT - "Files in third_party/ have their own licenses, as described therein. The MIT +# license, for third_party/fiat, which, unlike other third_party directories, is +# compiled into non-test libraries, is included below." +# OpenSSL - Obviously +#expression = "ISC AND MIT AND OpenSSL" +#license-files = [{ path = "LICENSE", hash = 0xbd0eed23 }] -[licenses.private] -# If true, ignores workspace crates that aren't published, or are only -# published to private registries. -# To see how to mark a crate as unpublished (to the official registry), -# visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field. -ignore = false -# One or more private registries that you might publish crates to, if a crate -# is only published to private registries, and ignore is true, the crate will -# not have its license(s) checked -registries = [ - #"https://sekretz.com/registry -] - -# This section is considered when running `cargo deny check bans`. -# More documentation about the 'bans' section can be found here: -# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html -[bans] -# Lint level for when multiple versions of the same crate are detected -multiple-versions = "warn" -# Lint level for when a crate version requirement is `*` -wildcards = "deny" -# The graph highlighting used when creating dotgraphs for crates -# with multiple versions -# * lowest-version - The path to the lowest versioned duplicate is highlighted -# * simplest-path - The path to the version with the fewest edges is highlighted -# * all - Both lowest-version and simplest-path are used -highlight = "all" -# The default lint level for `default` features for crates that are members of -# the workspace that is being checked. This can be overridden by allowing/denying -# `default` on a crate-by-crate basis if desired. -workspace-default-features = "allow" -# The default lint level for `default` features for external crates that are not -# members of the workspace. This can be overridden by allowing/denying `default` -# on a crate-by-crate basis if desired. -external-default-features = "allow" -# List of crates that are allowed. Use with care! -allow = [ - #{ name = "ansi_term", version = "=0.11.0" }, -] -# List of crates to deny -deny = [ - # Each entry the name of a crate and a version range. If version is - # not specified, all versions will be matched. - #{ name = "ansi_term", version = "=0.11.0" }, - # - # Wrapper crates can optionally be specified to allow the crate when it - # is a direct dependency of the otherwise banned crate - #{ name = "ansi_term", version = "=0.11.0", wrappers = [] }, - { name = "openssl" }, -] - -# List of features to allow/deny -# Each entry the name of a crate and a version range. If version is -# not specified, all versions will be matched. -#[[bans.features]] -#name = "reqwest" -# Features to not allow -#deny = ["json"] -# Features to allow -#allow = [ -# "rustls", -# "__rustls", -# "__tls", -# "hyper-rustls", -# "rustls", -# "rustls-pemfile", -# "rustls-tls-webpki-roots", -# "tokio-rustls", -# "webpki-roots", -#] -# If true, the allowed features must exactly match the enabled feature set. If -# this is set there is no point setting `deny` -#exact = true - -# Certain crates/versions that will be skipped when doing duplicate detection. -skip = [ - #{ name = "ansi_term", version = "=0.11.0" }, -] -# Similarly to `skip` allows you to skip certain crates during duplicate -# detection. Unlike skip, it also includes the entire tree of transitive -# dependencies starting at the specified crate, up to a certain depth, which is -# by default infinite. -skip-tree = [ - #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, -] - -# This section is considered when running `cargo deny check sources`. -# More documentation about the 'sources' section can be found here: -# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html -[sources] -# Lint level for what to happen when a crate from a crate registry that is not -# in the allow list is encountered -unknown-registry = "deny" -# Lint level for what to happen when a crate from a git repository that is not -# in the allow list is encountered -unknown-git = "deny" -# List of URLs for allowed crate registries. Defaults to the crates.io index -# if not specified. If it is specified but empty, no registries are allowed. -allow-registry = ["https://github.com/rust-lang/crates.io-index"] -# List of URLs for allowed Git repositories -allow-git = [ - "https://github.com/input-output-hk/hermes.git", - "https://github.com/input-output-hk/catalyst-pallas.git" -] +#[[licenses.clarify]] +#crate = "webpki" +#expression = "ISC" +#license-files = [{ path = "LICENSE", hash = 0x001c7e6c }] -[sources.allow-org] -# 1 or more github.com organizations to allow git sources for -#github = [""] -# 1 or more gitlab.com organizations to allow git sources for -#gitlab = [""] -# 1 or more bitbucket.org organizations to allow git sources for -#bitbucket = [""] +# Actually "ISC-style" +#[[licenses.clarify]] +#crate = "rustls-webpki" +#expression = "ISC" +#license-files = [{ path = "LICENSE", hash = 0x001c7e6c }] diff --git a/catalyst-gateway/event-db/Earthfile b/catalyst-gateway/event-db/Earthfile index 86841cd516..c3b57a36d8 100644 --- a/catalyst-gateway/event-db/Earthfile +++ b/catalyst-gateway/event-db/Earthfile @@ -1,15 +1,16 @@ # This is a Dockerfile for building a container image for the Catalyst Event Database. # The container image is built from scratch and includes the necessary files for running # the database and its associated software. +VERSION 0.8 -VERSION 0.7 +IMPORT github.com/input-output-hk/catalyst-ci/earthly/postgresql:v3.00.0 AS postgresql-ci # cspell: words # Internal: builder is our Event db builder target. Prepares all necessary artifacts. # CI target : dependency builder: - DO github.com/input-output-hk/catalyst-ci/earthly/postgresql:v2.11.1+BUILDER + DO postgresql-ci+BUILDER # override setup-db.sql COPY setup-db.sql /sql/ @@ -21,8 +22,8 @@ builder: build: FROM +builder - DO github.com/input-output-hk/catalyst-ci/earthly/postgresql:v2.11.1+BUILD --image_name=event-db - DO github.com/input-output-hk/catalyst-ci/earthly/postgresql:v2.11.1+DOCS --image_name=event-db + DO postgresql-ci+BUILD --image_name=event-db + DO postgresql-ci+DOCS --image_name=event-db # test the event db database schema # CI target : true diff --git a/catalyst-gateway/tests/Earthfile b/catalyst-gateway/tests/Earthfile index 7cc6478835..2713223062 100644 --- a/catalyst-gateway/tests/Earthfile +++ b/catalyst-gateway/tests/Earthfile @@ -1,34 +1,39 @@ -VERSION 0.7 +VERSION 0.8 package-schemathesis: FROM python:3.12-alpine3.19 ARG tag="latest" ARG max_examples=1000 - ARG max_response_time=300 + # TODO: https://github.com/input-output-hk/catalyst-voices/issues/465 + ARG max_response_time=1000 ARG wait_for_schema=15 ARG workers=2 ARG schema_version=30 ARG openapi_spec RUN apk add --no-cache gcc musl-dev - RUN python -m pip install schemathesis + RUN python -m pip install schemathesis==3.27.1 RUN mkdir /results VOLUME /results - ENTRYPOINT st run --checks all $openapi_spec --workers=$workers --wait-for-schema=$wait_for_schema \ - --max-response-time=$max_response_time --hypothesis-max-examples=$max_examples \ - --data-generation-method=all --skip-deprecated-operations \ - --force-schema-version=$schema_version --show-trace --force-color \ - --junit-xml /results/junit-report.xml --cassette-path=/results/cassette.yaml \ - # TODO: https://github.com/input-output-hk/catalyst-voices/issues/330 - --exclude-checks content_type_conformance \ - --exclude-checks response_schema_conformance + ENTRYPOINT st run --checks all $openapi_spec \ + --workers=$workers \ + --wait-for-schema=$wait_for_schema \ + --max-response-time=$max_response_time \ + --hypothesis-max-examples=$max_examples \ + --data-generation-method=all \ + --skip-deprecated-operations \ + --force-schema-version=$schema_version \ + --show-trace \ + --force-color \ + --junit-xml=/results/junit-report.xml \ + --cassette-path=/results/cassette.yaml SAVE IMAGE schemathesis:$tag # test-fuzzer-api - Fuzzy test cat-gateway using openapi specs -fuzzer-api: +test-fuzzer-api: FROM earthly/dind:alpine-3.19 RUN apk update && apk add iptables-legacy # workaround for https://github.com/earthly/earthly/issues/3784 RUN apk add yq zstd @@ -44,25 +49,18 @@ fuzzer-api: --service cat-gateway \ --allow-privileged RUN docker run --net=host --name=st schemathesis:latest || echo fail > fail && \ - docker logs cat-gateway > ./cat-gateway.log && zstd -9 cat-gateway.log && \ - docker cp st:/results/junit-report.xml junit-report.xml && \ - docker cp st:/results/cassette.yaml cassette.yaml + docker-compose logs cat-gateway > ./cat-gateway.log && zstd -9 cat-gateway.log && \ + docker cp st:/results/junit-report.xml junit-report.xml && \ + docker cp st:/results/cassette.yaml cassette.yaml END WAIT SAVE ARTIFACT junit-report.xml AS LOCAL schemathesis.junit-report.xml SAVE ARTIFACT cat-gateway.log.zst AS LOCAL cat-gateway.log.zst SAVE ARTIFACT cassette.yaml AS LOCAL cassette.yaml END - IF [ -f fail ] - RUN echo -e "\033[0;31mSchemathesis test run failed. Run the test locally to get Catalyst Gateway logs\n" && \ - echo -e "\033[0;31mFailed tests:" && \ - yq -PC '.http_interactions.[] | select(.status == "FAILURE")' cassette.yaml && \ - exit 1 - END # test-lint-openapi - OpenAPI linting from an artifact # testing whether the OpenAPI generated during build stage follows good practice. -# enable this linting after this issue will be solved test-lint-openapi: FROM github.com/input-output-hk/catalyst-ci/earthly/spectral:v2.4.0+spectral-base # Copy the doc artifact. diff --git a/catalyst-gateway/tests/api_tests/Earthfile b/catalyst-gateway/tests/api_tests/Earthfile index 5c4d985114..d25bfe8c1d 100644 --- a/catalyst-gateway/tests/api_tests/Earthfile +++ b/catalyst-gateway/tests/api_tests/Earthfile @@ -1,12 +1,15 @@ -VERSION --global-cache 0.7 +VERSION 0.8 +IMPORT github.com/input-output-hk/catalyst-ci/earthly/python:v3.00.0 AS python-ci + +# builder : builder: - FROM github.com/input-output-hk/catalyst-ci/earthly/python:v2.11.1+python-base + FROM python-ci+python-base # prepare tests COPY --dir ./api_tests . COPY ./snapshot_tool-56364174.json . - DO github.com/input-output-hk/catalyst-ci/earthly/python:v2.11.1+BUILDER + DO python-ci+BUILDER test: FROM +builder diff --git a/catalyst-gateway/tests/api_tests/api_tests/__init__.py b/catalyst-gateway/tests/api_tests/api_tests/__init__.py index 14d2437930..e15ed46f89 100644 --- a/catalyst-gateway/tests/api_tests/api_tests/__init__.py +++ b/catalyst-gateway/tests/api_tests/api_tests/__init__.py @@ -22,6 +22,7 @@ def cat_gateway_endpoint_url(endpoint: str): def check_is_live(): resp = requests.get(cat_gateway_endpoint_url("api/health/live")) + print(f"resp: {resp}, code: {resp.status_code}") assert resp.status_code == 204 logger.info("cat-gateway service is LIVE.") diff --git a/catalyst-gateway/tests/api_tests/docker-compose.yml b/catalyst-gateway/tests/api_tests/docker-compose.yml index eef91b418e..d029da3f67 100644 --- a/catalyst-gateway/tests/api_tests/docker-compose.yml +++ b/catalyst-gateway/tests/api_tests/docker-compose.yml @@ -34,7 +34,6 @@ services: - DATA_REFRESH_TICK=5 - CHECK_CONFIG_TICK=5 - MACHINE_ID="UID" - hostname: gateway ports: - 3030:3030 depends_on: diff --git a/catalyst-gateway/tests/schemathesis-docker-compose.yml b/catalyst-gateway/tests/schemathesis-docker-compose.yml index fe30738a89..01acbeab55 100644 --- a/catalyst-gateway/tests/schemathesis-docker-compose.yml +++ b/catalyst-gateway/tests/schemathesis-docker-compose.yml @@ -34,8 +34,8 @@ services: - DATA_REFRESH_TICK=5 - CHECK_CONFIG_TICK=5 - MACHINE_ID="UID" - container_name: cat-gateway - network_mode: "host" + ports: + - 3030:3030 depends_on: event-db: condition: service_healthy diff --git a/catalyst_voices/Earthfile b/catalyst_voices/Earthfile index ccf99e46a7..46b4ed0dc1 100644 --- a/catalyst_voices/Earthfile +++ b/catalyst_voices/Earthfile @@ -1,4 +1,6 @@ -VERSION --try --global-cache --arg-scope-and-set 0.7 +VERSION 0.8 + +IMPORT ../catalyst-gateway AS catalyst-gateway # If running this target with a local ssh agent active, set the environment # variable EARTHLY_SSH_AUTH_SOCK='' to make the `+deps` target work. Earthly @@ -8,6 +10,7 @@ VERSION --try --global-cache --arg-scope-and-set 0.7 deps: FROM debian:bookworm-slim ARG TARGETARCH + ARG FLUTTER_VERSION=3.19.5 RUN apt-get update RUN apt-get install -y git curl unzip bzip2 bash jq gpg lcov COPY --dir test_driver/scripts . @@ -17,10 +20,8 @@ deps: WORKDIR /frontend - RUN git clone https://github.com/flutter/flutter.git /usr/local/flutter + RUN git clone --depth 1 --branch $FLUTTER_VERSION https://github.com/flutter/flutter.git /usr/local/flutter ENV PATH="/usr/local/flutter/bin:/usr/local/flutter/bin/cache/dart-sdk/bin:$HOME/.pub-cache/bin:${PATH}" - RUN flutter channel stable - RUN flutter upgrade RUN flutter --version RUN flutter doctor -v RUN flutter config --enable-web @@ -43,7 +44,7 @@ code-generator: FROM +src WORKDIR /frontend/catalyst_voices/packages/catalyst_voices_services - COPY ../catalyst-gateway+build/doc/cat-gateway-api.json openapi/cat-gateway-api.json + COPY catalyst-gateway+build/doc/cat-gateway-api.json openapi/cat-gateway-api.json RUN flutter pub get RUN dart run build_runner build --delete-conflicting-outputs diff --git a/catalyst_voices/lib/pages/coming_soon/description.dart b/catalyst_voices/lib/pages/coming_soon/description.dart index 90214c098b..82fe7ae460 100644 --- a/catalyst_voices/lib/pages/coming_soon/description.dart +++ b/catalyst_voices/lib/pages/coming_soon/description.dart @@ -13,7 +13,7 @@ class ComingSoonDescription extends StatelessWidget { height: 66, child: DefaultTextStyle( style: GoogleFonts.notoSans( - textStyle: const TextStyle(color: VoicesColors.blueText), + textStyle: const TextStyle(color: VoicesColors.lightTextOnPrimary), fontSize: 16, fontWeight: FontWeight.w400, ), diff --git a/catalyst_voices/lib/pages/coming_soon/logo.dart b/catalyst_voices/lib/pages/coming_soon/logo.dart index 0547e27a5a..d3854da508 100644 --- a/catalyst_voices/lib/pages/coming_soon/logo.dart +++ b/catalyst_voices/lib/pages/coming_soon/logo.dart @@ -20,7 +20,7 @@ class ComingSoonLogo extends StatelessWidget { child: Text( l10n.comingSoonSubtitle, style: GoogleFonts.notoSans( - textStyle: const TextStyle(color: VoicesColors.blue), + textStyle: const TextStyle(color: VoicesColors.lightPrimary), fontSize: 19, fontWeight: FontWeight.w500, ), diff --git a/catalyst_voices/lib/pages/coming_soon/title.dart b/catalyst_voices/lib/pages/coming_soon/title.dart index e2230b295c..4f3ad1a614 100644 --- a/catalyst_voices/lib/pages/coming_soon/title.dart +++ b/catalyst_voices/lib/pages/coming_soon/title.dart @@ -18,7 +18,7 @@ class ComingSoonTitle extends StatelessWidget { children: [ DefaultTextStyle( style: GoogleFonts.poppins( - textStyle: const TextStyle(color: VoicesColors.blue), + textStyle: const TextStyle(color: VoicesColors.lightPrimary), fontSize: 53, height: 1.15, fontWeight: FontWeight.w700, @@ -35,7 +35,7 @@ class ComingSoonTitle extends StatelessWidget { ), DefaultTextStyle( style: GoogleFonts.poppins( - textStyle: const TextStyle(color: VoicesColors.blue), + textStyle: const TextStyle(color: VoicesColors.lightPrimary), fontSize: 53, height: 1.15, fontWeight: FontWeight.w700, diff --git a/catalyst_voices/lib/pages/home/home_page.dart b/catalyst_voices/lib/pages/home/home_page.dart index ca1ca53729..ebaec830fc 100644 --- a/catalyst_voices/lib/pages/home/home_page.dart +++ b/catalyst_voices/lib/pages/home/home_page.dart @@ -18,7 +18,7 @@ final class HomePage extends StatelessWidget { Text( context.l10n.homeScreenText, style: const TextStyle( - color: VoicesColors.purpleGradientStart, + color: VoicesColors.lightPrimary, fontFamily: VoicesFonts.sFPro, fontSize: 32, ), diff --git a/catalyst_voices/packages/catalyst_voices_assets/assets/colors/colors.xml b/catalyst_voices/packages/catalyst_voices_assets/assets/colors/colors.xml index 0a9f7a30dd..b5a26c57ce 100644 --- a/catalyst_voices/packages/catalyst_voices_assets/assets/colors/colors.xml +++ b/catalyst_voices/packages/catalyst_voices_assets/assets/colors/colors.xml @@ -1,14 +1,97 @@ - #FFFFFF - #000000 - #512DA8 - #673AB7 - #512DA8 - #222126 - #7CAE7A - #B02E0C - #565656 - #1235C7 - #506288 + #212A3D + #506288 + #FFFFFF + #61212A3D + #123CD3 + #FFFFFF + #A1B4F7 + #081B5E + #C014EB + #FFFFFF + #E6A1F7 + #4D085E + #D9DEE8 + #61BFC8D9 + #CC0000 + #FFFFFF + #FFD1D1 + #700000 + #218230 + #FFFFFF + #CEF3D4 + #13491B + #E76309 + #FFFFFF + #FDE1CE + #582603 + #14212A3D + #1F212A3D + #29212A3D + #A1B4F7 + #14123CD3 + #1F123CD3 + #29123CD3 + #14C014EB + #1FC014EB + #29C014EB + #14CC0000 + #1FCC0000 + #29CC0000 + #212A3D + #FFFFFF + #61212A3D + #123CD3 + #C014EB + #218230 + #E76309 + #CC0000 + #FFFFFF + #E6E9F0 + #0C288D + #61D9DEE8 + #728EF3 + #0C288D + #1035BC + #E8ECFD + #DF8AF5 + #26042F + #9910BC + #9910BC + #7F90B3 + #364463 + #FF9999 + #380000 + #AD0000 + #FFD1D1 + #BAEDC2 + #08210C + #1D722A + #CEF3D4 + #FBC9A7 + #2C1302 + #B64E07 + #FDE1CE + #1FBFC8D9 + #1FBFC8D9 + #29212A3D + #0C288D + #1F123CD3 + #1F123CD3 + #29123CD3 + #1FD972F3 + #1FC014EB + #29C014EB + #1FFFC2C2 + #1FCC0000 + #29CC0000 + #F2F4F8 + #212A3D + #61BFC8D9 + #728EF3 + #DF8AF5 + #85E093 + #FAB484 + #FF9999 diff --git a/catalyst_voices/packages/catalyst_voices_assets/example/lib/src/main.dart b/catalyst_voices/packages/catalyst_voices_assets/example/lib/src/main.dart index d2f8dccbbf..537effa13d 100644 --- a/catalyst_voices/packages/catalyst_voices_assets/example/lib/src/main.dart +++ b/catalyst_voices/packages/catalyst_voices_assets/example/lib/src/main.dart @@ -17,7 +17,7 @@ final class Example extends StatelessWidget { const Text( 'Catalyst Assets', style: TextStyle( - color: VoicesColors.purpleGradientStart, + color: VoicesColors.lightPrimary, fontFamily: VoicesFonts.sFPro, fontSize: 32, ), diff --git a/catalyst_voices/packages/catalyst_voices_assets/lib/generated/colors.gen.dart b/catalyst_voices/packages/catalyst_voices_assets/lib/generated/colors.gen.dart index 6259051f28..8e121dd46c 100644 --- a/catalyst_voices/packages/catalyst_voices_assets/lib/generated/colors.gen.dart +++ b/catalyst_voices/packages/catalyst_voices_assets/lib/generated/colors.gen.dart @@ -13,36 +13,285 @@ import 'package:flutter/material.dart'; class VoicesColors { VoicesColors._(); - /// Color: #1235C7 - static const Color blue = Color(0xFF1235C7); + /// Color: #FF9999 + static const Color darkError = Color(0xFFFF9999); - /// Color: #506288 - static const Color blueText = Color(0xFF506288); + /// Color: #AD0000 + static const Color darkErrorContainer = Color(0xFFAD0000); + + /// Color: #212A3D + static const Color darkIconsBackground = Color(0xFF212A3D); + + /// Color: #61BFC8D9 + static const Color darkIconsDisabled = Color(0x61BFC8D9); + + /// Color: #FF9999 + static const Color darkIconsError = Color(0xFFFF9999); + + /// Color: #F2F4F8 + static const Color darkIconsForeground = Color(0xFFF2F4F8); + + /// Color: #728EF3 + static const Color darkIconsPrimary = Color(0xFF728EF3); + + /// Color: #DF8AF5 + static const Color darkIconsSecondary = Color(0xFFDF8AF5); + + /// Color: #85E093 + static const Color darkIconsSuccess = Color(0xFF85E093); + + /// Color: #FAB484 + static const Color darkIconsWarning = Color(0xFFFAB484); + + /// Color: #380000 + static const Color darkOnError = Color(0xFF380000); + + /// Color: #FFD1D1 + static const Color darkOnErrorContainer = Color(0xFFFFD1D1); + + /// Color: #0C288D + static const Color darkOnPrimary = Color(0xFF0C288D); + + /// Color: #E8ECFD + static const Color darkOnPrimaryContainer = Color(0xFFE8ECFD); + + /// Color: #26042F + static const Color darkOnSecondary = Color(0xFF26042F); + + /// Color: #9910BC + static const Color darkOnSecondaryContainer = Color(0xFF9910BC); + + /// Color: #08210C + static const Color darkOnSuccess = Color(0xFF08210C); + + /// Color: #CEF3D4 + static const Color darkOnSuccessContainer = Color(0xFFCEF3D4); + + /// Color: #1FCC0000 + static const Color darkOnSurfaceError012 = Color(0x1FCC0000); + + /// Color: #29CC0000 + static const Color darkOnSurfaceError016 = Color(0x29CC0000); + + /// Color: #1FFFC2C2 + static const Color darkOnSurfaceError08 = Color(0x1FFFC2C2); + + /// Color: #1FBFC8D9 + static const Color darkOnSurfaceNeutral012 = Color(0x1FBFC8D9); + + /// Color: #29212A3D + static const Color darkOnSurfaceNeutral016 = Color(0x29212A3D); + + /// Color: #1FBFC8D9 + static const Color darkOnSurfaceNeutral08 = Color(0x1FBFC8D9); + + /// Color: #1F123CD3 + static const Color darkOnSurfacePrimary012 = Color(0x1F123CD3); + + /// Color: #29123CD3 + static const Color darkOnSurfacePrimary016 = Color(0x29123CD3); + + /// Color: #1F123CD3 + static const Color darkOnSurfacePrimary08 = Color(0x1F123CD3); + + /// Color: #0C288D + static const Color darkOnSurfacePrimaryContainer = Color(0xFF0C288D); + + /// Color: #1FC014EB + static const Color darkOnSurfaceSecondary012 = Color(0x1FC014EB); + + /// Color: #29C014EB + static const Color darkOnSurfaceSecondary016 = Color(0x29C014EB); + + /// Color: #1FD972F3 + static const Color darkOnSurfaceSecondary08 = Color(0x1FD972F3); + + /// Color: #2C1302 + static const Color darkOnWarning = Color(0xFF2C1302); + + /// Color: #FDE1CE + static const Color darkOnWarningContainer = Color(0xFFFDE1CE); + + /// Color: #7F90B3 + static const Color darkOutline = Color(0xFF7F90B3); + + /// Color: #364463 + static const Color darkOutlineVariant = Color(0xFF364463); + + /// Color: #728EF3 + static const Color darkPrimary = Color(0xFF728EF3); + + /// Color: #1035BC + static const Color darkPrimaryContainer = Color(0xFF1035BC); + + /// Color: #DF8AF5 + static const Color darkSecondary = Color(0xFFDF8AF5); + + /// Color: #9910BC + static const Color darkSecondaryContainer = Color(0xFF9910BC); + + /// Color: #BAEDC2 + static const Color darkSuccess = Color(0xFFBAEDC2); + + /// Color: #1D722A + static const Color darkSuccessContainer = Color(0xFF1D722A); + + /// Color: #61D9DEE8 + static const Color darkTextDisabled = Color(0x61D9DEE8); + + /// Color: #E6E9F0 + static const Color darkTextOnPrimary = Color(0xFFE6E9F0); + + /// Color: #0C288D + static const Color darkTextOnPrimaryContainer = Color(0xFF0C288D); + + /// Color: #FFFFFF + static const Color darkTextPrimary = Color(0xFFFFFFFF); + + /// Color: #FBC9A7 + static const Color darkWarning = Color(0xFFFBC9A7); - /// Color: #000000 - static const Color darkBackground = Color(0xFF000000); + /// Color: #B64E07 + static const Color darkWarningContainer = Color(0xFFB64E07); - /// Color: #222126 - static const Color darkCard = Color(0xFF222126); + /// Color: #CC0000 + static const Color lightError = Color(0xFFCC0000); - /// Color: #7CAE7A - static const Color green = Color(0xFF7CAE7A); + /// Color: #FFD1D1 + static const Color lightErrorContainer = Color(0xFFFFD1D1); - /// Color: #512DA8 - static const Color purple = Color(0xFF512DA8); + /// Color: #FFFFFF + static const Color lightIconsBackground = Color(0xFFFFFFFF); + + /// Color: #61212A3D + static const Color lightIconsDisabled = Color(0x61212A3D); + + /// Color: #CC0000 + static const Color lightIconsError = Color(0xFFCC0000); + + /// Color: #212A3D + static const Color lightIconsForeground = Color(0xFF212A3D); + + /// Color: #123CD3 + static const Color lightIconsPrimary = Color(0xFF123CD3); + + /// Color: #C014EB + static const Color lightIconsSecondary = Color(0xFFC014EB); + + /// Color: #218230 + static const Color lightIconsSuccess = Color(0xFF218230); + + /// Color: #E76309 + static const Color lightIconsWarning = Color(0xFFE76309); + + /// Color: #FFFFFF + static const Color lightOnError = Color(0xFFFFFFFF); + + /// Color: #700000 + static const Color lightOnErrorContainer = Color(0xFF700000); + + /// Color: #FFFFFF + static const Color lightOnPrimary = Color(0xFFFFFFFF); + + /// Color: #081B5E + static const Color lightOnPrimaryContainer = Color(0xFF081B5E); + + /// Color: #FFFFFF + static const Color lightOnSecondary = Color(0xFFFFFFFF); + + /// Color: #4D085E + static const Color lightOnSecondaryContainer = Color(0xFF4D085E); + + /// Color: #FFFFFF + static const Color lightOnSuccess = Color(0xFFFFFFFF); + + /// Color: #13491B + static const Color lightOnSuccessContainer = Color(0xFF13491B); + + /// Color: #1FCC0000 + static const Color lightOnSurfaceError012 = Color(0x1FCC0000); + + /// Color: #29CC0000 + static const Color lightOnSurfaceError016 = Color(0x29CC0000); + + /// Color: #14CC0000 + static const Color lightOnSurfaceError08 = Color(0x14CC0000); - /// Color: #673AB7 - static const Color purpleGradientStart = Color(0xFF673AB7); + /// Color: #1F212A3D + static const Color lightOnSurfaceNeutral012 = Color(0x1F212A3D); - /// Color: #512DA8 - static const Color purpleGradientStop = Color(0xFF512DA8); + /// Color: #29212A3D + static const Color lightOnSurfaceNeutral016 = Color(0x29212A3D); - /// Color: #B02E0C - static const Color red = Color(0xFFB02E0C); + /// Color: #14212A3D + static const Color lightOnSurfaceNeutral08 = Color(0x14212A3D); - /// Color: #565656 - static const Color today = Color(0xFF565656); + /// Color: #1F123CD3 + static const Color lightOnSurfacePrimary012 = Color(0x1F123CD3); + + /// Color: #29123CD3 + static const Color lightOnSurfacePrimary016 = Color(0x29123CD3); + + /// Color: #14123CD3 + static const Color lightOnSurfacePrimary08 = Color(0x14123CD3); + + /// Color: #A1B4F7 + static const Color lightOnSurfacePrimaryContainer = Color(0xFFA1B4F7); + + /// Color: #1FC014EB + static const Color lightOnSurfaceSecondary012 = Color(0x1FC014EB); + + /// Color: #29C014EB + static const Color lightOnSurfaceSecondary016 = Color(0x29C014EB); + + /// Color: #14C014EB + static const Color lightOnSurfaceSecondary08 = Color(0x14C014EB); /// Color: #FFFFFF - static const Color white = Color(0xFFFFFFFF); + static const Color lightOnWarning = Color(0xFFFFFFFF); + + /// Color: #582603 + static const Color lightOnWarningContainer = Color(0xFF582603); + + /// Color: #D9DEE8 + static const Color lightOutline = Color(0xFFD9DEE8); + + /// Color: #61BFC8D9 + static const Color lightOutlineVariant = Color(0x61BFC8D9); + + /// Color: #123CD3 + static const Color lightPrimary = Color(0xFF123CD3); + + /// Color: #A1B4F7 + static const Color lightPrimaryContainer = Color(0xFFA1B4F7); + + /// Color: #C014EB + static const Color lightSecondary = Color(0xFFC014EB); + + /// Color: #E6A1F7 + static const Color lightSecondaryContainer = Color(0xFFE6A1F7); + + /// Color: #218230 + static const Color lightSuccess = Color(0xFF218230); + + /// Color: #CEF3D4 + static const Color lightSuccessContainer = Color(0xFFCEF3D4); + + /// Color: #61212A3D + static const Color lightTextDisabled = Color(0x61212A3D); + + /// Color: #506288 + static const Color lightTextOnPrimary = Color(0xFF506288); + + /// Color: #FFFFFF + static const Color lightTextOnPrimaryContainer = Color(0xFFFFFFFF); + + /// Color: #212A3D + static const Color lightTextPrimary = Color(0xFF212A3D); + + /// Color: #E76309 + static const Color lightWarning = Color(0xFFE76309); + + /// Color: #FDE1CE + static const Color lightWarningContainer = Color(0xFFFDE1CE); } diff --git a/catalyst_voices/packages/catalyst_voices_brands/lib/src/theme_builder/theme_builder.dart b/catalyst_voices/packages/catalyst_voices_brands/lib/src/theme_builder/theme_builder.dart index 40c4ae71cb..440921a96a 100644 --- a/catalyst_voices/packages/catalyst_voices_brands/lib/src/theme_builder/theme_builder.dart +++ b/catalyst_voices/packages/catalyst_voices_brands/lib/src/theme_builder/theme_builder.dart @@ -4,23 +4,34 @@ import 'package:catalyst_voices_brands/src/themes/fallback.dart'; import 'package:flutter/material.dart'; /// A utility class to build themes dynamically based on brand keys. -/// +/// /// [buildTheme] can be used to obtain the corresponding theme data for the /// [BrandKey] passed to the method. -/// -/// For each brand there is a specific key defined in the [BrandKey] enum +/// +/// [buildDarkTheme] operates in the same way but picks the dark version of the +/// theme for a specific brand. +/// +/// For each brand there is a specific key defined in the [BrandKey] enum /// and a corresponding [ThemeData] in the `themes` folder. +/// For each brand a light and a dark [ThemeData] should be defined. /// -/// [buildTheme] defaults to the [catalyst] theme. +/// [buildTheme] and [buildDarkTheme] default to the [catalyst] theme. class ThemeBuilder { + static final Map lightThemes = { + BrandKey.catalyst: catalyst, + BrandKey.fallback: fallback, + }; + + static final Map darkThemes = { + BrandKey.catalyst: darkCatalyst, + BrandKey.fallback: darkFallback, + }; + static ThemeData buildTheme(BrandKey? brandKey) { - switch (brandKey) { - case BrandKey.catalyst: - return catalyst; - case BrandKey.fallback: - return fallback; - case null: - return catalyst; - } + return lightThemes[brandKey ?? BrandKey.catalyst]!; + } + + static ThemeData buildDarkTheme(BrandKey? brandKey) { + return darkThemes[brandKey ?? BrandKey.catalyst]!; } } diff --git a/catalyst_voices/packages/catalyst_voices_brands/lib/src/themes/catalyst.dart b/catalyst_voices/packages/catalyst_voices_brands/lib/src/themes/catalyst.dart index 8e3c5698d9..885c4efcf6 100644 --- a/catalyst_voices/packages/catalyst_voices_brands/lib/src/themes/catalyst.dart +++ b/catalyst_voices/packages/catalyst_voices_brands/lib/src/themes/catalyst.dart @@ -1,10 +1,232 @@ import 'package:catalyst_voices_assets/catalyst_voices_assets.dart'; +import 'package:catalyst_voices_assets/generated/colors.gen.dart'; +import 'package:catalyst_voices_brands/src/themes/voices_color_scheme.dart'; import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +ThemeData _buildThemeData( + ColorScheme colorScheme, + VoicesColorScheme voicesColorScheme, +) { + return ThemeData( + textTheme: TextTheme( + displayLarge: GoogleFonts.notoSans( + color: voicesColorScheme.textPrimary, + fontSize: 57, + letterSpacing: -1.14, + fontWeight: FontWeight.w700, + height: 1.12, + ), + displayMedium: GoogleFonts.poppins( + color: voicesColorScheme.textPrimary, + fontSize: 45, + fontWeight: FontWeight.w700, + height: 1.15, + ), + displaySmall: GoogleFonts.poppins( + color: voicesColorScheme.textPrimary, + fontSize: 36, + fontWeight: FontWeight.w700, + height: 1.22, + ), + headlineLarge: GoogleFonts.poppins( + color: voicesColorScheme.textPrimary, + fontSize: 32, + fontWeight: FontWeight.w700, + height: 1.25, + ), + headlineMedium: GoogleFonts.poppins( + color: voicesColorScheme.textPrimary, + fontSize: 28, + fontWeight: FontWeight.w700, + height: 1.28, + ), + headlineSmall: GoogleFonts.poppins( + color: voicesColorScheme.textPrimary, + fontSize: 24, + fontWeight: FontWeight.w700, + height: 1.33, + ), + titleLarge: GoogleFonts.poppins( + color: voicesColorScheme.textPrimary, + fontSize: 22, + fontWeight: FontWeight.w700, + height: 1.27, + letterSpacing: 0.66, + ), + titleMedium: GoogleFonts.poppins( + color: voicesColorScheme.textPrimary, + fontSize: 16, + fontWeight: FontWeight.w700, + height: 1.5, + letterSpacing: 0.48, + ), + titleSmall: GoogleFonts.poppins( + color: voicesColorScheme.textPrimary, + fontSize: 14, + fontWeight: FontWeight.w700, + height: 1.42, + letterSpacing: 0.42, + ), + bodyLarge: GoogleFonts.notoSans( + color: voicesColorScheme.textPrimary, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + letterSpacing: 0.08, + ), + bodyMedium: GoogleFonts.notoSans( + color: voicesColorScheme.textPrimary, + fontSize: 14, + fontWeight: FontWeight.w500, + height: 1.42, + letterSpacing: 0.04, + ), + bodySmall: GoogleFonts.notoSans( + color: voicesColorScheme.textPrimary, + fontSize: 12, + fontWeight: FontWeight.w500, + height: 1.33, + letterSpacing: 0.05, + ), + labelLarge: GoogleFonts.notoSans( + color: voicesColorScheme.textPrimary, + fontSize: 14, + fontWeight: FontWeight.w500, + height: 1.42, + letterSpacing: 0.10, + ), + labelMedium: GoogleFonts.notoSans( + color: voicesColorScheme.textPrimary, + fontSize: 12, + fontWeight: FontWeight.w500, + height: 1, + ), + labelSmall: GoogleFonts.notoSans( + color: voicesColorScheme.textPrimary, + fontSize: 11, + fontWeight: FontWeight.w500, + height: 1.45, + letterSpacing: 0.50, + ), + ), + colorScheme: colorScheme, + extensions: >[ + voicesColorScheme, + ], + ); +} + +const ColorScheme lightColorScheme = ColorScheme.light( + primary: VoicesColors.lightPrimary, + primaryContainer: VoicesColors.lightPrimaryContainer, + onPrimaryContainer: VoicesColors.lightOnPrimaryContainer, + secondary: VoicesColors.lightSecondary, + onSecondary: VoicesColors.lightOnSecondary, + secondaryContainer: VoicesColors.lightSecondaryContainer, + onSecondaryContainer: VoicesColors.lightOnSecondaryContainer, + error: VoicesColors.lightError, + errorContainer: VoicesColors.lightErrorContainer, + onErrorContainer: VoicesColors.lightOnErrorContainer, + outline: VoicesColors.lightOutline, + outlineVariant: VoicesColors.lightOutlineVariant, +); + +const VoicesColorScheme lightVoicesColorScheme = VoicesColorScheme( + textPrimary: VoicesColors.lightTextPrimary, + textOnPrimary: VoicesColors.lightTextOnPrimary, + textOnPrimaryContainer: VoicesColors.lightTextOnPrimaryContainer, + textDisabled: VoicesColors.lightTextDisabled, + success: VoicesColors.lightSuccess, + onSuccess: VoicesColors.lightOnSuccess, + successContainer: VoicesColors.lightSuccessContainer, + onSuccessContainer: VoicesColors.lightOnSuccessContainer, + warning: VoicesColors.lightWarning, + onWarning: VoicesColors.lightOnWarning, + warningContainer: VoicesColors.lightWarningContainer, + onWarningContainer: VoicesColors.lightOnWarningContainer, + onSurfaceNeutral08: VoicesColors.lightOnSurfaceNeutral08, + onSurfaceNeutral012: VoicesColors.lightOnSurfaceNeutral012, + onSurfaceNeutral016: VoicesColors.lightOnSurfaceNeutral016, + onSurfacePrimaryContainer: VoicesColors.lightOnSurfacePrimaryContainer, + onSurfacePrimary08: VoicesColors.lightOnSurfacePrimary08, + onSurfacePrimary012: VoicesColors.lightOnSurfacePrimary012, + onSurfacePrimary016: VoicesColors.lightOnSurfacePrimary016, + onSurfaceSecondary08: VoicesColors.lightOnSurfaceSecondary08, + onSurfaceSecondary012: VoicesColors.lightOnSurfaceSecondary012, + onSurfaceSecondary016: VoicesColors.lightOnSurfaceSecondary016, + onSurfaceError08: VoicesColors.lightOnSurfaceError08, + onSurfaceError012: VoicesColors.lightOnSurfaceError012, + onSurfaceError016: VoicesColors.lightOnSurfaceError016, + iconsForeground: VoicesColors.lightIconsForeground, + iconsBackground: VoicesColors.lightIconsBackground, + iconsDisabled: VoicesColors.lightIconsDisabled, + iconsPrimary: VoicesColors.lightIconsPrimary, + iconsSecondary: VoicesColors.lightIconsSecondary, + iconsSuccess: VoicesColors.lightIconsSuccess, + iconsWarning: VoicesColors.lightIconsWarning, + iconsError: VoicesColors.lightIconsError, +); + +const ColorScheme darkColorScheme = ColorScheme.dark( + primary: VoicesColors.darkPrimary, + primaryContainer: VoicesColors.darkPrimaryContainer, + onPrimaryContainer: VoicesColors.darkOnPrimaryContainer, + secondary: VoicesColors.darkSecondary, + onSecondary: VoicesColors.darkOnSecondary, + secondaryContainer: VoicesColors.darkSecondaryContainer, + onSecondaryContainer: VoicesColors.darkOnSecondaryContainer, + error: VoicesColors.darkError, + errorContainer: VoicesColors.darkErrorContainer, + onErrorContainer: VoicesColors.darkOnErrorContainer, + outline: VoicesColors.darkOutline, + outlineVariant: VoicesColors.darkOutlineVariant, +); + +const VoicesColorScheme darkVoicesColorScheme = VoicesColorScheme( + textPrimary: VoicesColors.darkTextPrimary, + textOnPrimary: VoicesColors.darkTextOnPrimary, + textOnPrimaryContainer: VoicesColors.darkTextOnPrimaryContainer, + textDisabled: VoicesColors.darkTextDisabled, + success: VoicesColors.darkSuccess, + onSuccess: VoicesColors.darkOnSuccess, + successContainer: VoicesColors.darkSuccessContainer, + onSuccessContainer: VoicesColors.darkOnSuccessContainer, + warning: VoicesColors.darkWarning, + onWarning: VoicesColors.darkOnWarning, + warningContainer: VoicesColors.darkWarningContainer, + onWarningContainer: VoicesColors.darkOnWarningContainer, + onSurfaceNeutral08: VoicesColors.darkOnSurfaceNeutral08, + onSurfaceNeutral012: VoicesColors.darkOnSurfaceNeutral012, + onSurfaceNeutral016: VoicesColors.darkOnSurfaceNeutral016, + onSurfacePrimaryContainer: VoicesColors.darkOnSurfacePrimaryContainer, + onSurfacePrimary08: VoicesColors.darkOnSurfacePrimary08, + onSurfacePrimary012: VoicesColors.darkOnSurfacePrimary012, + onSurfacePrimary016: VoicesColors.darkOnSurfacePrimary016, + onSurfaceSecondary08: VoicesColors.darkOnSurfaceSecondary08, + onSurfaceSecondary012: VoicesColors.darkOnSurfaceSecondary012, + onSurfaceSecondary016: VoicesColors.darkOnSurfaceSecondary016, + onSurfaceError08: VoicesColors.darkOnSurfaceError08, + onSurfaceError012: VoicesColors.darkOnSurfaceError012, + onSurfaceError016: VoicesColors.darkOnSurfaceError016, + iconsForeground: VoicesColors.darkIconsForeground, + iconsBackground: VoicesColors.darkIconsBackground, + iconsDisabled: VoicesColors.darkIconsDisabled, + iconsPrimary: VoicesColors.darkIconsPrimary, + iconsSecondary: VoicesColors.darkIconsSecondary, + iconsSuccess: VoicesColors.darkIconsSuccess, + iconsWarning: VoicesColors.darkIconsWarning, + iconsError: VoicesColors.darkIconsError, +); /// [ThemeData] for the `catalyst` brand. -final ThemeData catalyst = ThemeData( - colorScheme: ColorScheme.fromSeed( - seedColor: VoicesColors.blue, - primary: VoicesColors.blue, - ), +final ThemeData catalyst = _buildThemeData( + lightColorScheme, + lightVoicesColorScheme, +); + +/// Dark [ThemeData] for the `catalyst` brand. +final ThemeData darkCatalyst = _buildThemeData( + darkColorScheme, + darkVoicesColorScheme, ); diff --git a/catalyst_voices/packages/catalyst_voices_brands/lib/src/themes/fallback.dart b/catalyst_voices/packages/catalyst_voices_brands/lib/src/themes/fallback.dart index fc8dca40e4..7fa296225d 100644 --- a/catalyst_voices/packages/catalyst_voices_brands/lib/src/themes/fallback.dart +++ b/catalyst_voices/packages/catalyst_voices_brands/lib/src/themes/fallback.dart @@ -1,4 +1,7 @@ import 'package:flutter/material.dart'; /// [ThemeData] for the `fallback` brand. -final ThemeData fallback = ThemeData(useMaterial3: true); +final ThemeData fallback = ThemeData.light(); + +/// Dark [ThemeData] for the `fallback` brand. +final ThemeData darkFallback = ThemeData.dark(); diff --git a/catalyst_voices/packages/catalyst_voices_brands/lib/src/themes/voices_color_scheme.dart b/catalyst_voices/packages/catalyst_voices_brands/lib/src/themes/voices_color_scheme.dart new file mode 100644 index 0000000000..2708ae520f --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_brands/lib/src/themes/voices_color_scheme.dart @@ -0,0 +1,219 @@ +import 'package:flutter/material.dart'; + +@immutable +class VoicesColorScheme extends ThemeExtension { + final Color? textPrimary; + final Color? textOnPrimary; + final Color? textOnPrimaryContainer; + final Color? textDisabled; + final Color? success; + final Color? onSuccess; + final Color? successContainer; + final Color? onSuccessContainer; + final Color? warning; + final Color? onWarning; + final Color? warningContainer; + final Color? onWarningContainer; + final Color? onSurfaceNeutral08; + final Color? onSurfaceNeutral012; + final Color? onSurfaceNeutral016; + final Color? onSurfacePrimaryContainer; + final Color? onSurfacePrimary08; + final Color? onSurfacePrimary012; + final Color? onSurfacePrimary016; + final Color? onSurfaceSecondary08; + final Color? onSurfaceSecondary012; + final Color? onSurfaceSecondary016; + final Color? onSurfaceError08; + final Color? onSurfaceError012; + final Color? onSurfaceError016; + final Color? iconsForeground; + final Color? iconsBackground; + final Color? iconsDisabled; + final Color? iconsPrimary; + final Color? iconsSecondary; + final Color? iconsSuccess; + final Color? iconsWarning; + final Color? iconsError; + + const VoicesColorScheme({ + required this.textPrimary, + required this.textOnPrimary, + required this.textOnPrimaryContainer, + required this.textDisabled, + required this.success, + required this.onSuccess, + required this.successContainer, + required this.onSuccessContainer, + required this.warning, + required this.onWarning, + required this.warningContainer, + required this.onWarningContainer, + required this.onSurfaceNeutral08, + required this.onSurfaceNeutral012, + required this.onSurfaceNeutral016, + required this.onSurfacePrimaryContainer, + required this.onSurfacePrimary08, + required this.onSurfacePrimary012, + required this.onSurfacePrimary016, + required this.onSurfaceSecondary08, + required this.onSurfaceSecondary012, + required this.onSurfaceSecondary016, + required this.onSurfaceError08, + required this.onSurfaceError012, + required this.onSurfaceError016, + required this.iconsForeground, + required this.iconsBackground, + required this.iconsDisabled, + required this.iconsPrimary, + required this.iconsSecondary, + required this.iconsSuccess, + required this.iconsWarning, + required this.iconsError, + }); + + @override + ThemeExtension copyWith({ + Color? textPrimary, + Color? textOnPrimary, + Color? textOnPrimaryContainer, + Color? textDisabled, + Color? success, + Color? onSuccess, + Color? successContainer, + Color? onSuccessContainer, + Color? warning, + Color? onWarning, + Color? warningContainer, + Color? onWarningContainer, + Color? onSurfaceNeutral08, + Color? onSurfaceNeutral012, + Color? onSurfaceNeutral016, + Color? onSurfacePrimaryContainer, + Color? onSurfacePrimary08, + Color? onSurfacePrimary012, + Color? onSurfacePrimary016, + Color? onSurfaceSecondary08, + Color? onSurfaceSecondary012, + Color? onSurfaceSecondary016, + Color? onSurfaceError08, + Color? onSurfaceError012, + Color? onSurfaceError016, + Color? iconsForeground, + Color? iconsBackground, + Color? iconsDisabled, + Color? iconsPrimary, + Color? iconsSecondary, + Color? iconsSuccess, + Color? iconsWarning, + Color? iconsError, + }) { + return VoicesColorScheme( + textPrimary: textPrimary ?? this.textPrimary, + textOnPrimary: textOnPrimary ?? this.textOnPrimary, + textOnPrimaryContainer: + textOnPrimaryContainer ?? this.textOnPrimaryContainer, + textDisabled: textDisabled ?? this.textDisabled, + success: success ?? this.success, + onSuccess: onSuccess ?? this.onSuccess, + successContainer: successContainer ?? this.successContainer, + onSuccessContainer: onSuccessContainer ?? this.onSuccessContainer, + warning: warning ?? this.warning, + onWarning: onWarning ?? this.onWarning, + warningContainer: warningContainer ?? this.warningContainer, + onWarningContainer: onWarningContainer ?? this.onWarningContainer, + onSurfaceNeutral08: onSurfaceNeutral08 ?? this.onSurfaceError08, + onSurfaceNeutral012: onSurfaceNeutral012 ?? this.onSurfaceError012, + onSurfaceNeutral016: onSurfaceNeutral016 ?? this.onSurfaceError016, + onSurfacePrimaryContainer: + onSurfacePrimaryContainer ?? this.onSurfacePrimaryContainer, + onSurfacePrimary08: onSurfacePrimary08 ?? this.onSurfacePrimary08, + onSurfacePrimary012: onSurfacePrimary012 ?? this.onSurfacePrimary012, + onSurfacePrimary016: onSurfacePrimary016 ?? this.onSurfacePrimary016, + onSurfaceSecondary08: onSurfaceSecondary08 ?? this.onSurfaceSecondary08, + onSurfaceSecondary012: + onSurfaceSecondary012 ?? this.onSurfaceSecondary012, + onSurfaceSecondary016: + onSurfaceSecondary016 ?? this.onSurfaceSecondary016, + onSurfaceError08: onSurfaceError08 ?? this.onSurfaceError08, + onSurfaceError012: onSurfaceError012 ?? this.onSurfaceError012, + onSurfaceError016: onSurfaceError016 ?? this.onSurfaceError016, + iconsForeground: iconsForeground ?? this.iconsForeground, + iconsBackground: iconsBackground ?? this.iconsBackground, + iconsDisabled: iconsDisabled ?? this.iconsDisabled, + iconsPrimary: iconsPrimary ?? this.iconsPrimary, + iconsSecondary: iconsSecondary ?? this.iconsSecondary, + iconsSuccess: iconsSuccess ?? this.iconsSuccess, + iconsWarning: iconsWarning ?? this.iconsWarning, + iconsError: iconsError ?? this.iconsError, + ); + } + + @override + VoicesColorScheme lerp( + ThemeExtension? other, + double t, + ) { + if (other is! VoicesColorScheme) { + return this; + } + return VoicesColorScheme( + textPrimary: Color.lerp(textPrimary, other.textPrimary, t), + textOnPrimary: Color.lerp(textOnPrimary, other.textOnPrimary, t), + textOnPrimaryContainer: + Color.lerp(textOnPrimaryContainer, other.textOnPrimaryContainer, t), + textDisabled: Color.lerp(textDisabled, other.textDisabled, t), + success: Color.lerp(success, other.success, t), + onSuccess: Color.lerp(onSuccess, other.onSuccess, t), + successContainer: Color.lerp(successContainer, other.successContainer, t), + onSuccessContainer: + Color.lerp(onSuccessContainer, other.onSuccessContainer, t), + warning: Color.lerp(warning, other.warning, t), + onWarning: Color.lerp(onWarning, other.onWarning, t), + warningContainer: Color.lerp(warningContainer, other.warningContainer, t), + onWarningContainer: + Color.lerp(onWarningContainer, other.onWarningContainer, t), + onSurfaceNeutral08: + Color.lerp(onSurfaceNeutral08, other.onSurfaceNeutral08, t), + onSurfaceNeutral012: + Color.lerp(onSurfaceNeutral012, other.onSurfaceNeutral012, t), + onSurfaceNeutral016: + Color.lerp(onSurfaceNeutral016, other.onSurfaceNeutral016, t), + onSurfacePrimaryContainer: Color.lerp( + onSurfacePrimaryContainer, + other.onSurfacePrimaryContainer, + t, + ), + onSurfacePrimary08: + Color.lerp(onSurfacePrimary08, other.onSurfacePrimary08, t), + onSurfacePrimary012: + Color.lerp(onSurfacePrimary012, other.onSurfacePrimary012, t), + onSurfacePrimary016: + Color.lerp(onSurfacePrimary016, other.onSurfacePrimary016, t), + onSurfaceSecondary08: + Color.lerp(onSurfaceSecondary08, other.onSurfaceSecondary08, t), + onSurfaceSecondary012: + Color.lerp(onSurfaceSecondary012, other.onSurfaceSecondary012, t), + onSurfaceSecondary016: + Color.lerp(onSurfaceSecondary016, other.onSurfaceSecondary016, t), + onSurfaceError08: Color.lerp(onSurfaceError08, other.onSurfaceError08, t), + onSurfaceError012: + Color.lerp(onSurfaceError012, other.onSurfaceError012, t), + onSurfaceError016: + Color.lerp(onSurfaceError016, other.onSurfaceError016, t), + iconsForeground: Color.lerp(iconsForeground, other.iconsForeground, t), + iconsBackground: Color.lerp(iconsBackground, other.iconsBackground, t), + iconsDisabled: Color.lerp(iconsDisabled, other.iconsDisabled, t), + iconsPrimary: Color.lerp(iconsPrimary, other.iconsPrimary, t), + iconsSecondary: Color.lerp(iconsSecondary, other.iconsSecondary, t), + iconsSuccess: Color.lerp(iconsSuccess, other.iconsSuccess, t), + iconsWarning: Color.lerp(iconsWarning, other.iconsWarning, t), + iconsError: Color.lerp(iconsError, other.iconsError, t), + ); + } +} + +extension VoicesColorSchemeExtension on ThemeData { + VoicesColorScheme get colors => extension()!; + Color get linksPrimary => primaryColor; +} diff --git a/catalyst_voices/packages/catalyst_voices_brands/pubspec.yaml b/catalyst_voices/packages/catalyst_voices_brands/pubspec.yaml index acd46ab52c..c77b7a4a4a 100644 --- a/catalyst_voices/packages/catalyst_voices_brands/pubspec.yaml +++ b/catalyst_voices/packages/catalyst_voices_brands/pubspec.yaml @@ -12,6 +12,7 @@ dependencies: path: ../catalyst_voices_assets flutter: sdk: flutter + google_fonts: ^6.2.1 dev_dependencies: catalyst_analysis: diff --git a/catalyst_voices/packages/catalyst_voices_brands/test/src/catalyst_voices_brands_test.dart b/catalyst_voices/packages/catalyst_voices_brands/test/src/catalyst_voices_brands_test.dart index ea24aace4c..eea47f7db2 100644 --- a/catalyst_voices/packages/catalyst_voices_brands/test/src/catalyst_voices_brands_test.dart +++ b/catalyst_voices/packages/catalyst_voices_brands/test/src/catalyst_voices_brands_test.dart @@ -10,51 +10,51 @@ void main() { const fallbackKey = Key('F'); Widget buildApp() => BlocProvider( - create: (context) => BrandBloc(), - child: BlocBuilder( - builder: (context, state) { - return MaterialApp( - home: Builder( - builder: (context) => Scaffold( - body: Row( - children: [ - MaterialButton( - key: catalystKey, - color: Theme.of(context).primaryColor, - onPressed: () { - context.read().add( - const BrandChangedEvent(BrandKey.catalyst), - ); - }, - child: const Text('Catalyst'), + create: (context) => BrandBloc(), + child: BlocBuilder( + builder: (context, state) { + return MaterialApp( + home: Builder( + builder: (context) => Scaffold( + body: Row( + children: [ + MaterialButton( + key: catalystKey, + color: Theme.of(context).primaryColor, + onPressed: () { + context.read().add( + const BrandChangedEvent(BrandKey.catalyst), + ); + }, + child: const Text('Catalyst'), + ), + MaterialButton( + key: fallbackKey, + color: Theme.of(context).primaryColor, + child: const Text('Fallback'), + onPressed: () { + context.read().add( + const BrandChangedEvent(BrandKey.fallback), + ); + }, + ), + ], ), - MaterialButton( - key: fallbackKey, - color: Theme.of(context).primaryColor, - child: const Text('Fallback'), - onPressed: () { - context.read().add( - const BrandChangedEvent(BrandKey.fallback), - ); - }, - ), - ], + ), ), - ), - ), - theme: ThemeBuilder.buildTheme(state.brandKey), - ); - }, - ), - ); + theme: ThemeBuilder.buildTheme(state.brandKey), + darkTheme: ThemeBuilder.buildTheme(state.brandKey), + ); + }, + ), + ); group('Test brands', () { - // Colors used in the Brand themes as primary. They are used for // the color of the widgets we are testing and they are the colors // we will check against to ensure correct rendering. final fallbackColor = ThemeData(useMaterial3: true).primaryColor; - const catalystColor = VoicesColors.blue; + const catalystColor = VoicesColors.lightPrimary; testWidgets('Default Catalyst theme is applied', (tester) async { await tester.pumpWidget( @@ -85,10 +85,10 @@ void main() { expect(catalystButton, findsOneWidget); expect(fallbackButton, findsOneWidget); - + await tester.tap(fallbackButton); // We need to wait for the animation to complete - await tester.pumpAndSettle(); + await tester.pumpAndSettle(); expect( tester.widget(catalystButton).color, fallbackColor, @@ -109,14 +109,14 @@ void main() { expect(catalystButton, findsOneWidget); expect(fallbackButton, findsOneWidget); - + // We first switch do FallbackBrand, we wait for the animation completion // and then we switch back to the CatalystBrand to check the correct // color is applied. await tester.tap(fallbackButton); await tester.pumpAndSettle(); await tester.tap(catalystButton); - await tester.pumpAndSettle(); + await tester.pumpAndSettle(); expect( tester.widget(catalystButton).color, catalystColor, @@ -126,7 +126,5 @@ void main() { catalystColor, ); }); - }); - } diff --git a/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.enums.swagger.dart b/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.enums.swagger.dart index b963d59336..ec8b97b8b5 100644 --- a/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.enums.swagger.dart +++ b/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.enums.swagger.dart @@ -1,22 +1,6 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:collection/collection.dart'; -enum Animals { - @JsonValue(null) - swaggerGeneratedUnknown(null), - - @JsonValue('Dogs') - dogs('Dogs'), - @JsonValue('Cats') - cats('Cats'), - @JsonValue('Rabbits') - rabbits('Rabbits'); - - final String? value; - - const Animals(this.value); -} - enum Network { @JsonValue(null) swaggerGeneratedUnknown(null), diff --git a/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.models.swagger.dart b/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.models.swagger.dart index 199cba5729..49881b58a2 100644 --- a/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.models.swagger.dart +++ b/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.models.swagger.dart @@ -625,31 +625,31 @@ extension $RejectedFragmentExtension on RejectedFragment { } @JsonSerializable(explicitToJson: true) -class ServerErrorPayload { - const ServerErrorPayload({ +class ServerError { + const ServerError({ required this.id, - this.msg, + required this.msg, this.issue, }); - factory ServerErrorPayload.fromJson(Map json) => - _$ServerErrorPayloadFromJson(json); + factory ServerError.fromJson(Map json) => + _$ServerErrorFromJson(json); - static const toJsonFactory = _$ServerErrorPayloadToJson; - Map toJson() => _$ServerErrorPayloadToJson(this); + static const toJsonFactory = _$ServerErrorToJson; + Map toJson() => _$ServerErrorToJson(this); @JsonKey(name: 'id') final String id; @JsonKey(name: 'msg') - final String? msg; + final String msg; @JsonKey(name: 'issue') final String? issue; - static const fromJsonFactory = _$ServerErrorPayloadFromJson; + static const fromJsonFactory = _$ServerErrorFromJson; @override bool operator ==(Object other) { return identical(this, other) || - (other is ServerErrorPayload && + (other is ServerError && (identical(other.id, id) || const DeepCollectionEquality().equals(other.id, id)) && (identical(other.msg, msg) || @@ -669,15 +669,15 @@ class ServerErrorPayload { runtimeType.hashCode; } -extension $ServerErrorPayloadExtension on ServerErrorPayload { - ServerErrorPayload copyWith({String? id, String? msg, String? issue}) { - return ServerErrorPayload( +extension $ServerErrorExtension on ServerError { + ServerError copyWith({String? id, String? msg, String? issue}) { + return ServerError( id: id ?? this.id, msg: msg ?? this.msg, issue: issue ?? this.issue); } - ServerErrorPayload copyWithWrapped( - {Wrapped? id, Wrapped? msg, Wrapped? issue}) { - return ServerErrorPayload( + ServerError copyWithWrapped( + {Wrapped? id, Wrapped? msg, Wrapped? issue}) { + return ServerError( id: (id != null ? id.value : this.id), msg: (msg != null ? msg.value : this.msg), issue: (issue != null ? issue.value : this.issue)); @@ -1053,6 +1053,49 @@ extension $SyncStateExtension on SyncState { } } +@JsonSerializable(explicitToJson: true) +class ValidationError { + const ValidationError({ + required this.message, + }); + + factory ValidationError.fromJson(Map json) => + _$ValidationErrorFromJson(json); + + static const toJsonFactory = _$ValidationErrorToJson; + Map toJson() => _$ValidationErrorToJson(this); + + @JsonKey(name: 'message') + final String message; + static const fromJsonFactory = _$ValidationErrorFromJson; + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other is ValidationError && + (identical(other.message, message) || + const DeepCollectionEquality().equals(other.message, message))); + } + + @override + String toString() => jsonEncode(this); + + @override + int get hashCode => + const DeepCollectionEquality().hash(message) ^ runtimeType.hashCode; +} + +extension $ValidationErrorExtension on ValidationError { + ValidationError copyWith({String? message}) { + return ValidationError(message: message ?? this.message); + } + + ValidationError copyWithWrapped({Wrapped? message}) { + return ValidationError( + message: (message != null ? message.value : this.message)); + } +} + @JsonSerializable(explicitToJson: true) class VotePlan { const VotePlan({ @@ -1425,68 +1468,6 @@ extension $VotingInfoDirectVoterExtension on VotingInfoDirectVoter { } } -String? animalsNullableToJson(enums.Animals? animals) { - return animals?.value; -} - -String? animalsToJson(enums.Animals animals) { - return animals.value; -} - -enums.Animals animalsFromJson( - Object? animals, [ - enums.Animals? defaultValue, -]) { - return enums.Animals.values.firstWhereOrNull((e) => e.value == animals) ?? - defaultValue ?? - enums.Animals.swaggerGeneratedUnknown; -} - -enums.Animals? animalsNullableFromJson( - Object? animals, [ - enums.Animals? defaultValue, -]) { - if (animals == null) { - return null; - } - return enums.Animals.values.firstWhereOrNull((e) => e.value == animals) ?? - defaultValue; -} - -String animalsExplodedListToJson(List? animals) { - return animals?.map((e) => e.value!).join(',') ?? ''; -} - -List animalsListToJson(List? animals) { - if (animals == null) { - return []; - } - - return animals.map((e) => e.value!).toList(); -} - -List animalsListFromJson( - List? animals, [ - List? defaultValue, -]) { - if (animals == null) { - return defaultValue ?? []; - } - - return animals.map((e) => animalsFromJson(e.toString())).toList(); -} - -List? animalsNullableListFromJson( - List? animals, [ - List? defaultValue, -]) { - if (animals == null) { - return defaultValue; - } - - return animals.map((e) => animalsFromJson(e.toString())).toList(); -} - String? networkNullableToJson(enums.Network? network) { return network?.value; } diff --git a/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.models.swagger.g.dart b/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.models.swagger.g.dart index 824cf7a055..d953798421 100644 --- a/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.models.swagger.g.dart +++ b/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.models.swagger.g.dart @@ -152,14 +152,13 @@ Map _$RejectedFragmentToJson(RejectedFragment instance) => 'reason': reasonRejectedToJson(instance.reason), }; -ServerErrorPayload _$ServerErrorPayloadFromJson(Map json) => - ServerErrorPayload( +ServerError _$ServerErrorFromJson(Map json) => ServerError( id: json['id'] as String, - msg: json['msg'] as String?, + msg: json['msg'] as String, issue: json['issue'] as String?, ); -Map _$ServerErrorPayloadToJson(ServerErrorPayload instance) => +Map _$ServerErrorToJson(ServerError instance) => { 'id': instance.id, 'msg': instance.msg, @@ -246,6 +245,16 @@ Map _$SyncStateToJson(SyncState instance) => { 'last_updated': instance.lastUpdated.toIso8601String(), }; +ValidationError _$ValidationErrorFromJson(Map json) => + ValidationError( + message: json['message'] as String, + ); + +Map _$ValidationErrorToJson(ValidationError instance) => + { + 'message': instance.message, + }; + VotePlan _$VotePlanFromJson(Map json) => VotePlan( votingToken: json['voting_token'] as String, ); diff --git a/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.swagger.chopper.dart b/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.swagger.chopper.dart index 7af0561ff4..d839455d5e 100644 --- a/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.swagger.chopper.dart +++ b/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.swagger.chopper.dart @@ -17,37 +17,6 @@ final class _$CatGatewayApi extends CatGatewayApi { @override final Type definitionType = CatGatewayApi; - @override - Future> _apiTestTestIdTestActionGet({ - required int? id, - required String? action, - List? pet, - }) { - final Uri $url = Uri.parse('/api/test/test/${id}/test/${action}'); - final Map $params = {'pet': pet}; - final Request $request = Request( - 'GET', - $url, - client.baseUrl, - parameters: $params, - ); - return client.send($request); - } - - @override - Future> _apiTestTestIdTestActionPost({ - required int? id, - required String? action, - }) { - final Uri $url = Uri.parse('/api/test/test/${id}/test/${action}'); - final Request $request = Request( - 'POST', - $url, - client.baseUrl, - ); - return client.send($request); - } - @override Future> _apiHealthStartedGet() { final Uri $url = Uri.parse('/api/health/started'); diff --git a/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.swagger.dart b/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.swagger.dart index a20a2d48fe..698049b133 100644 --- a/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.swagger.dart +++ b/catalyst_voices/packages/catalyst_voices_services/lib/generated/catalyst_gateway/cat_gateway_api.swagger.dart @@ -48,56 +48,6 @@ abstract class CatGatewayApi extends ChopperService { return _$CatGatewayApi(newClient); } - ///Test Get API - ///@param id The ID of the test. This comment ends up in the documentation. * 5 will print an info log * 10 will print a warn log * 15 will print a error log * 20 will panic which should generate a 500 - ///@param action The action just needs to be any valid UUID. # Make sure its a UUID - ///@param pet List your favorite pets, in order of preference - @deprecated - Future apiTestTestIdTestActionGet({ - required int? id, - required String? action, - List? pet, - }) { - return _apiTestTestIdTestActionGet( - id: id, action: action, pet: animalsListToJson(pet)); - } - - ///Test Get API - ///@param id The ID of the test. This comment ends up in the documentation. * 5 will print an info log * 10 will print a warn log * 15 will print a error log * 20 will panic which should generate a 500 - ///@param action The action just needs to be any valid UUID. # Make sure its a UUID - ///@param pet List your favorite pets, in order of preference - @deprecated - @Get(path: '/api/test/test/{id}/test/{action}') - Future _apiTestTestIdTestActionGet({ - @Path('id') required int? id, - @Path('action') required String? action, - @Query('pet') List? pet, - }); - - ///Test Post API - ///@param id The ID of the test. * 5 will print an info log * 10 will print a warn log * 15 will print a error log * 20 will panic which should generate a 500 - ///@param action The action just needs to be any valid UUID. # Make sure its a UUID - @deprecated - Future apiTestTestIdTestActionPost({ - required int? id, - required String? action, - }) { - return _apiTestTestIdTestActionPost(id: id, action: action); - } - - ///Test Post API - ///@param id The ID of the test. * 5 will print an info log * 10 will print a warn log * 15 will print a error log * 20 will panic which should generate a 500 - ///@param action The action just needs to be any valid UUID. # Make sure its a UUID - @deprecated - @Post( - path: '/api/test/test/{id}/test/{action}', - optionalBody: true, - ) - Future _apiTestTestIdTestActionPost({ - @Path('id') required int? id, - @Path('action') required String? action, - }); - ///Service Started Future apiHealthStartedGet() { return _apiHealthStartedGet(); diff --git a/catalyst_voices/pubspec.yaml b/catalyst_voices/pubspec.yaml index 15c94c316a..810aaed179 100644 --- a/catalyst_voices/pubspec.yaml +++ b/catalyst_voices/pubspec.yaml @@ -10,6 +10,8 @@ environment: dependencies: animated_text_kit: ^4.2.2 animations: ^2.0.11 + catalyst_cardano_serialization: + path: ../catalyst_voices_packages/catalyst_cardano_serialization catalyst_voices_assets: path: ./packages/catalyst_voices_assets catalyst_voices_blocs: diff --git a/catalyst_voices/test_driver/Earthfile b/catalyst_voices/test_driver/Earthfile index b68ca8fc4a..a35db067f1 100644 --- a/catalyst_voices/test_driver/Earthfile +++ b/catalyst_voices/test_driver/Earthfile @@ -1,7 +1,9 @@ -VERSION --try --global-cache --arg-scope-and-set 0.7 +VERSION 0.8 + +IMPORT ../ AS catalyst-voices integration-test-web: - FROM ../+build + FROM catalyst-voices+build ARG TARGETARCH ARG browser LET driver_port = 4444 diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/CHANGELOG.md b/catalyst_voices_packages/catalyst_cardano_serialization/CHANGELOG.md new file mode 100644 index 0000000000..a533b45bb9 --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/CHANGELOG.md @@ -0,0 +1,3 @@ +# 0.1.0 + +* Initial release. diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/README.md b/catalyst_voices_packages/catalyst_cardano_serialization/README.md new file mode 100644 index 0000000000..191e021c7c --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/README.md @@ -0,0 +1 @@ +# catalyst_cardano_serialization diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/analysis_options.yaml b/catalyst_voices_packages/catalyst_cardano_serialization/analysis_options.yaml new file mode 100644 index 0000000000..886855b51a --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:catalyst_analysis/analysis_options.1.0.0.yaml + +analyzer: + exclude: [build/**, lib/*.g.dart, lib/generated/**] diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/lib/catalyst_cardano_serialization.dart b/catalyst_voices_packages/catalyst_cardano_serialization/lib/catalyst_cardano_serialization.dart new file mode 100644 index 0000000000..bf48afc09d --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/lib/catalyst_cardano_serialization.dart @@ -0,0 +1,7 @@ +export 'src/address.dart'; +export 'src/exceptions.dart'; +export 'src/fees.dart'; +export 'src/hashes.dart'; +export 'src/transaction.dart'; +export 'src/types.dart'; +export 'src/witness.dart'; diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/address.dart b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/address.dart new file mode 100644 index 0000000000..a0aefa1477 --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/address.dart @@ -0,0 +1,128 @@ +// Copyright 2021 Richard Easterling +// SPDX-License-Identifier: Apache-2.0 + +// ignore_for_file: avoid_equals_and_hash_code_on_mutable_classes + +import 'package:bip32_ed25519/bip32_ed25519.dart'; +import 'package:catalyst_cardano_serialization/src/exceptions.dart'; +import 'package:catalyst_cardano_serialization/src/types.dart'; +import 'package:cbor/cbor.dart'; + +/// [ShelleyAddress] supports bech32 encoded addresses as defined in CIP19. +class ShelleyAddress { + /// The prefix of a base address. + static const String defaultAddrHrp = 'addr'; + + /// The prefix of a stake/reward address. + static const String defaultRewardHrp = 'stake'; + + /// The hrp suffix of an address on testnet network. + static const String testnetHrpSuffix = '_test'; + + static const Bech32Encoder _mainNetEncoder = + Bech32Encoder(hrp: defaultAddrHrp); + static const Bech32Encoder _testNetEncoder = + Bech32Encoder(hrp: defaultAddrHrp + testnetHrpSuffix); + static const Bech32Encoder _mainNetRewardEncoder = + Bech32Encoder(hrp: defaultRewardHrp); + static const Bech32Encoder _testNetRewardEncoder = + Bech32Encoder(hrp: defaultRewardHrp + testnetHrpSuffix); + + /// Raw bytes of address. + /// Format [ 8 bit header | payload ] + final Uint8List bytes; + + /// The prefix specifying the address type and networkId. + final String hrp; + + /// The constructor for [ShelleyAddress] from raw [bytes] and [hrp]. + ShelleyAddress(List bytes, {this.hrp = defaultAddrHrp}) + : bytes = Uint8List.fromList(bytes); + + /// The constructor which parses the address from bech32 format. + factory ShelleyAddress.fromBech32(String address) { + final hrp = _hrpPrefix(address); + if (hrp.isEmpty) { + throw InvalidAddressException( + 'not a valid Bech32 address - no prefix: $address', + ); + } + + switch (hrp) { + case defaultAddrHrp: + return ShelleyAddress(_mainNetEncoder.decode(address), hrp: hrp); + case const (defaultAddrHrp + testnetHrpSuffix): + return ShelleyAddress(_testNetEncoder.decode(address), hrp: hrp); + case defaultRewardHrp: + return ShelleyAddress(_mainNetRewardEncoder.decode(address), hrp: hrp); + case const (defaultRewardHrp + testnetHrpSuffix): + return ShelleyAddress(_testNetRewardEncoder.decode(address), hrp: hrp); + default: + return ShelleyAddress( + Bech32Encoder(hrp: hrp).decode(address), + hrp: hrp, + ); + } + } + + /// Returns the [NetworkId] related to this address. + NetworkId get network => NetworkId.testnet.id == (bytes[0] & 0x0f) + ? NetworkId.testnet + : NetworkId.mainnet; + + /// Encodes the address in bech32 format. + String toBech32() { + final prefix = _computeHrp(network, hrp); + switch (prefix) { + case defaultAddrHrp: + return _mainNetEncoder.encode(bytes); + case const (defaultAddrHrp + testnetHrpSuffix): + return _testNetEncoder.encode(bytes); + case defaultRewardHrp: + return _mainNetRewardEncoder.encode(bytes); + case const (defaultRewardHrp + testnetHrpSuffix): + return _testNetRewardEncoder.encode(bytes); + default: + return Bech32Encoder(hrp: prefix).encode(bytes); + } + } + + /// Serializes the type as cbor. + CborValue toCbor() => CborBytes(bytes); + + @override + int get hashCode => Object.hash(bytes, hrp); + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + if (other is! ShelleyAddress) return false; + if (bytes.length != other.bytes.length) return false; + if (hrp != other.hrp) return false; + + for (var i = 0; i < bytes.length; i++) { + if (bytes[i] != other.bytes[i]) return false; + } + return true; + } + + @override + String toString() => toBech32(); + + /// If were using the testnet, make sure the hrp ends with '_test' + static String _computeHrp(NetworkId id, String prefix) { + if (id == NetworkId.mainnet) { + return prefix; + } else if (prefix.endsWith(testnetHrpSuffix)) { + return prefix; + } else { + return prefix + testnetHrpSuffix; + } + } + + static String _hrpPrefix(String addr) { + final s = addr.trim(); + final i = s.indexOf('1'); + return s.substring(0, i > 0 ? i : 0); + } +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/exceptions.dart b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/exceptions.dart new file mode 100644 index 0000000000..ba6eb0c25a --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/exceptions.dart @@ -0,0 +1,90 @@ +import 'package:catalyst_cardano_serialization/src/types.dart'; + +/// Exception thrown when the transaction exceeds the allowed maximum size. +final class MaxTxSizeExceededException implements Exception { + /// The maximum amount of bytes per transaction. + final int maxTxSize; + + /// The amount of bytes of transaction that exceeded it's maximum size. + final int actualTxSize; + + /// The default constructor for [MaxTxSizeExceededException]. + const MaxTxSizeExceededException({ + required this.maxTxSize, + required this.actualTxSize, + }); + + @override + String toString() => 'MaxTxSizeExceededException(' + 'maxTxSize:$maxTxSize' + ', actualTxSize:$actualTxSize' + ')'; +} + +/// Exception thrown when the transaction outputs exceed the inputs. +final class InsufficientUtxoBalanceException implements Exception { + /// The amount of [Coin] that user has. + final Coin actualAmount; + + /// The amount of [Coin] that user wants to spend. + final Coin requiredAmount; + + /// The default constructor for [InsufficientUtxoBalanceException]. + const InsufficientUtxoBalanceException({ + required this.actualAmount, + required this.requiredAmount, + }); + + @override + String toString() => 'InsufficientUtxoBalanceException(' + 'actualAmount:$actualAmount' + ', requiredAmount:$requiredAmount' + ')'; +} + +/// Exception thrown when building a transaction that doesn't specify the fee. +final class TxFeeNotSpecifiedException implements Exception { + /// The default constructor for [TxFeeNotSpecifiedException]. + const TxFeeNotSpecifiedException(); + + @override + String toString() => 'TxFeeNotSpecifiedException'; +} + +/// Exception thrown when parsing a hash that has incorrect length. +final class HashFormatException implements Exception { + /// The default constructor for [HashFormatException]. + const HashFormatException(); + + @override + String toString() => 'HashFormatException'; +} + +/// Exception thrown if the address doesn't match the bech32 specification +/// for Shelley addresses. +final class InvalidAddressException implements Exception { + /// Exception details. + final String message; + + /// Default constructor [InvalidAddressException]. + const InvalidAddressException(this.message); + + @override + String toString() => 'InvalidAddressException: $message'; +} + +/// Exception thrown when the number of witnesses doesn't match +/// the expected amount. +/// +/// When calculating the fee for the transaction the amount of witnesses +/// needs to be specified since they affect the transaction bytes length. +/// +/// Thus less or more witnesses than were included when calculating +/// the fee are not allowed. +final class InvalidTransactionWitnessesException implements Exception { + /// The default constructor for [InvalidTransactionWitnessesException]. + const InvalidTransactionWitnessesException(); + + @override + String toString() => 'InvalidTransactionWitnessesException'; +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/fees.dart b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/fees.dart new file mode 100644 index 0000000000..a47471798c --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/fees.dart @@ -0,0 +1,30 @@ +import 'package:catalyst_cardano_serialization/src/transaction.dart'; +import 'package:catalyst_cardano_serialization/src/types.dart'; +import 'package:cbor/cbor.dart'; + +/// Calculates fees for the transaction on Cardano blockchain. +/// +/// The fee is calculated using the following formula: +/// - `fee = constant + tx.bytes.len * coefficient` +final class LinearFee { + /// The constant amount of [Coin] that is charged per transaction. + final Coin constant; + + /// The amount of [Coin] per transaction byte that is charged per transaction. + final Coin coefficient; + + /// The default constructor for the [LinearFee]. + /// The parameters are Cardano protocol parameters. + const LinearFee({ + required this.constant, + required this.coefficient, + }); + + /// Calculates the fee for the transaction denominated in lovelaces. + /// + /// The formula doesn't take into account smart contract scripts. + Coin minNoScriptFee(Transaction tx) { + final bytesCount = cbor.encode(tx.toCbor()).length; + return Coin(bytesCount) * coefficient + constant; + } +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/hashes.dart b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/hashes.dart new file mode 100644 index 0000000000..e499cbc87b --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/hashes.dart @@ -0,0 +1,110 @@ +// ignore_for_file: avoid_equals_and_hash_code_on_mutable_classes + +import 'dart:typed_data'; + +import 'package:catalyst_cardano_serialization/src/exceptions.dart'; +import 'package:catalyst_cardano_serialization/src/transaction.dart'; +import 'package:cbor/cbor.dart'; +import 'package:convert/convert.dart'; +import 'package:pinenacl/digests.dart'; + +/// Implements a common base of hash types that holds +/// binary [bytes] of exact [length]. +abstract base class BaseHash { + /// The raw [bytes] of a hash. + final List bytes; + + /// Constructs the [BaseHash] from raw [bytes]. + BaseHash.fromBytes({required this.bytes}) { + if (bytes.length != length) { + throw const HashFormatException(); + } + } + + /// Constructs the [BaseHash] from a hex string representation + /// of [bytes]. + BaseHash.fromHex(String string) : this.fromBytes(bytes: hex.decode(string)); + + /// The expected length of the transaction hash bytes. + int get length; + + /// Serializes the type as cbor. + CborValue toCbor() => CborBytes(bytes); + + /// Returns the hex string representation of [bytes]. + String toHex() => hex.encode(bytes); + + @override + String toString() => toHex(); + + @override + int get hashCode => Object.hash(bytes, length); + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + if (other is! BaseHash) return false; + + // prevent subclasses of different types to be equal to each other, + // even if they hold the same bytes they represent different kinds + if (other.runtimeType != runtimeType) return false; + + if (length != other.length) return false; + + for (var i = 0; i < bytes.length; i++) { + if (bytes[i] != other.bytes[i]) return false; + } + + return true; + } +} + +/// Describes the hash of the transaction which serves as proof +/// of transaction validation. +final class TransactionHash extends BaseHash { + static const int _length = 32; + + /// Constructs the [TransactionHash] from raw [bytes]. + TransactionHash.fromBytes({required super.bytes}) : super.fromBytes(); + + /// Constructs the [TransactionHash] from a hex string representation + /// of [bytes]. + TransactionHash.fromHex(super.string) : super.fromHex(); + + /// Constructs the [TransactionHash] from a [TransactionBody]. + TransactionHash.fromTransactionBody(TransactionBody body) + : super.fromBytes( + bytes: Hash.blake2b( + Uint8List.fromList(cbor.encode(body.toCbor())), + digestSize: _length, + ), + ); + + @override + int get length => _length; +} + +/// Describes the hash of auxiliary data which is included +/// in the transaction body. +final class AuxiliaryDataHash extends BaseHash { + static const int _length = 32; + + /// Constructs the [AuxiliaryDataHash] from raw [bytes]. + AuxiliaryDataHash.fromBytes({required super.bytes}) : super.fromBytes(); + + /// Constructs the [AuxiliaryDataHash] from a hex string representation + /// of [bytes]. + AuxiliaryDataHash.fromHex(super.string) : super.fromHex(); + + /// Constructs the [AuxiliaryDataHash] from a [AuxiliaryData]. + AuxiliaryDataHash.fromAuxiliaryData(AuxiliaryData data) + : super.fromBytes( + bytes: Hash.blake2b( + Uint8List.fromList(cbor.encode(data.toCbor())), + digestSize: _length, + ), + ); + + @override + int get length => _length; +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/transaction.dart b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/transaction.dart new file mode 100644 index 0000000000..5b26b34d08 --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/transaction.dart @@ -0,0 +1,178 @@ +import 'package:catalyst_cardano_serialization/src/address.dart'; +import 'package:catalyst_cardano_serialization/src/hashes.dart'; +import 'package:catalyst_cardano_serialization/src/types.dart'; +import 'package:catalyst_cardano_serialization/src/utils/cbor.dart'; +import 'package:catalyst_cardano_serialization/src/witness.dart'; +import 'package:cbor/cbor.dart'; + +/// Represents the signed transaction with a list of witnesses +/// which are used to verify the validity of a transaction. +final class Transaction { + /// The transaction body containing the inputs, outputs, fees, etc. + final TransactionBody body; + + /// The set of witnesses that have signed given transaction. + final TransactionWitnessSet witnessSet; + + /// True if the transaction is valid, false otherwise. + final bool isValid; + + /// The optional transaction metadata. + final AuxiliaryData? auxiliaryData; + + /// The default constructor for the [Transaction]. + const Transaction({ + required this.body, + required this.isValid, + required this.witnessSet, + this.auxiliaryData, + }); + + /// Serializes the type as cbor. + CborValue toCbor() { + return CborList([ + body.toCbor(), + witnessSet.toCbor(), + CborBool(isValid), + (auxiliaryData ?? const AuxiliaryData()).toCbor(), + ]); + } +} + +/// Represents the details of a transaction including inputs, outputs, fee, etc. +/// +/// Does not contain the witnesses which are used to verify the transaction. +final class TransactionBody { + /// The transaction inputs. + final Set inputs; + + /// The transaction outputs. + final List outputs; + + /// The fee for the transaction. + final Coin fee; + + /// The absolute slot value before the tx becomes invalid. + final SlotBigNum? ttl; + + /// The hash of the optional [AuxiliaryData] + /// which is the metadata of the transaction. + final AuxiliaryDataHash? auxiliaryDataHash; + + /// Specifies on which network the code will run. + final NetworkId? networkId; + + /// The default constructor for [TransactionBody]. + const TransactionBody({ + required this.inputs, + required this.outputs, + required this.fee, + this.ttl, + this.auxiliaryDataHash, + this.networkId, + }); + + /// Serializes the type as cbor. + CborValue toCbor() { + return CborMap({ + const CborSmallInt(0): CborList([ + for (final input in inputs) input.toCbor(), + ]), + const CborSmallInt(1): CborList([ + for (final output in outputs) output.toCbor(), + ]), + const CborSmallInt(2): fee.toCbor(), + if (ttl != null) const CborSmallInt(3): ttl!.toCbor(), + }); + } +} + +/// The transaction output of a previous transaction, +/// acts as input for the next transaction. +final class TransactionInput { + /// The hash of the given transaction. + final TransactionHash transactionId; + + /// The index of the utxo in the given transaction. + final int index; + + /// The default constructor for [TransactionInput]. + const TransactionInput({ + required this.transactionId, + required this.index, + }); + + /// Serializes the type as cbor. + CborValue toCbor() { + return CborList([ + transactionId.toCbor(), + CborSmallInt(index), + ]); + } +} + +/// The transaction output which assigns the owner of given address +/// with leftover change from previous transaction. +final class TransactionOutput { + /// The address associated with the transaction. + final ShelleyAddress address; + + /// The leftover change from the previous transaction that can be spent. + final Coin amount; + + /// The default constructor for the [TransactionOutput]. + const TransactionOutput({ + required this.address, + required this.amount, + }); + + /// Serializes the type as cbor. + CborValue toCbor() { + return CborList([ + address.toCbor(), + amount.toCbor(), + ]); + } +} + +/// The UTXO that can be used as an input in a new transaction. +final class TransactionUnspentOutput { + /// The transaction output of a previous transaction, + /// acts as input for the next transaction. + final TransactionInput input; + + /// The transaction output which assigns the owner of given address + /// with leftover change from previous transaction. + final TransactionOutput output; + + /// The default constructor for [TransactionUnspentOutput]. + const TransactionUnspentOutput({ + required this.input, + required this.output, + }); + + /// Serializes the type as cbor. + CborValue toCbor() { + return CborList([ + input.toCbor(), + output.toCbor(), + ]); + } +} + +/// The transaction metadata as a list of key-value pairs (a map). +final class AuxiliaryData { + /// The transaction metadata map. + final Map map; + + /// The default constructor for the [AuxiliaryData]. + const AuxiliaryData({this.map = const {}}); + + /// Serializes the type as cbor. + CborValue toCbor() { + return CborMap( + map, + tags: map.isNotEmpty ? const [] : [CborCustomTags.map], + ); + } +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/types.dart b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/types.dart new file mode 100644 index 0000000000..addf9f731c --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/types.dart @@ -0,0 +1,52 @@ +import 'package:cbor/cbor.dart'; + +/// Specifies on which network the code will run. +enum NetworkId { + /// The production network + mainnet(id: 1), + + /// The test network. + testnet(id: 0); + + /// The magic protocol number acting as the identifier of the network. + final int id; + + const NetworkId({required this.id}); +} + +/// Specifies an amount of ADA in terms of lovelace. +extension type const Coin(int value) { + /// Adds [other] value to this value and returns a new [Coin]. + Coin operator +(Coin other) => Coin(value + other.value); + + /// Subtracts [other] values from this value and returns a new [Coin]. + Coin operator -(Coin other) => Coin(value - other.value); + + /// Multiplies this value by [other] values and returns a new [Coin]. + Coin operator *(Coin other) => Coin(value * other.value); + + /// Divides this value by [other] value without remainder + /// and returns a new [Coin]. + Coin operator ~/(Coin other) => Coin(value ~/ other.value); + + /// Returns true if [value] is greater than [other] value. + bool operator >(Coin other) => value > other.value; + + /// Returns true if [value] is greater than or equal [other] value. + bool operator >=(Coin other) => value > other.value || value == other.value; + + /// Returns true if [value] is smaller than [other] value. + bool operator <(Coin other) => value < other.value; + + /// Returns true if [value] is smaller than or equal [other] value. + bool operator <=(Coin other) => value < other.value || value == other.value; + + /// Serializes the type as cbor. + CborValue toCbor() => CborSmallInt(value); +} + +/// A blockchain slot number. +extension type const SlotBigNum(int value) { + /// Serializes the type as cbor. + CborValue toCbor() => CborSmallInt(value); +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/utils/cbor.dart b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/utils/cbor.dart new file mode 100644 index 0000000000..6ce64d2ee1 --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/utils/cbor.dart @@ -0,0 +1,48 @@ +/// Holds cbor tags not specified by the official cbor package. +final class CborCustomTags { + const CborCustomTags._(); + + /// A cbor tag describing a key-value pairs data. + static const int map = 259; +} + +/// How many bytes are used in cbor encoding for a major type/length. +enum CborSize { + /// Length/data is encoded inside of the type information. + inline(bytes: 0), + + /// Length/data is in 1 byte following the type information. + one(bytes: 1), + + /// Length/data is in 2 bytes following the type information. + two(bytes: 2), + + /// Length/data is in 4 bytes following the type information. + four(bytes: 4), + + /// Length/data is in 8 bytes following the type information. + eight(bytes: 8); + + /// The amount of bytes it takes to encode the type in cbor. + final int bytes; + + const CborSize({required this.bytes}); + + /// The max int value that can be inlined in cbor without extra bytes. + static const int maxInlineEncoding = 23; + + /// Calculates the [CborSize] for arbitrary [value]. + static CborSize ofInt(int value) { + if (value <= maxInlineEncoding) { + return CborSize.inline; + } else if (value < 0x100) { + return CborSize.one; + } else if (value < 0x10000) { + return CborSize.two; + } else if (value < 0x100000000) { + return CborSize.four; + } else { + return CborSize.eight; + } + } +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/witness.dart b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/witness.dart new file mode 100644 index 0000000000..7ad376805f --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/lib/src/witness.dart @@ -0,0 +1,93 @@ +import 'package:cbor/cbor.dart'; + +/// A set of witnesses that sign the transaction. +class TransactionWitnessSet { + /// The witnesses that sign the transaction. + final Set vkeyWitnesses; + + /// The default constructor for [TransactionWitnessSet]. + const TransactionWitnessSet({required this.vkeyWitnesses}); + + /// Serializes the type as cbor. + CborValue toCbor() { + return CborMap({ + for (final vkey in vkeyWitnesses.indexed) + CborSmallInt(vkey.$1): vkey.$2.toCbor(), + }); + } +} + +/// The transaction witness with a [signature] of the transaction. +class VkeyWitness { + /// The public key of the witness. + final Vkey vkey; + + /// The witness signature of the transaction. + final Ed25519Signature signature; + + /// The default constructor for [VkeyWitness]. + const VkeyWitness({ + required this.vkey, + required this.signature, + }); + + /// Builds a fake [VkeyWitness] that helps to measure target transaction + /// size when the transaction hasn't been signed yet. + factory VkeyWitness.seeded(int byte) { + return VkeyWitness( + vkey: Vkey.seeded(byte), + signature: Ed25519Signature.seeded(byte), + ); + } + + /// Serializes the type as cbor. + CborValue toCbor() { + return CborList([ + vkey.toCbor(), + signature.toCbor(), + ]); + } +} + +/// The public key of the witness. +extension type Vkey._(List bytes) { + /// The length of the [Vkey]. + static const int length = 32; + + /// The default constructor for [Vkey]. + Vkey.fromBytes(this.bytes) { + if (bytes.length != length) { + throw ArgumentError('Vkey length does not match: ${bytes.length}'); + } + } + + /// Returns the [Vkey] filled with [byte] that can be + /// used to reserve size to calculate the final transaction bytes size. + factory Vkey.seeded(int byte) => Vkey.fromBytes(List.filled(length, byte)); + + /// Serializes the type as cbor. + CborValue toCbor() => CborBytes(bytes); +} + +/// The witness signature of the transaction. +extension type Ed25519Signature._(List bytes) { + /// The length of the [Ed25519Signature]. + static const int length = 64; + + /// The default constructor for [Ed25519Signature]. + Ed25519Signature.fromBytes(this.bytes) { + if (bytes.length != length) { + throw ArgumentError( + 'Ed25519Signature length does not match: ${bytes.length}', + ); + } + } + + /// Returns the [Ed25519Signature] filled with [byte] that can be + /// used to reserve size to calculate the final transaction bytes size. + factory Ed25519Signature.seeded(int byte) => + Ed25519Signature.fromBytes(List.filled(length, byte)); + + /// Serializes the type as cbor. + CborValue toCbor() => CborBytes(bytes); +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/pubspec.yaml b/catalyst_voices_packages/catalyst_cardano_serialization/pubspec.yaml new file mode 100644 index 0000000000..c6c0c143b1 --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/pubspec.yaml @@ -0,0 +1,21 @@ +name: catalyst_cardano_serialization +description: Dart package providing serialization/deserialization for common structures for Cardano blockchain. +repository: https://github.com/input-output-hk/catalyst-voices/tree/main/catalyst_voices_packages/catalyst_cardano_serialization +issue_tracker: https://github.com/input-output-hk/catalyst-voices/issues +topics: [blockchain, cardano, cryptocurrency, wallet] +version: 0.1.0 + +environment: + sdk: ">=3.3.0 <4.0.0" + +dependencies: + bech32: ^0.2.2 + bip32_ed25519: ^0.5.0 + cbor: ^6.2.0 + convert: ^3.1.1 + pinenacl: ^0.5.1 + +dev_dependencies: + catalyst_analysis: + path: ../catalyst_analysis + test: ^1.24.9 diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/test/address_test.dart b/catalyst_voices_packages/catalyst_cardano_serialization/test/address_test.dart new file mode 100644 index 0000000000..4775dd82ce --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/test/address_test.dart @@ -0,0 +1,74 @@ +import 'package:catalyst_cardano_serialization/src/address.dart'; +import 'package:catalyst_cardano_serialization/src/types.dart'; +import 'package:test/test.dart'; + +import 'test_utils/test_data.dart'; + +void main() { + group(ShelleyAddress, () { + test('round-trip conversion from and to bytes', () { + expect( + ShelleyAddress(mainnetAddr.bytes, hrp: mainnetAddr.hrp), + equals(mainnetAddr), + ); + + expect( + ShelleyAddress(testnetAddr.bytes, hrp: testnetAddr.hrp), + equals(testnetAddr), + ); + + expect( + ShelleyAddress(mainnetStakeAddr.bytes, hrp: mainnetStakeAddr.hrp), + equals(mainnetStakeAddr), + ); + + expect( + ShelleyAddress(testnetStakeAddr.bytes, hrp: testnetStakeAddr.hrp), + equals(testnetStakeAddr), + ); + }); + + test('round-trip conversion from and to bech32', () { + expect( + ShelleyAddress.fromBech32(mainnetAddr.toBech32()), + equals(mainnetAddr), + ); + + expect( + ShelleyAddress.fromBech32(testnetAddr.toBech32()), + equals(testnetAddr), + ); + + expect( + ShelleyAddress.fromBech32(mainnetStakeAddr.toBech32()), + equals(mainnetStakeAddr), + ); + + expect( + ShelleyAddress.fromBech32(testnetStakeAddr.toBech32()), + equals(testnetStakeAddr), + ); + }); + + test('hrp from address', () { + expect(mainnetAddr.hrp, equals('addr')); + expect(testnetAddr.hrp, equals('addr_test')); + expect(mainnetStakeAddr.hrp, equals('stake')); + expect(testnetStakeAddr.hrp, equals('stake_test')); + }); + + test('network ID from address', () { + expect(mainnetAddr.network, equals(NetworkId.mainnet)); + expect(testnetAddr.network, equals(NetworkId.testnet)); + expect(mainnetStakeAddr.network, equals(NetworkId.mainnet)); + expect(testnetStakeAddr.network, equals(NetworkId.testnet)); + }); + + test('toString returns bech32', () { + expect(mainnetAddr.toString(), equals(mainnetAddr.toBech32())); + expect(testnetAddr.toString(), equals(testnetAddr.toBech32())); + expect(mainnetStakeAddr.toString(), equals(mainnetStakeAddr.toBech32())); + expect(testnetStakeAddr.toString(), equals(testnetStakeAddr.toBech32())); + }); + }); +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/test/fees_test.dart b/catalyst_voices_packages/catalyst_cardano_serialization/test/fees_test.dart new file mode 100644 index 0000000000..82482ec4b5 --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/test/fees_test.dart @@ -0,0 +1,39 @@ +import 'package:catalyst_cardano_serialization/src/fees.dart'; +import 'package:catalyst_cardano_serialization/src/types.dart'; +import 'package:test/test.dart'; + +import 'test_utils/test_data.dart'; + +void main() { + group(LinearFee, () { + test('minFeeNoScript with current protocol params', () { + const linearFee = LinearFee( + constant: Coin(155381), + coefficient: Coin(44), + ); + + final tx = fullTestTransaction(); + expect(linearFee.minNoScriptFee(tx), equals(159693)); + }); + + test('minFeeNoScript with constant fee only', () { + const linearFee = LinearFee( + constant: Coin(155381), + coefficient: Coin(0), + ); + + final tx = fullTestTransaction(); + expect(linearFee.minNoScriptFee(tx), equals(linearFee.constant)); + }); + + test('minFeeNoScript with coefficient fee only', () { + const linearFee = LinearFee( + constant: Coin(0), + coefficient: Coin(44), + ); + + final tx = fullTestTransaction(); + expect(linearFee.minNoScriptFee(tx), equals(4312)); + }); + }); +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/test/hashes_test.dart b/catalyst_voices_packages/catalyst_cardano_serialization/test/hashes_test.dart new file mode 100644 index 0000000000..d68b88516b --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/test/hashes_test.dart @@ -0,0 +1,92 @@ +import 'package:catalyst_cardano_serialization/src/hashes.dart'; +import 'package:catalyst_cardano_serialization/src/transaction.dart'; +import 'package:catalyst_cardano_serialization/src/types.dart'; +import 'package:cbor/cbor.dart'; +import 'package:convert/convert.dart'; +import 'package:test/test.dart'; + +void main() { + group(TransactionHash, () { + const hexString = + '4d3f576f26db29139981a69443c2325daa812cc353a31b5a4db794a5bcbb06c2'; + final bytes = hex.decode(hexString); + + test('from and to hex', () { + final hash = TransactionHash.fromHex(hexString); + expect(hash.toHex(), equals(hexString)); + }); + + test('from and to bytes', () { + final hash = TransactionHash.fromBytes(bytes: bytes); + expect(hash.bytes, equals(bytes)); + }); + + test('from transaction body', () { + const body = TransactionBody( + inputs: {}, + outputs: [], + fee: Coin(0), + ); + + final hash = TransactionHash.fromTransactionBody(body); + expect( + hash, + equals( + TransactionHash.fromHex( + '36fdff68dfe3660f1ceea60f018a0fd7a83da13def229108794c397a879b0436', + ), + ), + ); + }); + + test('toCbor returns bytes', () { + final hash = TransactionHash.fromBytes(bytes: bytes); + final encodedCbor = cbor.encode(hash.toCbor()); + final decodedCbor = cbor.decode(encodedCbor); + expect(decodedCbor, isA()); + expect((decodedCbor as CborBytes).bytes, equals(bytes)); + }); + }); + + group(AuxiliaryDataHash, () { + const hexString = + '4d3f576f26db29139981a69443c2325daa812cc353a31b5a4db794a5bcbb06c2'; + final bytes = hex.decode(hexString); + + test('from and to hex', () { + final hash = AuxiliaryDataHash.fromHex(hexString); + expect(hash.toHex(), equals(hexString)); + }); + + test('from and to bytes', () { + final hash = AuxiliaryDataHash.fromBytes(bytes: bytes); + expect(hash.bytes, equals(bytes)); + }); + + test('from auxiliary data', () { + final data = AuxiliaryData( + map: { + const CborSmallInt(1): CborString('Test'), + }, + ); + + final hash = AuxiliaryDataHash.fromAuxiliaryData(data); + expect( + hash, + equals( + AuxiliaryDataHash.fromHex( + '568d2b7d4052f6ce9f2c60b942b10da9d19e60c8bf24b17aa7bcfb3caffcc1ea', + ), + ), + ); + }); + + test('toCbor returns bytes', () { + final hash = AuxiliaryDataHash.fromBytes(bytes: bytes); + final encodedCbor = cbor.encode(hash.toCbor()); + final decodedCbor = cbor.decode(encodedCbor); + expect(decodedCbor, isA()); + expect((decodedCbor as CborBytes).bytes, equals(bytes)); + }); + }); +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/test/test_utils/test_data.dart b/catalyst_voices_packages/catalyst_cardano_serialization/test/test_utils/test_data.dart new file mode 100644 index 0000000000..44e148c686 --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/test/test_utils/test_data.dart @@ -0,0 +1,87 @@ +import 'package:catalyst_cardano_serialization/src/address.dart'; +import 'package:catalyst_cardano_serialization/src/hashes.dart'; +import 'package:catalyst_cardano_serialization/src/transaction.dart'; +import 'package:catalyst_cardano_serialization/src/types.dart'; +import 'package:catalyst_cardano_serialization/src/witness.dart'; +import 'package:cbor/cbor.dart'; + +/* cSpell:disable */ +final mainnetAddr = ShelleyAddress.fromBech32( + 'addr1qx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3n0d3vllmyqws' + 'x5wktcd8cc3sq835lu7drv2xwl2wywfgse35a3x', +); +final testnetAddr = ShelleyAddress.fromBech32( + 'addr_test1vz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzerspjrlsz', +); +final mainnetStakeAddr = ShelleyAddress.fromBech32( + 'stake1uyehkck0lajq8gr28t9uxnuvgcqrc6070x3k9r8048z8y5gh6ffgw', +); +final testnetStakeAddr = ShelleyAddress.fromBech32( + 'stake_test1uqehkck0lajq8gr28t9uxnuvgcqrc6070x3k9r8048z8y5gssrtvn', +); + +final testTransactionHash = TransactionHash.fromHex( + '583a3a5150bc7990656020ffb4e5a1be' + '1589ce6f1a430aacb8e7e089b894d3d1', +); + +/// Returns a minimal transaction with optional fields skipped. +Transaction minimalTestTransaction() { + return Transaction( + body: TransactionBody( + inputs: { + TransactionInput( + transactionId: testTransactionHash, + index: 1, + ), + }, + outputs: [ + TransactionOutput( + address: testnetAddr, + amount: const Coin(5000000), + ), + ], + fee: const Coin(10000000), + ), + isValid: true, + witnessSet: const TransactionWitnessSet(vkeyWitnesses: {}), + ); +} + +/// Returns a full transaction with all possible optional fields. +Transaction fullTestTransaction() { + final auxiliaryData = AuxiliaryData( + map: { + const CborSmallInt(1): CborString('Test'), + }, + ); + + return Transaction( + body: TransactionBody( + inputs: { + TransactionInput( + transactionId: testTransactionHash, + index: 1, + ), + }, + outputs: [ + TransactionOutput( + address: testnetAddr, + amount: const Coin(5000000), + ), + ], + fee: const Coin(10000000), + ttl: const SlotBigNum(41001), + auxiliaryDataHash: AuxiliaryDataHash.fromAuxiliaryData(auxiliaryData), + networkId: NetworkId.testnet, + ), + isValid: true, + // TODO(dtscalac): provide witness + witnessSet: const TransactionWitnessSet( + vkeyWitnesses: {}, + ), + auxiliaryData: auxiliaryData, + ); +} + +/* cSpell:enable */ diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/test/transaction_test.dart b/catalyst_voices_packages/catalyst_cardano_serialization/test/transaction_test.dart new file mode 100644 index 0000000000..52d8f88084 --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/test/transaction_test.dart @@ -0,0 +1,38 @@ +import 'package:catalyst_cardano_serialization/src/transaction.dart'; +import 'package:cbor/cbor.dart'; +import 'package:convert/convert.dart'; +import 'package:test/test.dart'; + +import 'test_utils/test_data.dart'; + +void main() { + group(Transaction, () { + test('transaction with all supported fields serialized to bytes', () { + final bytes = cbor.encode(fullTestTransaction().toCbor()); + final hexString = hex.encode(bytes); + + expect( + hexString, + equals( + '84a40081825820583a3a5150bc7990656020ffb4e5a1be1589ce6f1a430aacb8e7e0' + '89b894d3d101018182581d609493315cd92eb5d8c4304e67b7e16ae36d61d3450269' + '4657811a2c8e1a004c4b40021a009896800319a029a0f5a1016454657374', + ), + ); + }); + + test('transaction with required fields serialized to bytes', () { + final bytes = cbor.encode(minimalTestTransaction().toCbor()); + final hexString = hex.encode(bytes); + + expect( + hexString, + equals( + '84a30081825820583a3a5150bc7990656020ffb4e5a1be1589ce6f1a430aacb8e7e0' + '89b894d3d101018182581d609493315cd92eb5d8c4304e67b7e16ae36d61d3450269' + '4657811a2c8e1a004c4b40021a00989680a0f5d90103a0', + ), + ); + }); + }); +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/test/types_test.dart b/catalyst_voices_packages/catalyst_cardano_serialization/test/types_test.dart new file mode 100644 index 0000000000..7aeeaf13a4 --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/test/types_test.dart @@ -0,0 +1,33 @@ +import 'package:catalyst_cardano_serialization/src/types.dart'; +import 'package:test/test.dart'; + +void main() { + group(Coin, () { + test('addition', () { + expect(const Coin(3) + const Coin(100), equals(const Coin(103))); + expect(const Coin(-100) + const Coin(100), equals(const Coin(0))); + }); + + test('subtraction', () { + expect(const Coin(5) - const Coin(2), equals(const Coin(3))); + expect(const Coin(10) - const Coin(27), equals(const Coin(-17))); + }); + + test('multiplication', () { + expect(const Coin(3) * const Coin(6), equals(const Coin(18))); + expect(const Coin(-5) * const Coin(7), equals(const Coin(-35))); + }); + + test('division', () { + expect(const Coin(3) ~/ const Coin(2), equals(const Coin(1))); + expect(const Coin(100) ~/ const Coin(50), equals(const Coin(2))); + }); + + test('comparison', () { + expect(const Coin(3) > const Coin(2), isTrue); + expect(const Coin(3) >= const Coin(3), isTrue); + expect(const Coin(100) < const Coin(100), isFalse); + expect(const Coin(100) <= const Coin(100), isTrue); + }); + }); +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/test/utils/cbor_test.dart b/catalyst_voices_packages/catalyst_cardano_serialization/test/utils/cbor_test.dart new file mode 100644 index 0000000000..cadd24b03a --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/test/utils/cbor_test.dart @@ -0,0 +1,29 @@ +import 'package:catalyst_cardano_serialization/src/utils/cbor.dart'; +import 'package:test/test.dart'; + +void main() { + group(CborSize, () { + test('of int value', () { + expect(CborSize.ofInt(0), equals(CborSize.inline)); + expect( + CborSize.ofInt(CborSize.maxInlineEncoding), + equals(CborSize.inline), + ); + expect(CborSize.ofInt(0xff), equals(CborSize.one)); + expect(CborSize.ofInt(0x100), equals(CborSize.two)); + expect(CborSize.ofInt(0xffff), equals(CborSize.two)); + expect(CborSize.ofInt(0x10000), equals(CborSize.four)); + expect(CborSize.ofInt(0xffffffff), equals(CborSize.four)); + expect(CborSize.ofInt(0x100000000), equals(CborSize.eight)); + expect(CborSize.ofInt(0xfffffffffffff), equals(CborSize.eight)); + }); + + test('bytes length', () { + expect(CborSize.inline.bytes, equals(0)); + expect(CborSize.one.bytes, equals(1)); + expect(CborSize.two.bytes, equals(2)); + expect(CborSize.four.bytes, equals(4)); + expect(CborSize.eight.bytes, equals(8)); + }); + }); +} diff --git a/catalyst_voices_packages/catalyst_cardano_serialization/test/witness_test.dart b/catalyst_voices_packages/catalyst_cardano_serialization/test/witness_test.dart new file mode 100644 index 0000000000..ae9f5f0625 --- /dev/null +++ b/catalyst_voices_packages/catalyst_cardano_serialization/test/witness_test.dart @@ -0,0 +1,22 @@ +import 'package:catalyst_cardano_serialization/src/witness.dart'; +import 'package:test/test.dart'; + +void main() { + group(Vkey, () { + test('seeded has correct length', () { + expect( + Vkey.seeded(1).bytes.length, + equals(Vkey.length), + ); + }); + }); + + group(Ed25519Signature, () { + test('seeded has correct length', () { + expect( + Ed25519Signature.seeded(2).bytes.length, + equals(Ed25519Signature.length), + ); + }); + }); +} diff --git a/docs/Earthfile b/docs/Earthfile index 436b628f43..6e10e0ab3c 100644 --- a/docs/Earthfile +++ b/docs/Earthfile @@ -1,20 +1,25 @@ -# Set the Earthly version to 0.7 -VERSION 0.7 +VERSION 0.8 + +IMPORT github.com/input-output-hk/catalyst-ci/earthly/docs:v3.00.0 AS docs-ci + +IMPORT .. AS repo +IMPORT ../catalyst-gateway AS catalyst-gateway +IMPORT ../catalyst-gateway/event-db AS event-db # cspell: words mkdocs runable # Copy all the source we need to build the docs src: # Common src setup - DO github.com/input-output-hk/catalyst-ci/earthly/docs:v2.11.1+SRC + DO docs-ci+SRC # Now copy into that any artifacts we pull from the builds. - COPY --dir ../+repo-docs/repo /docs/includes + COPY --dir repo+repo-docs/repo /docs/includes # copy Rust docs - COPY ./../catalyst-gateway+build/doc /docs/src/api/cat-gateway/rust-docs + COPY catalyst-gateway+build/doc /docs/src/api/cat-gateway/rust-docs # Copy docs we build in the postgres example. - COPY --dir ../catalyst-gateway/event-db+build/docs src/architecture/08_concepts/event_db + COPY --dir event-db+build/docs src/architecture/08_concepts/event_db # Build the docs here. diff --git a/melos.yaml b/melos.yaml index 21730e065a..f930ba47bd 100644 --- a/melos.yaml +++ b/melos.yaml @@ -24,6 +24,11 @@ command: meta: ^1.10.0 result_type: ^0.2.0 plugin_platform_interface: ^2.1.7 + bech32: ^0.2.2 + bip32_ed25519: ^0.5.0 + cbor: ^6.2.0 + convert: ^3.1.1 + pinenacl: ^0.5.1 dev_dependencies: test: ^1.24.9 build_runner: ^2.3.3 diff --git a/utilities/wallet-tester/Earthfile b/utilities/wallet-tester/Earthfile index 0926786d82..1eb1dd76ac 100644 --- a/utilities/wallet-tester/Earthfile +++ b/utilities/wallet-tester/Earthfile @@ -1,4 +1,4 @@ -VERSION --try --global-cache 0.7 +VERSION 0.8 # builder - Installs node packages. builder: