diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index 0101f95..b70bd85 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -38,7 +38,7 @@ jobs: - name: Install latest nightly uses: actions-rs/toolchain@v1 with: - toolchain: nightly-2022-12-11 + toolchain: 1.71.0 override: true components: rustfmt, clippy diff --git a/.gitignore b/.gitignore index 1bbc4c4..d6c7de5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /target/ .env.local keypair.json -.vscode \ No newline at end of file +.vscode diff --git a/Cargo.lock b/Cargo.lock index 78ff428..aecea8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8f9420f797f2d9e935edf629310eb938a0d839f984e25327f3c7eed22300c" +checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0" dependencies = [ "memchr", ] @@ -88,24 +88,23 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" [[package]] name = "anstyle-parse" @@ -127,9 +126,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", "windows-sys", @@ -137,136 +136,13 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.72" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" dependencies = [ "backtrace", ] -[[package]] -name = "ark-bn254" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" -dependencies = [ - "ark-ec", - "ark-ff", - "ark-std", -] - -[[package]] -name = "ark-ec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" -dependencies = [ - "ark-ff", - "ark-poly", - "ark-serialize", - "ark-std", - "derivative", - "hashbrown 0.13.2", - "itertools", - "num-traits", - "zeroize", -] - -[[package]] -name = "ark-ff" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" -dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", - "derivative", - "digest 0.10.7", - "itertools", - "num-bigint", - "num-traits", - "paste", - "rustc_version", - "zeroize", -] - -[[package]] -name = "ark-ff-asm" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-macros" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" -dependencies = [ - "num-bigint", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-poly" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" -dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", - "derivative", - "hashbrown 0.13.2", -] - -[[package]] -name = "ark-serialize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" -dependencies = [ - "ark-serialize-derive", - "ark-std", - "digest 0.10.7", - "num-bigint", -] - -[[package]] -name = "ark-serialize-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-std" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "array-bytes" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad284aeb45c13f2fb4f084de4a420ebf447423bdf9386c0540ce33cb3ef4b8c" - [[package]] name = "arrayref" version = "0.3.7" @@ -297,7 +173,7 @@ dependencies = [ "async-stream", "async-trait", "base64 0.13.1", - "bytes 1.4.0", + "bytes 1.5.0", "chrono", "fast_chemail", "fnv", @@ -371,7 +247,7 @@ version = "5.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d461325bfb04058070712296601dfe5e5bd6cdff84780a0a8c569ffb15c87eb3" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "indexmap 1.9.3", "serde", "serde_json", @@ -396,40 +272,29 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] name = "atoi" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" dependencies = [ "num-traits", ] -[[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" @@ -450,9 +315,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -463,19 +328,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "bae" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b8de67cc41132507eeece2584804efcb15f85ba516e34c944b7667f480397a" -dependencies = [ - "heck 0.3.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "base-x" version = "0.2.11" @@ -496,9 +348,26 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bigdecimal" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] [[package]] name = "bincode" @@ -517,17 +386,11 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" - -[[package]] -name = "bitmaps" -version = "2.1.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" dependencies = [ - "typenum", + "serde", ] [[package]] @@ -544,24 +407,24 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", "arrayvec", - "constant_time_eq 0.2.6", + "constant_time_eq", ] [[package]] name = "blake2s_simd" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" +checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" dependencies = [ "arrayref", "arrayvec", - "constant_time_eq 0.2.6", + "constant_time_eq", ] [[package]] @@ -574,7 +437,7 @@ dependencies = [ "arrayvec", "cc", "cfg-if", - "constant_time_eq 0.3.0", + "constant_time_eq", "digest 0.10.7", ] @@ -703,9 +566,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bv" @@ -741,22 +604,22 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" +checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] @@ -773,18 +636,18 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ "serde", ] [[package]] name = "cc" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", "libc", @@ -798,18 +661,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", - "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets", ] [[package]] @@ -827,84 +689,43 @@ dependencies = [ [[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", - "termcolor", - "textwrap", -] - -[[package]] -name = "clap" -version = "4.3.21" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" +checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" dependencies = [ "clap_builder", - "clap_derive 4.3.12", - "once_cell", + "clap_derive", ] [[package]] name = "clap_builder" -version = "4.3.21" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" +checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" dependencies = [ "anstream", "anstyle", - "clap_lex 0.5.0", - "once_cell", + "clap_lex", "strsim", ] [[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.3.12" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", - "syn 2.0.28", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", + "syn 2.0.37", ] [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "colorchoice" @@ -933,10 +754,10 @@ dependencies = [ ] [[package]] -name = "constant_time_eq" -version = "0.2.6" +name = "const-oid" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "constant_time_eq" @@ -1003,30 +824,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - [[package]] name = "crossbeam-queue" version = "0.3.8" @@ -1074,14 +871,13 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "serde", "subtle", "zeroize", ] @@ -1131,7 +927,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] @@ -1153,7 +949,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] @@ -1182,11 +978,22 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" dependencies = [ "serde", ] @@ -1218,30 +1025,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dotenv" version = "0.15.0" @@ -1271,12 +1059,15 @@ name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +dependencies = [ + "serde", +] [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -1289,9 +1080,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", @@ -1308,6 +1099,17 @@ dependencies = [ "libc", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1344,12 +1146,30 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" +[[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 = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project 1.1.3", + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1430,13 +1250,13 @@ dependencies = [ [[package]] name = "futures-intrusive" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ "futures-core", "lock_api", - "parking_lot 0.11.2", + "parking_lot", ] [[package]] @@ -1453,7 +1273,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] @@ -1535,25 +1355,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "glob" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "fnv", "futures-core", "futures-sink", @@ -1568,9 +1392,9 @@ dependencies = [ [[package]] name = "handlebars" -version = "4.3.7" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c3372087601b532857d332f5957cbae686da52bb7810bf038c3e3c3cc2fa0d" +checksum = "c39b3bc2a8f715298032cf5087e58573809374b08160aa7d750582bdb82d2683" dependencies = [ "log", "pest", @@ -1619,22 +1443,21 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ "hashbrown 0.14.0", ] [[package]] name = "headers" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", - "bytes 1.4.0", + "base64 0.21.4", + "bytes 1.5.0", "headers-core", "http", "httpdate", @@ -1651,15 +1474,6 @@ dependencies = [ "http", ] -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.1" @@ -1671,18 +1485,9 @@ dependencies = [ [[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.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -1734,8 +1539,8 @@ dependencies = [ [[package]] name = "holaplex-hub-core" -version = "0.5.3" -source = "git+https://github.com/holaplex/hub-core?branch=stable#40a8dfab0dbf2d01b0eda61ff1ce831e1ea4a10b" +version = "0.5.5" +source = "git+https://github.com/holaplex/hub-core?branch=stable#ffd5b04a3f411d2bae8af317f2b8626012ec3c0b" dependencies = [ "anyhow", "async-trait", @@ -1743,14 +1548,18 @@ dependencies = [ "bs58 0.5.0", "chrono", "cid", - "clap 4.3.21", + "clap", "dotenv", "futures-util", "holaplex-hub-core-macros", "holaplex-hub-core-schemas", "hostname", "num_cpus", + "opentelemetry", + "opentelemetry-prometheus", + "opentelemetry_sdk", "pin-project-lite", + "prometheus", "prost", "prost-types", "rand 0.8.5", @@ -1759,10 +1568,10 @@ dependencies = [ "sea-orm", "serde_json", "serde_with", - "strum", + "strum 0.24.1", "thiserror", "tokio", - "toml 0.7.6", + "toml 0.7.8", "tracing", "tracing-loki", "tracing-subscriber", @@ -1773,7 +1582,7 @@ dependencies = [ [[package]] name = "holaplex-hub-core-build" version = "0.2.1" -source = "git+https://github.com/holaplex/hub-core?branch=stable#40a8dfab0dbf2d01b0eda61ff1ce831e1ea4a10b" +source = "git+https://github.com/holaplex/hub-core?branch=stable#ffd5b04a3f411d2bae8af317f2b8626012ec3c0b" dependencies = [ "anyhow", "dotenv", @@ -1792,18 +1601,18 @@ dependencies = [ [[package]] name = "holaplex-hub-core-macros" version = "0.1.0" -source = "git+https://github.com/holaplex/hub-core?branch=stable#40a8dfab0dbf2d01b0eda61ff1ce831e1ea4a10b" +source = "git+https://github.com/holaplex/hub-core?branch=stable#ffd5b04a3f411d2bae8af317f2b8626012ec3c0b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", "thiserror", ] [[package]] name = "holaplex-hub-core-schemas" version = "0.3.2" -source = "git+https://github.com/holaplex/hub-core?branch=stable#40a8dfab0dbf2d01b0eda61ff1ce831e1ea4a10b" +source = "git+https://github.com/holaplex/hub-core?branch=stable#ffd5b04a3f411d2bae8af317f2b8626012ec3c0b" dependencies = [ "holaplex-hub-core-build", "prost", @@ -1826,7 +1635,16 @@ dependencies = [ "serde", "serde_json", "solana-program", - "strum", + "strum 0.24.1", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", ] [[package]] @@ -1846,7 +1664,7 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "fnv", "itoa", ] @@ -1857,7 +1675,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "http", "pin-project-lite", ] @@ -1870,9 +1688,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" @@ -1880,7 +1698,7 @@ version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures-channel", "futures-core", "futures-util", @@ -1904,7 +1722,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "hyper", "native-tls", "tokio", @@ -1950,22 +1768,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "im" -version = "15.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" -dependencies = [ - "bitmaps", - "rand_core 0.6.4", - "rand_xoshiro", - "rayon", - "serde", - "sized-chunks", - "typenum", - "version_check", -] - [[package]] name = "indexmap" version = "1.9.3" @@ -1987,6 +1789,17 @@ dependencies = [ "hashbrown 0.14.0", ] +[[package]] +name = "inherent" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce243b1bfa62ffc028f1cc3b6034ec63d649f3031bc8a4fbbb004e1ac17d1f68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "instant" version = "0.1.12" @@ -2003,21 +1816,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] -name = "is-terminal" -version = "0.4.9" +name = "itertools" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ - "hermit-abi 0.3.2", - "rustix", - "windows-sys", + "either", ] [[package]] name = "itertools" -version = "0.10.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] @@ -2060,12 +1871,21 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] [[package]] name = "libc" -version = "0.2.147" +version = "0.2.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" + +[[package]] +name = "libm" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "libsecp256k1" @@ -2115,6 +1935,17 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "libsqlite3-sys" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "libz-sys" version = "1.1.12" @@ -2129,9 +1960,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" [[package]] name = "lock_api" @@ -2145,9 +1976,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "loki-api" @@ -2194,9 +2025,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memmap2" @@ -2207,15 +2038,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "migration" version = "0.1.0" @@ -2262,7 +2084,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "encoding_rs", "futures-util", "http", @@ -2362,15 +2184,32 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -2392,6 +2231,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.16" @@ -2399,6 +2249,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -2407,7 +2258,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi", "libc", ] @@ -2434,9 +2285,9 @@ dependencies = [ [[package]] name = "object" -version = "0.31.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -2455,11 +2306,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.56" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cfg-if", "foreign-types", "libc", @@ -2476,7 +2327,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] @@ -2487,9 +2338,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.91" +version = "0.9.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" dependencies = [ "cc", "libc", @@ -2497,6 +2348,76 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9591d937bc0e6d2feb6f71a559540ab300ea49955229c347a517a28d27784c54" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] + +[[package]] +name = "opentelemetry-prometheus" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d81bc254e2d572120363a2b16cdb0d715d301b5789be0cfc26ad87e4e10e53" +dependencies = [ + "once_cell", + "opentelemetry_api", + "opentelemetry_sdk", + "prometheus", + "protobuf", +] + +[[package]] +name = "opentelemetry_api" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a81f725323db1b1206ca3da8bb19874bbd3f57c3bcd59471bfb04525b265b9b" +dependencies = [ + "futures-channel", + "futures-util", + "indexmap 1.9.3", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", + "urlencoding", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8e705a0612d48139799fcbaba0d4a90f06277153e43dd2bdc16c6f0edd8026" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "ordered-float", + "percent-encoding", + "rand 0.8.5", + "regex", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "ordered-float" +version = "3.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a54938017eacd63036332b4ae5c8a49fc8c0c1d6d629893057e4f13609edd06" +dependencies = [ + "num-traits", +] + [[package]] name = "os_pipe" version = "1.1.4" @@ -2507,33 +2428,28 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "os_str_bytes" -version = "6.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" - [[package]] name = "ouroboros" -version = "0.15.6" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db" +checksum = "e2ba07320d39dfea882faa70554b4bd342a5f273ed59ba7c1c6b4c840492c954" dependencies = [ "aliasable", "ouroboros_macro", + "static_assertions", ] [[package]] name = "ouroboros_macro" -version = "0.15.6" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7" +checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" dependencies = [ - "Inflector", + "heck", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.37", ] [[package]] @@ -2542,17 +2458,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -2560,21 +2465,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -2585,7 +2476,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", "windows-targets", ] @@ -2597,12 +2488,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] -name = "pbkdf2" -version = "0.4.0" +name = "pem-rfc7468" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ - "crypto-mac", + "base64ct", ] [[package]] @@ -2613,19 +2504,20 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" +checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" dependencies = [ + "memchr", "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" +checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" dependencies = [ "pest", "pest_generator", @@ -2633,22 +2525,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" +checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] name = "pest_meta" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" +checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" dependencies = [ "once_cell", "pest", @@ -2657,12 +2549,12 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 1.9.3", + "indexmap 2.0.0", ] [[package]] @@ -2702,14 +2594,14 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] name = "pin-project-lite" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -2717,6 +2609,27 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.27" @@ -2725,20 +2638,20 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "poem" -version = "1.3.57" +version = "1.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d92c532a37a9e98c0e9a0411e6852b8acccf9ec07d5e6e450b01cbf947d90b" +checksum = "ebc7ae19f3e791ae8108b08801abb3708d64d3a16490c720e0b81040cae87b5d" dependencies = [ "anyhow", "async-trait", - "base64 0.21.2", - "bytes 1.4.0", + "base64 0.21.4", + "bytes 1.5.0", "futures-util", "headers", "http", "hyper", "mime", - "parking_lot 0.12.1", + "parking_lot", "percent-encoding", "pin-project-lite", "poem-derive", @@ -2759,14 +2672,14 @@ dependencies = [ [[package]] name = "poem-derive" -version = "1.3.57" +version = "1.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5dd58846a1f582215370384c3090c62c9ef188e9d798ffc67ea90d0a1a8a3b8" +checksum = "2550a0bce7273b278894ef3ccc5a6869e7031b6870042f3cc6826ed9faa980a6" dependencies = [ "proc-macro-crate 1.1.3", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] @@ -2830,20 +2743,35 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" 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.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "prost-derive", ] @@ -2853,9 +2781,9 @@ version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ - "bytes 1.4.0", - "heck 0.4.1", - "itertools", + "bytes 1.5.0", + "heck", + "itertools 0.10.5", "lazy_static", "log", "multimap", @@ -2876,7 +2804,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", "syn 1.0.109", @@ -2891,6 +2819,12 @@ 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" @@ -2913,9 +2847,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -2997,37 +2931,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_xoshiro" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" -dependencies = [ - "rand_core 0.6.4", -] - -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - [[package]] name = "rdkafka" version = "0.29.0" @@ -3048,9 +2951,9 @@ dependencies = [ [[package]] name = "rdkafka-sys" -version = "4.5.0+1.9.2" +version = "4.6.0+2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb0676c2112342ac7165decdedbc4e7086c0af384479ccce534546b10687a5d" +checksum = "ad63c279fca41a27c231c450a2d2ad18288032e9cbb159ad16c9d96eba35aaaf" dependencies = [ "libc", "libz-sys", @@ -3061,15 +2964,6 @@ dependencies = [ "zstd-sys", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -3079,27 +2973,16 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom 0.2.10", - "redox_syscall 0.2.16", - "thiserror", -] - [[package]] name = "regex" -version = "1.9.3" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.6", - "regex-syntax 0.7.4", + "regex-automata 0.3.8", + "regex-syntax 0.7.5", ] [[package]] @@ -3113,13 +2996,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.4", + "regex-syntax 0.7.5", ] [[package]] @@ -3130,9 +3013,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "rend" @@ -3145,12 +3028,12 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.2", - "bytes 1.4.0", + "base64 0.21.4", + "bytes 1.5.0", "encoding_rs", "futures-core", "futures-util", @@ -3234,16 +3117,37 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "rsa" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" +dependencies = [ + "byteorder", + "const-oid", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rust_decimal" -version = "1.31.0" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a2ab0025103a60ecaaf3abf24db1db240a4e1c15837090d2c32f625ac98abea" +checksum = "a4c4216490d5a413bc6d10fa4742bd7d4955941d062c0ef873141d6b0e7b30fd" dependencies = [ "arrayvec", "borsh 0.10.3", - "byteorder", - "bytes 1.4.0", + "bytes 1.5.0", "num-traits", "rand 0.8.5", "rkyv", @@ -3257,12 +3161,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc_version" version = "0.4.0" @@ -3274,11 +3172,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.7" +version = "0.38.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172891ebdceb05aa0005f533a6cbfca599ddd7d966f6f5d4d9b2e70478e70399" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", @@ -3287,14 +3185,13 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ - "log", "ring", + "rustls-webpki", "sct", - "webpki", ] [[package]] @@ -3303,7 +3200,17 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" +dependencies = [ + "ring", + "untrusted", ] [[package]] @@ -3355,29 +3262,42 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sea-bae" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd3534a9978d0aa7edd2808dc1f8f31c4d0ecd31ddf71d997b3c98e9f3c9114" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "sea-orm" -version = "0.10.7" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88694d01b528a94f90ad87f8d2f546d060d070eee180315c67d158cb69476034" +checksum = "61f6c7daef05dde3476d97001e11fca7a52b655aa3bf4fd610ab2da1176a2ed5" dependencies = [ "async-stream", "async-trait", + "bigdecimal", "chrono", "futures", - "futures-util", "log", "ouroboros", "rust_decimal", "sea-orm-macros", "sea-query", "sea-query-binder", - "sea-strum", "serde", "serde_json", "sqlx", + "strum 0.25.0", "thiserror", - "time 0.3.25", + "time", "tracing", "url", "uuid", @@ -3385,13 +3305,14 @@ dependencies = [ [[package]] name = "sea-orm-cli" -version = "0.10.7" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ebe1f820fe8949cf6a57272ba9ebd0be766e47c9b85c04b3cabea40ab9459b3" +checksum = "3e3f0ff2fa5672e2e7314d107c6498a18e469beeb340a0ed84e3075fce73c2cd" dependencies = [ "chrono", - "clap 3.2.25", + "clap", "dotenvy", + "glob", "regex", "sea-schema", "tracing", @@ -3401,26 +3322,28 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.10.7" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7216195de9c6b2474fd0efab486173dccd0eff21f28cc54aa4c0205d52fb3af0" +checksum = "cd90e73d5f5b184bad525767da29fbfec132b4e62ebd6f60d2f2737ec6468f62" dependencies = [ - "bae", - "heck 0.3.3", + "heck", "proc-macro2", "quote", - "syn 1.0.109", + "sea-bae", + "syn 2.0.37", + "unicode-ident", ] [[package]] name = "sea-orm-migration" -version = "0.10.7" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed3cdfa669e4c385922f902b9a58e0c2128782a4d0fe79c6c34f3b927565e5b" +checksum = "21f673fcefb3a7e7b89a12b6c0e854ec0be14367635ac3435369c8ad7f11e09e" dependencies = [ "async-trait", - "clap 3.2.25", + "clap", "dotenvy", + "futures", "sea-orm", "sea-orm-cli", "sea-schema", @@ -3430,40 +3353,45 @@ dependencies = [ [[package]] name = "sea-query" -version = "0.27.2" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4f0fc4d8e44e1d51c739a68d336252a18bc59553778075d5e32649be6ec92ed" +checksum = "28c05a5bf6403834be253489bbe95fa9b1e5486bc843b61f60d26b5c9c1e244b" dependencies = [ + "bigdecimal", "chrono", + "derivative", + "inherent", + "ordered-float", "rust_decimal", "sea-query-derive", "serde_json", - "time 0.3.25", + "time", "uuid", ] [[package]] name = "sea-query-binder" -version = "0.2.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2585b89c985cfacfe0ec9fc9e7bb055b776c1a2581c4e3c6185af2b8bf8865" +checksum = "36bbb68df92e820e4d5aeb17b4acd5cc8b5d18b2c36a4dd6f4626aabfa7ab1b9" dependencies = [ + "bigdecimal", "chrono", "rust_decimal", "sea-query", "serde_json", "sqlx", - "time 0.3.25", + "time", "uuid", ] [[package]] name = "sea-query-derive" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cdc022b4f606353fe5dc85b09713a04e433323b70163e81513b141c6ae6eb5" +checksum = "bd78f2e0ee8e537e9195d1049b752e0433e2cac125426bccb7b5c3e508096117" dependencies = [ - "heck 0.3.3", + "heck", "proc-macro2", "quote", "syn 1.0.109", @@ -3472,9 +3400,9 @@ dependencies = [ [[package]] name = "sea-schema" -version = "0.10.3" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d5fda574d980e9352b6c7abd6fc75697436fe0078cac2b548559b52643ad3b" +checksum = "0cd9561232bd1b82ea748b581f15909d11de0db6563ddcf28c5d908aee8282f1" dependencies = [ "futures", "sea-query", @@ -3483,35 +3411,13 @@ dependencies = [ [[package]] name = "sea-schema-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56821b7076f5096b8f726e2791ad255a99c82498e08ec477a65a96c461ff1927" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "sea-strum" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391d06a6007842cfe79ac6f7f53911b76dfd69fc9a6769f1cf6569d12ce20e1b" -dependencies = [ - "sea-strum_macros", -] - -[[package]] -name = "sea-strum_macros" -version = "0.23.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b4397b825df6ccf1e98bcdabef3bbcfc47ff5853983467850eeab878384f21" +checksum = "c6f686050f76bffc4f635cda8aea6df5548666b830b52387e8bc7de11056d11e" dependencies = [ - "heck 0.3.3", + "heck", "proc-macro2", "quote", - "rustversion", "syn 1.0.109", ] @@ -3552,9 +3458,9 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] @@ -3570,20 +3476,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -3624,7 +3530,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.25", + "time", ] [[package]] @@ -3636,7 +3542,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] @@ -3704,26 +3610,26 @@ dependencies = [ ] [[package]] -name = "simdutf8" -version = "0.1.4" +name = "signature" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] [[package]] -name = "sized-chunks" -version = "0.6.5" +name = "simdutf8" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" -dependencies = [ - "bitmaps", - "typenum", -] +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -3752,9 +3658,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", "windows-sys", @@ -3762,115 +3668,88 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.16.7" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee2b96d4150d9ebf55e903014bc332ac64c642837d7f1e6f7b911d709331380" +checksum = "1f704637b29f1d58b819601efede8eff0998ec10381cb96796dacfe4cfea5581" dependencies = [ - "ahash 0.8.3", - "blake3", - "block-buffer 0.10.4", "bs58 0.4.0", "bv", - "byteorder", - "cc", - "either", "generic-array", - "getrandom 0.1.16", - "im", - "lazy_static", "log", "memmap2", - "once_cell", - "rand_core 0.6.4", "rustc_version", "serde", - "serde_bytes", "serde_derive", - "serde_json", "sha2 0.10.7", "solana-frozen-abi-macro", - "subtle", "thiserror", ] [[package]] name = "solana-frozen-abi-macro" -version = "1.16.7" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942534eb972f955ed186175495654cabece6261a8ac3211e5791440d40a1ed96" +checksum = "96bf045e938c042c59739ba3a77bf1d25cb7cf073bbf3690cc2d56c7cff27ba2" dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.28", + "syn 1.0.109", ] [[package]] name = "solana-program" -version = "1.16.7" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f81c59ed0b65b403cc5db459dd1214dfab89ccd3ce20aadf98102b072d08562" +checksum = "888f50c71dc45a528cb63df960e657601fe6fa3d643159d93ebff1dd1cc00b63" dependencies = [ - "ark-bn254", - "ark-ec", - "ark-ff", - "ark-serialize", - "array-bytes", - "base64 0.21.2", + "base64 0.13.1", "bincode", "bitflags 1.3.2", "blake3", - "borsh 0.10.3", "borsh 0.9.3", + "borsh-derive 0.9.3", "bs58 0.4.0", "bv", "bytemuck", - "cc", "console_error_panic_hook", "console_log", "curve25519-dalek", - "getrandom 0.2.10", - "itertools", + "getrandom 0.1.16", + "itertools 0.10.5", "js-sys", "lazy_static", - "libc", "libsecp256k1", "log", - "memoffset", - "num-bigint", "num-derive", "num-traits", - "parking_lot 0.12.1", + "parking_lot", "rand 0.7.3", - "rand_chacha 0.2.2", "rustc_version", "rustversion", "serde", "serde_bytes", "serde_derive", - "serde_json", "sha2 0.10.7", "sha3", "solana-frozen-abi", "solana-frozen-abi-macro", "solana-sdk-macro", "thiserror", - "tiny-bip39", "wasm-bindgen", - "zeroize", ] [[package]] name = "solana-sdk-macro" -version = "1.16.7" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7d686e405694cd6510cd77bb87d0eeda64ad3df08d3293278ba47ca78b8e5e" +checksum = "2388e9b1690e83413393f3e20d98551cbebae9d9385397600d25ae9992873736" dependencies = [ "bs58 0.4.0", "proc-macro2", "quote", "rustversion", - "syn 2.0.28", + "syn 1.0.109", ] [[package]] @@ -3884,115 +3763,246 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] [[package]] name = "sqlformat" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" +checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" dependencies = [ - "itertools", + "itertools 0.11.0", "nom", "unicode_categories", ] [[package]] name = "sqlx" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +checksum = "8e58421b6bc416714d5115a2ca953718f6c621a51b68e4f4922aea5a4391a721" dependencies = [ "sqlx-core", "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", ] [[package]] name = "sqlx-core" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +checksum = "dd4cef4251aabbae751a3710927945901ee1d97ee96d757f6880ebb9a79bfd53" dependencies = [ - "ahash 0.7.6", + "ahash 0.8.3", "atoi", - "base64 0.13.1", - "bitflags 1.3.2", + "bigdecimal", "byteorder", - "bytes 1.4.0", + "bytes 1.5.0", "chrono", "crc", "crossbeam-queue", - "dirs", "dotenvy", "either", "event-listener", "futures-channel", "futures-core", "futures-intrusive", + "futures-io", "futures-util", "hashlink", "hex", - "hkdf", - "hmac 0.12.1", - "indexmap 1.9.3", - "itoa", - "libc", + "indexmap 2.0.0", "log", - "md-5", "memchr", - "num-bigint", "once_cell", "paste", "percent-encoding", - "rand 0.8.5", "rust_decimal", "rustls", "rustls-pemfile", "serde", "serde_json", - "sha1", "sha2 0.10.7", "smallvec", "sqlformat", - "sqlx-rt", - "stringprep", "thiserror", - "time 0.3.25", + "time", + "tokio", "tokio-stream", + "tracing", "url", "uuid", "webpki-roots", - "whoami", ] [[package]] name = "sqlx-macros" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +checksum = "208e3165167afd7f3881b16c1ef3f2af69fa75980897aac8874a0696516d12c2" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a4a8336d278c62231d87f24e8a7a74898156e34c1c18942857be2acb29c7dfc" dependencies = [ "dotenvy", "either", - "heck 0.4.1", + "heck", + "hex", "once_cell", "proc-macro2", "quote", + "serde", "serde_json", "sha2 0.10.7", "sqlx-core", - "sqlx-rt", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", "syn 1.0.109", + "tempfile", + "tokio", "url", ] [[package]] -name = "sqlx-rt" -version = "0.6.3" +name = "sqlx-mysql" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +checksum = "8ca69bf415b93b60b80dc8fda3cb4ef52b2336614d8da2de5456cc942a110482" dependencies = [ + "atoi", + "base64 0.21.4", + "bigdecimal", + "bitflags 2.4.0", + "byteorder", + "bytes 1.5.0", + "chrono", + "crc", + "digest 0.10.7", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac 0.12.1", + "itoa", + "log", + "md-5", + "memchr", "once_cell", - "tokio", - "tokio-rustls", + "percent-encoding", + "rand 0.8.5", + "rsa", + "rust_decimal", + "serde", + "sha1", + "sha2 0.10.7", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0db2df1b8731c3651e204629dd55e52adbae0462fa1bdcbed56a2302c18181e" +dependencies = [ + "atoi", + "base64 0.21.4", + "bigdecimal", + "bitflags 2.4.0", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac 0.12.1", + "home", + "itoa", + "log", + "md-5", + "memchr", + "num-bigint", + "once_cell", + "rand 0.8.5", + "rust_decimal", + "serde", + "serde_json", + "sha1", + "sha2 0.10.7", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4c21bf34c7cae5b283efb3ac1bcc7670df7561124dc2f8bdc0b59be40f79a2" +dependencies = [ + "atoi", + "chrono", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "time", + "tracing", + "url", + "uuid", ] [[package]] @@ -4015,10 +4025,11 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stringprep" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3737bde7edce97102e0e2b15365bf7a20bfdb5f60f4f9e8d7004258a51a8da" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" dependencies = [ + "finl_unicode", "unicode-bidi", "unicode-normalization", ] @@ -4038,13 +4049,19 @@ dependencies = [ "strum_macros", ] +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + [[package]] name = "strum_macros" version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "rustversion", @@ -4070,9 +4087,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -4099,50 +4116,35 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.7.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand 2.0.0", - "redox_syscall 0.3.5", + "redox_syscall", "rustix", "windows-sys", ] -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] @@ -4157,20 +4159,9 @@ dependencies = [ [[package]] name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", "itoa", @@ -4187,32 +4178,13 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ "time-core", ] -[[package]] -name = "tiny-bip39" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" -dependencies = [ - "anyhow", - "hmac 0.8.1", - "once_cell", - "pbkdf2", - "rand 0.7.3", - "rustc-hash", - "sha2 0.9.9", - "thiserror", - "unicode-normalization", - "wasm-bindgen", - "zeroize", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -4230,18 +4202,18 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.30.0" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3ce25f50619af8b0aec2eb23deebe84249e19e2ddd393a6e16e3300a6dadfd" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ "backtrace", - "bytes 1.4.0", + "bytes 1.5.0", "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", - "socket2 0.5.3", + "socket2 0.5.4", "tokio-macros", "windows-sys", ] @@ -4254,7 +4226,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] @@ -4267,17 +4239,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" -dependencies = [ - "rustls", - "tokio", - "webpki", -] - [[package]] name = "tokio-stream" version = "0.1.14" @@ -4291,9 +4252,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c" +checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" dependencies = [ "futures-util", "log", @@ -4307,7 +4268,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures-core", "futures-io", "futures-sink", @@ -4328,9 +4289,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", @@ -4349,9 +4310,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.14" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.0.0", "serde", @@ -4387,7 +4348,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", ] [[package]] @@ -4468,12 +4429,12 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" +checksum = "e862a1c4128df0112ab625f55cd5c934bcb4312ba80b39ae4b4835a3fd58e649" dependencies = [ "byteorder", - "bytes 1.4.0", + "bytes 1.5.0", "data-encoding", "http", "httparse", @@ -4487,9 +4448,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" @@ -4514,9 +4475,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -4547,9 +4508,9 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] name = "unsigned-varint" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" [[package]] name = "untrusted" @@ -4559,9 +4520,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -4569,6 +4530,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" @@ -4624,12 +4591,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -4657,7 +4618,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", "wasm-bindgen-shared", ] @@ -4691,7 +4652,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.37", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4704,9 +4665,9 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-streams" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" dependencies = [ "futures-util", "js-sys", @@ -4725,34 +4686,25 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "webpki-roots" -version = "0.22.6" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" dependencies = [ - "webpki", + "rustls-webpki", ] [[package]] name = "which" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", - "libc", + "home", "once_cell", + "rustix", ] [[package]] @@ -4760,10 +4712,6 @@ name = "whoami" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" -dependencies = [ - "wasm-bindgen", - "web-sys", -] [[package]] name = "winapi" @@ -4781,15 +4729,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -4816,9 +4755,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -4831,62 +4770,63 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.4" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acaaa1190073b2b101e15083c38ee8ec891b5e05cbee516521e94ec008f61e64" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys", ] [[package]] @@ -4900,23 +4840,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.28", -] +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" [[package]] name = "zstd-sys" diff --git a/Cargo.toml b/Cargo.toml index 6a72d43..3b2f56a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,3 @@ [workspace] members = ["api", "migration"] -resolver = "2" \ No newline at end of file +resolver = "2" diff --git a/api/Cargo.toml b/api/Cargo.toml index 95c168f..21dfc72 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -17,7 +17,7 @@ categories = ["cryptography::cryptocurrencies", "web-programming"] [lib] [dependencies] -sea-orm = { version = "^0.10.0", features = [ +sea-orm = { version = "0.12.2", features = [ "debug-print", "runtime-tokio-rustls", "sqlx-postgres", @@ -31,7 +31,7 @@ async-graphql = { version = "5.0.4", features = [ ] } serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.93" -solana-program = "1.15.0" +solana-program = "1" poem = { version = "1.3.50", features = ["anyhow", "test"] } async-graphql-poem = "5.0.3" prost = "0.11.9" @@ -42,10 +42,10 @@ strum = { version = "0.24.1", features = ["derive"] } [dependencies.hub-core] package = "holaplex-hub-core" -version = "0.5.3" +version = "0.5.5" git = "https://github.com/holaplex/hub-core" branch = "stable" -features = ["kafka", "credits", "asset_proxy", "sea-orm"] +features = ["kafka", "credits", "asset_proxy", "sea-orm", "metrics"] [build-dependencies.hub-core-build] package = "holaplex-hub-core-build" diff --git a/api/proto.lock b/api/proto.lock index ecab697..2fbdf20 100644 --- a/api/proto.lock +++ b/api/proto.lock @@ -5,8 +5,8 @@ sha512 = "d75800df0d4744c6b0f4d9a9952d3bfd0bb6b24a8babd19104cc11b54a525f85551b3c [[schemas]] subject = "nfts" -version = 28 -sha512 = "25960e99e2eb1edeb70b7619918926d877b834640cf44fcc8104da5be6e213c05be18f8f49dba35e649d751bc62e16d9ca428cbafdb432b7c0b7f40a6cef7483" +version = 30 +sha512 = "bee70bd6f0f18a8049f93bceb9c4b500b49352f9d19d55d5a411da92cbd786c88bec47f73e1ef6946ceefc7de8e558f704bf8187be9d9f4e49bd102baec29327" [[schemas]] subject = "organization" @@ -20,8 +20,8 @@ sha512 = "c5ddf43d2958ec690ee2261d0ff9808b67ce810d2fc4b6077f96f561929a920f03509f [[schemas]] subject = "solana_nfts" -version = 10 -sha512 = "1bcb166ab5dfdf4841d60caa07a4098dcec03d7e3b0e63adb090ed2f5fe990c1e13826867e8df7521ec631027d5a931a08865fd2cf2daa905807c4b7dca40213" +version = 11 +sha512 = "967fefde938a0f6ce05194e4fca15673e681caac54d8aeec114c5d38418632b9696dbaf5362345a15114e5abb49de55d0af8b9edcc0f2c91f9ef1ccc4ff55d68" [[schemas]] subject = "timestamp" @@ -30,5 +30,5 @@ sha512 = "d167e0a143c813073eef8597f0b237e5a8eaf32abbf709724e8071b2dd73ce0438b82f [[schemas]] subject = "treasury" -version = 22 -sha512 = "bde788b07f818aa52e684dcbd91e1f1e3db82f242f616ec2a42ab6d412df33a1461677c229f2f9bae345938c2f325e6332a95caef2c7e01a47531af53e39bf03" +version = 23 +sha512 = "0e4d77999767d5971122e720c1cee7a57c3e47ce69f58a582f1762d8e65e031ea3bd9024cfc21bd7da5db6e38a71657151c58cdfa21d9ff643fb2fc657105cf5" diff --git a/api/proto.toml b/api/proto.toml index 3d92c89..44a45d7 100644 --- a/api/proto.toml +++ b/api/proto.toml @@ -3,9 +3,9 @@ endpoint = "https://schemas.holaplex.tools" [schemas] organization = 5 -nfts = 28 +nfts = 30 customer = 2 -treasury = 22 -solana_nfts = 10 +treasury = 23 +solana_nfts = 11 polygon_nfts = 6 timestamp = 1 \ No newline at end of file diff --git a/api/src/blockchains/mod.rs b/api/src/blockchains/mod.rs index 6aab281..954e6ec 100644 --- a/api/src/blockchains/mod.rs +++ b/api/src/blockchains/mod.rs @@ -3,8 +3,11 @@ pub mod solana; use hub_core::anyhow::Result; -use crate::proto::{ - NftEventKey, RetryUpdateSolanaMintPayload, SwitchCollectionPayload, UpdateSolanaMintPayload, +use crate::{ + entities::sea_orm_active_enums::DropType, + proto::{ + NftEventKey, RetryUpdateSolanaMintPayload, SwitchCollectionPayload, UpdateSolanaMintPayload, + }, }; /// Represents a response from a transaction on the blockchain. This struct @@ -19,9 +22,14 @@ pub struct TransactionResponse { #[async_trait::async_trait] pub trait DropEvent { - async fn create_drop(&self, key: NftEventKey, payload: A) -> Result<()>; - async fn retry_create_drop(&self, key: NftEventKey, payload: A) -> Result<()>; - async fn update_drop(&self, key: NftEventKey, payload: C) -> Result<()>; + async fn create_drop(&self, drop_type: DropType, key: NftEventKey, payload: A) -> Result<()>; + async fn retry_create_drop( + &self, + drop_type: DropType, + key: NftEventKey, + payload: A, + ) -> Result<()>; + async fn update_drop(&self, drop_type: DropType, key: NftEventKey, payload: C) -> Result<()>; async fn mint_drop(&self, key: NftEventKey, payload: B) -> Result<()>; async fn retry_mint_drop(&self, key: NftEventKey, payload: B) -> Result<()>; } diff --git a/api/src/blockchains/polygon.rs b/api/src/blockchains/polygon.rs index b2853ff..8696a33 100644 --- a/api/src/blockchains/polygon.rs +++ b/api/src/blockchains/polygon.rs @@ -1,13 +1,16 @@ -use hub_core::{anyhow::Result, producer::Producer}; +use hub_core::{anyhow::Result, prelude::bail, producer::Producer}; use super::{DropEvent, TransferEvent}; -use crate::proto::{ - nft_events::Event::{ - PolygonCreateDrop, PolygonMintDrop, PolygonRetryDrop, PolygonRetryMintDrop, - PolygonTransferAsset, PolygonUpdateDrop, +use crate::{ + entities::sea_orm_active_enums::DropType, + proto::{ + nft_events::Event::{ + PolygonCreateDrop, PolygonMintDrop, PolygonRetryDrop, PolygonRetryMintDrop, + PolygonTransferAsset, PolygonUpdateDrop, + }, + CreateEditionTransaction, MintEditionTransaction, NftEventKey, NftEvents, + TransferPolygonAsset, UpdateEdtionTransaction, }, - CreateEditionTransaction, MintEditionTransaction, NftEventKey, NftEvents, TransferPolygonAsset, - UpdateEdtionTransaction, }; #[derive(Clone)] @@ -34,46 +37,69 @@ impl Polygon { impl DropEvent for Polygon { - async fn create_drop(&self, key: NftEventKey, payload: CreateEditionTransaction) -> Result<()> { - let event = NftEvents { - event: Some(PolygonCreateDrop(payload)), + async fn create_drop( + &self, + drop_type: DropType, + key: NftEventKey, + payload: CreateEditionTransaction, + ) -> Result<()> { + let event = match drop_type { + DropType::Edition => Some(PolygonCreateDrop(payload)), + DropType::Open => bail!("Open drops are not supported on Polygon"), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } async fn retry_create_drop( &self, + drop_type: DropType, key: NftEventKey, payload: CreateEditionTransaction, ) -> Result<()> { - let event = NftEvents { - event: Some(PolygonRetryDrop(payload)), + let event = match drop_type { + DropType::Edition => Some(PolygonRetryDrop(payload)), + DropType::Open => bail!("Open drops are not supported on Polygon"), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } - async fn update_drop(&self, key: NftEventKey, payload: UpdateEdtionTransaction) -> Result<()> { - let event = NftEvents { - event: Some(PolygonUpdateDrop(payload)), + async fn update_drop( + &self, + drop_type: DropType, + key: NftEventKey, + payload: UpdateEdtionTransaction, + ) -> Result<()> { + let event = match drop_type { + DropType::Edition => Some(PolygonUpdateDrop(payload)), + DropType::Open => bail!("Open drops are not supported on Polygon"), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } async fn mint_drop(&self, key: NftEventKey, payload: MintEditionTransaction) -> Result<()> { - let event = NftEvents { - event: Some(PolygonMintDrop(payload)), - }; - - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send( + Some(&NftEvents { + event: Some(PolygonMintDrop(payload)), + }), + Some(&key), + ) + .await?; Ok(()) } @@ -83,11 +109,14 @@ impl DropEvent Result<()> { - let event = NftEvents { - event: Some(PolygonRetryMintDrop(payload)), - }; - - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send( + Some(&NftEvents { + event: Some(PolygonRetryMintDrop(payload)), + }), + Some(&key), + ) + .await?; Ok(()) } diff --git a/api/src/blockchains/solana.rs b/api/src/blockchains/solana.rs index ac999a6..838775a 100644 --- a/api/src/blockchains/solana.rs +++ b/api/src/blockchains/solana.rs @@ -1,23 +1,34 @@ use hub_core::{anyhow::Result, producer::Producer}; use super::{CollectionEvent, DropEvent, TransferEvent}; -use crate::proto::{ - nft_events::Event::{ - SolanaCreateCollection, SolanaCreateDrop, SolanaMintDrop, SolanaMintToCollection, - SolanaRetryCreateCollection, SolanaRetryDrop, SolanaRetryMintDrop, - SolanaRetryMintToCollection, SolanaRetryUpdatedCollectionMint, - SolanaSwitchMintCollectionRequested, SolanaTransferAsset, SolanaUpdateCollection, - SolanaUpdateDrop, SolanaUpdatedCollectionMint, +use crate::{ + entities::sea_orm_active_enums::DropType, + proto::{ + nft_events::Event::{ + SolanaCreateCollection, SolanaCreateEditionDrop, SolanaCreateOpenDrop, + SolanaMintEditionDrop, SolanaMintOpenDrop, SolanaMintToCollection, + SolanaRetryCreateCollection, SolanaRetryEditionDrop, SolanaRetryMintEditionDrop, + SolanaRetryMintOpenDrop, SolanaRetryMintToCollection, SolanaRetryOpenDrop, + SolanaRetryUpdatedCollectionMint, SolanaSwitchMintCollectionRequested, + SolanaTransferAsset, SolanaUpdateCollection, SolanaUpdateEditionDrop, + SolanaUpdateOpenDrop, SolanaUpdatedCollectionMint, + }, + MetaplexMasterEditionTransaction, MintMetaplexEditionTransaction, + MintMetaplexMetadataTransaction, NftEventKey, NftEvents, RetryUpdateSolanaMintPayload, + SwitchCollectionPayload, TransferMetaplexAssetTransaction, UpdateSolanaMintPayload, }, - MetaplexMasterEditionTransaction, MintMetaplexEditionTransaction, - MintMetaplexMetadataTransaction, NftEventKey, NftEvents, RetryUpdateSolanaMintPayload, - SwitchCollectionPayload, TransferMetaplexAssetTransaction, UpdateSolanaMintPayload, }; + #[derive(Clone)] pub struct Solana { producer: Producer, } +pub enum MintDropTransaction { + Edition(MintMetaplexEditionTransaction), + Open(MintMetaplexMetadataTransaction), +} + impl Solana { #[must_use] pub fn new(producer: Producer) -> Self { @@ -29,7 +40,7 @@ impl Solana { &self, ) -> impl DropEvent< MetaplexMasterEditionTransaction, - MintMetaplexEditionTransaction, + MintDropTransaction, MetaplexMasterEditionTransaction, > + TransferEvent + CollectionEvent< @@ -45,76 +56,86 @@ impl Solana { impl DropEvent< MetaplexMasterEditionTransaction, - MintMetaplexEditionTransaction, + MintDropTransaction, MetaplexMasterEditionTransaction, > for Solana { async fn create_drop( &self, + drop_type: DropType, key: NftEventKey, payload: MetaplexMasterEditionTransaction, ) -> Result<()> { - let event = NftEvents { - event: Some(SolanaCreateDrop(payload)), + let event = match drop_type { + DropType::Edition => Some(SolanaCreateEditionDrop(payload)), + DropType::Open => Some(SolanaCreateOpenDrop(payload)), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } async fn retry_create_drop( &self, + drop_type: DropType, key: NftEventKey, payload: MetaplexMasterEditionTransaction, ) -> Result<()> { - let event = NftEvents { - event: Some(SolanaRetryDrop(payload)), + let event = match drop_type { + DropType::Edition => Some(SolanaRetryEditionDrop(payload)), + DropType::Open => Some(SolanaRetryOpenDrop(payload)), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } async fn update_drop( &self, + drop_type: DropType, key: NftEventKey, payload: MetaplexMasterEditionTransaction, ) -> Result<()> { - let event = NftEvents { - event: Some(SolanaUpdateDrop(payload)), + let event = match drop_type { + DropType::Edition => Some(SolanaUpdateEditionDrop(payload)), + DropType::Open => Some(SolanaUpdateOpenDrop(payload)), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } - async fn mint_drop( - &self, - key: NftEventKey, - payload: MintMetaplexEditionTransaction, - ) -> Result<()> { - let event = NftEvents { - event: Some(SolanaMintDrop(payload)), + async fn mint_drop(&self, key: NftEventKey, payload: MintDropTransaction) -> Result<()> { + let event = match payload { + MintDropTransaction::Edition(p) => Some(SolanaMintEditionDrop(p)), + MintDropTransaction::Open(p) => Some(SolanaMintOpenDrop(p)), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } - async fn retry_mint_drop( - &self, - key: NftEventKey, - payload: MintMetaplexEditionTransaction, - ) -> Result<()> { - let event = NftEvents { - event: Some(SolanaRetryMintDrop(payload)), + async fn retry_mint_drop(&self, key: NftEventKey, payload: MintDropTransaction) -> Result<()> { + let event = match payload { + MintDropTransaction::Edition(tx) => Some(SolanaRetryMintEditionDrop(tx)), + MintDropTransaction::Open(tx) => Some(SolanaRetryMintOpenDrop(tx)), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } diff --git a/api/src/dataloaders/collection_mints.rs b/api/src/dataloaders/collection_mints.rs index 1e37b6f..22a1383 100644 --- a/api/src/dataloaders/collection_mints.rs +++ b/api/src/dataloaders/collection_mints.rs @@ -2,9 +2,13 @@ use std::{borrow::Cow, collections::HashMap}; use async_graphql::{dataloader::Loader as DataLoader, FieldError, Result}; use poem::async_trait; -use sea_orm::prelude::*; +use sea_orm::{prelude::*, JoinType, QuerySelect}; -use crate::{db::Connection, entities::collection_mints, objects::CollectionMint}; +use crate::{ + db::Connection, + entities::{collection_mints, collections, drops, sea_orm_active_enums::CreationStatus}, + objects::CollectionMint, +}; #[derive(Debug, Clone)] pub struct Loader { @@ -28,6 +32,7 @@ impl DataLoader for Loader { .filter( collection_mints::Column::CollectionId.is_in(keys.iter().map(ToOwned::to_owned)), ) + .filter(collection_mints::Column::CreationStatus.ne(CreationStatus::Queued)) .all(self.db.get()) .await?; @@ -74,12 +79,11 @@ impl DataLoader for OwnerLoader { Ok(collection_mints .into_iter() .fold(HashMap::new(), |mut acc, collection_mint| { - acc.entry(collection_mint.owner.clone()) - .or_insert_with(Vec::new); - - acc.entry(collection_mint.owner.clone()) - .and_modify(|collection_mints| collection_mints.push(collection_mint.into())); - + if let Some(owner) = collection_mint.owner.clone() { + acc.entry(owner) + .or_insert_with(Vec::new) + .push(collection_mint.into()); + } acc })) } @@ -114,3 +118,41 @@ impl DataLoader for CollectionMintLoader { .collect()) } } + +/// Dataloader for queued mints for a drop +#[derive(Debug, Clone)] +pub struct QueuedMintsLoader { + pub db: Connection, +} + +impl QueuedMintsLoader { + #[must_use] + pub fn new(db: Connection) -> Self { + Self { db } + } +} + +#[async_trait] +impl DataLoader for QueuedMintsLoader { + type Error = FieldError; + type Value = Vec; + + async fn load(&self, keys: &[Uuid]) -> Result, Self::Error> { + let drop_mints = drops::Entity::find() + .select_with(collection_mints::Entity) + .join(JoinType::InnerJoin, drops::Relation::Collections.def()) + .join( + JoinType::InnerJoin, + collections::Relation::CollectionMints.def(), + ) + .filter(collection_mints::Column::CreationStatus.eq(CreationStatus::Queued)) + .filter(drops::Column::Id.is_in(keys.iter().map(ToOwned::to_owned))) + .all(self.db.get()) + .await?; + + Ok(drop_mints + .into_iter() + .map(|(drop, mints)| (drop.id, mints.into_iter().map(Into::into).collect())) + .collect()) + } +} diff --git a/api/src/dataloaders/holders.rs b/api/src/dataloaders/holders.rs index 46914b8..dbed271 100644 --- a/api/src/dataloaders/holders.rs +++ b/api/src/dataloaders/holders.rs @@ -28,6 +28,7 @@ impl DataLoader for Loader { .filter( collection_mints::Column::CollectionId.is_in(keys.iter().map(ToOwned::to_owned)), ) + .filter(collection_mints::Column::Owner.is_not_null()) .select_only() .column(collection_mints::Column::CollectionId) .column_as(collection_mints::Column::Owner, "address") diff --git a/api/src/dataloaders/mod.rs b/api/src/dataloaders/mod.rs index b2244cb..f6648c7 100644 --- a/api/src/dataloaders/mod.rs +++ b/api/src/dataloaders/mod.rs @@ -18,7 +18,7 @@ pub use collection::Loader as CollectionLoader; pub use collection_drop::Loader as CollectionDropLoader; pub use collection_mints::{ CollectionMintLoader, Loader as CollectionMintsLoader, - OwnerLoader as CollectionMintsOwnerLoader, + OwnerLoader as CollectionMintsOwnerLoader, QueuedMintsLoader, }; pub use creators::Loader as CreatorsLoader; pub use drop::Loader as DropLoader; diff --git a/api/src/dataloaders/switch_collection_histories.rs b/api/src/dataloaders/switch_collection_histories.rs index c1653bf..ceade5f 100644 --- a/api/src/dataloaders/switch_collection_histories.rs +++ b/api/src/dataloaders/switch_collection_histories.rs @@ -37,11 +37,11 @@ impl DataLoader for SwitchCollectionHistoryLoader { Ok(switch_histories.into_iter().fold( HashMap::new(), |mut acc: HashMap>, switch_history| { - acc.entry(switch_history.collection_mint_id.clone()) + acc.entry(switch_history.collection_mint_id) .or_insert_with(Vec::new); - acc.entry(switch_history.collection_mint_id.clone()) - .and_modify(|switch_histories| switch_histories.push(switch_history.into())); + acc.entry(switch_history.collection_mint_id) + .and_modify(|switch_histories| switch_histories.push(switch_history)); acc }, diff --git a/api/src/entities/collection_mints.rs b/api/src/entities/collection_mints.rs index 940ab90..27dd451 100644 --- a/api/src/entities/collection_mints.rs +++ b/api/src/entities/collection_mints.rs @@ -13,8 +13,8 @@ pub struct Model { pub collection_id: Uuid, #[sea_orm(column_type = "Text", nullable)] pub address: Option, - #[sea_orm(column_type = "Text")] - pub owner: String, + #[sea_orm(column_type = "Text", nullable)] + pub owner: Option, pub creation_status: CreationStatus, pub created_by: Uuid, pub created_at: DateTimeWithTimeZone, @@ -23,7 +23,8 @@ pub struct Model { pub edition: i64, pub seller_fee_basis_points: i16, pub credits_deduction_id: Option, - pub compressed: bool, + #[sea_orm(nullable)] + pub compressed: Option, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/api/src/entities/drops.rs b/api/src/entities/drops.rs index b19c1b2..ed5a48e 100644 --- a/api/src/entities/drops.rs +++ b/api/src/entities/drops.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -use super::sea_orm_active_enums::CreationStatus; +use super::sea_orm_active_enums::{CreationStatus, DropType}; #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "drops")] @@ -20,6 +20,7 @@ pub struct Model { pub paused_at: Option, pub shutdown_at: Option, pub credits_deduction_id: Option, + pub drop_type: DropType, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/api/src/entities/sea_orm_active_enums.rs b/api/src/entities/sea_orm_active_enums.rs index db967e9..69989a4 100644 --- a/api/src/entities/sea_orm_active_enums.rs +++ b/api/src/entities/sea_orm_active_enums.rs @@ -43,4 +43,16 @@ pub enum CreationStatus { Pending, #[sea_orm(string_value = "rejected")] Rejected, + #[sea_orm(string_value = "queued")] + Queued, +} + +#[derive(Debug, Clone, Default, PartialEq, Eq, EnumIter, DeriveActiveEnum, Enum, Copy)] +#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "drop_type")] +pub enum DropType { + #[default] + #[sea_orm(string_value = "edition")] + Edition, + #[sea_orm(string_value = "open")] + Open, } diff --git a/api/src/events.rs b/api/src/events.rs index 8a2dd9a..bd73902 100644 --- a/api/src/events.rs +++ b/api/src/events.rs @@ -1,6 +1,7 @@ use hub_core::{ chrono::{DateTime, NaiveDateTime, Offset, Utc}, credits::{CreditsClient, TransactionId}, + metrics::KeyValue, prelude::*, producer::Producer, thiserror, @@ -26,6 +27,7 @@ use crate::{ sea_orm_active_enums::{Blockchain, CreationStatus}, switch_collection_histories, transfer_charges, update_histories, }, + metrics::Metrics, proto::{ nft_events::Event as NftEvent, polygon_nft_events::Event as PolygonNftEvents, @@ -71,6 +73,8 @@ pub enum ProcessorErrorKind { #[error("Database record contains no deduction ID")] RecordMissingDeductionId, + #[error("Database record contains no owner address")] + RecordMissingOwner, #[error("Invalid basis point value for seller fee")] #[permanent] @@ -111,6 +115,7 @@ pub struct Processor { pub db: Connection, pub credits: CreditsClient, pub producer: Producer, + pub metrics: Metrics, } #[derive(Clone)] @@ -149,14 +154,22 @@ impl Processor { db: Connection, credits: CreditsClient, producer: Producer, + metrics: Metrics, ) -> Self { Self { db, credits, producer, + metrics, } } + #[allow(clippy::too_many_lines)] + /// Processes incoming messages related to different services like Treasury and Solana. + /// Routes each message to the corresponding handler based on the type of service and the specific event. + + /// # Errors + /// - Returns an error wrapped in `ProcessorError` if any of the operations inside the function fail. pub async fn process(&self, msg: Services) -> Result<()> { match msg { Services::Treasury(TreasuryEventKey { id, .. }, e) => match e.event { @@ -188,8 +201,8 @@ impl Processor { e, ) => match e.event { Some( - SolanaNftsEvent::CreateDropSubmitted(payload) - | SolanaNftsEvent::RetryCreateDropSubmitted(payload), + SolanaNftsEvent::CreateEditionDropSubmitted(payload) + | SolanaNftsEvent::RetryCreateEditionDropSubmitted(payload), ) => { self.drop_created(id, MintResult::Success(payload.into())) .await @@ -202,8 +215,8 @@ impl Processor { .await }, Some( - SolanaNftsEvent::MintDropSubmitted(payload) - | SolanaNftsEvent::RetryMintDropSubmitted(payload), + SolanaNftsEvent::MintEditionDropSubmitted(payload) + | SolanaNftsEvent::RetryMintEditionDropSubmitted(payload), ) => { self.drop_minted(id, MintResult::Success(payload.into())) .await @@ -229,14 +242,14 @@ impl Processor { .await }, Some( - SolanaNftsEvent::CreateDropFailed(_) - | SolanaNftsEvent::RetryCreateDropFailed(_), + SolanaNftsEvent::CreateEditionDropFailed(_) + | SolanaNftsEvent::RetryCreateEditionDropFailed(_), ) => self.drop_created(id, MintResult::Failure).await, Some( SolanaNftsEvent::CreateCollectionFailed(_) | SolanaNftsEvent::RetryCreateCollectionFailed(_), ) => self.collection_created(id, MintResult::Failure).await, - Some(SolanaNftsEvent::MintDropFailed(_)) => { + Some(SolanaNftsEvent::MintEditionDropFailed(_)) => { self.drop_minted(id, MintResult::Failure).await }, Some( @@ -246,7 +259,7 @@ impl Processor { Some(SolanaNftsEvent::TransferAssetFailed(_)) => { self.mint_transferred(id, TransferResult::Failure).await }, - Some(SolanaNftsEvent::RetryMintDropFailed(_)) => { + Some(SolanaNftsEvent::RetryMintEditionDropFailed(_)) => { self.drop_minted(id, MintResult::Failure).await }, Some( @@ -271,6 +284,27 @@ impl Processor { ) .await }, + Some( + SolanaNftsEvent::CreateOpenDropSubmitted(payload) + | SolanaNftsEvent::RetryCreateOpenDropSubmitted(payload), + ) => { + self.drop_created(id, MintResult::Success(payload.into())) + .await + }, + Some( + SolanaNftsEvent::MintOpenDropSubmitted(payload) + | SolanaNftsEvent::RetryMintOpenDropSubmitted(payload), + ) => { + self.drop_minted(id, MintResult::Success(payload.into())) + .await + }, + Some( + SolanaNftsEvent::CreateOpenDropFailed(_) + | SolanaNftsEvent::RetryCreateOpenDropFailed(_), + ) => self.drop_created(id, MintResult::Failure).await, + Some(SolanaNftsEvent::MintOpenDropFailed(_)) => { + self.drop_minted(id, MintResult::Failure).await + }, None | Some(_) => Ok(()), }, Services::Polygon(_, e) => match e.event { @@ -390,7 +424,7 @@ impl Processor { id: Set(id.parse()?), collection_id: Set(collection_id.parse()?), address: Set(Some(mint_address)), - owner: Set(owner), + owner: Set(Some(owner)), creation_status: Set(CreationStatus::Created), created_by: Set(created_by.parse()?), created_at: Set(Utc::now().into()), @@ -400,7 +434,7 @@ impl Processor { .try_into() .map_err(ProcessorErrorKind::InvalidSellerFee)?), credits_deduction_id: Set(None), - compressed: Set(compressed), + compressed: Set(Some(compressed)), }; let mint_model = mint_am.insert(self.db.get()).await?; @@ -463,7 +497,7 @@ impl Processor { .ok_or(ProcessorErrorKind::DbMissingCollectionMint)?; let mut mint_am: collection_mints::ActiveModel = mint.into(); - mint_am.owner = Set(payload.recipient.clone()); + mint_am.owner = Set(Some(payload.recipient.clone())); mint_am.update(self.db.get()).await?; @@ -492,7 +526,7 @@ impl Processor { let created_at = timestamp .and_then(|t| { - Some(DateTime::from_utc( + Some(DateTime::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(t.seconds, t.nanos.try_into().ok()?)?, Utc.fix(), )) @@ -514,13 +548,13 @@ impl Processor { for mint in mints { let mut mint_am: collection_mints::ActiveModel = mint.clone().into(); - mint_am.owner = Set(new_owner.clone()); + mint_am.owner = Set(Some(new_owner.clone())); mint_am.update(&txn).await?; let nft_transfers = nft_transfers::ActiveModel { tx_signature: Set(Some(transaction_hash.clone())), collection_mint_id: Set(mint.id), - sender: Set(mint.owner), + sender: Set(mint.owner.ok_or(ProcessorErrorKind::RecordMissingOwner)?), recipient: Set(new_owner.clone()), created_at: Set(created_at), ..Default::default() @@ -787,6 +821,17 @@ impl Processor { creation_status = NftCreationStatus::Failed; } + let now = Utc::now(); + let elapsed = now + .signed_duration_since(collection_mint.created_at) + .num_milliseconds(); + self.metrics + .mint_duration_ms_bucket + .record(elapsed, &[KeyValue::new( + "status", + creation_status.as_str_name(), + )]); + self.producer .send( Some(&NftEvents { @@ -833,7 +878,8 @@ impl Processor { } async fn mint_updated(&self, id: String, payload: UpdateResult) -> ProcessResult<()> { - let update_history = UpdateHistories::find_by_id(id.parse()?) + let id: Uuid = id.parse()?; + let update_history = UpdateHistories::find_by_id(id) .one(self.db.get()) .await? .ok_or(ProcessorErrorKind::DbMissingUpdateHistory)?; diff --git a/api/src/handlers.rs b/api/src/handlers.rs index d1a32bb..5c3aa37 100644 --- a/api/src/handlers.rs +++ b/api/src/handlers.rs @@ -1,16 +1,22 @@ use async_graphql::http::{playground_source, GraphQLPlaygroundConfig}; use async_graphql_poem::{GraphQLRequest, GraphQLResponse}; -use hub_core::anyhow::Result; +use hub_core::{ + anyhow::Result, + metrics::{Encoder, TextEncoder}, +}; use poem::{ handler, + http::StatusCode, web::{Data, Html}, IntoResponse, }; -use crate::{AppContext, AppState, Balance, OrganizationId, UserID}; +use crate::{AppContext, AppState, Balance, Metrics, OrganizationId, UserID}; #[handler] -pub fn health() {} +pub fn health() -> StatusCode { + StatusCode::OK +} #[handler] pub fn playground() -> impl IntoResponse { @@ -42,3 +48,11 @@ pub async fn graphql_handler( .await .into()) } + +#[handler] +pub fn metrics_handler(Data(metrics): Data<&Metrics>) -> Result { + let mut buffer = vec![]; + let encoder = TextEncoder::new(); + encoder.encode(&metrics.registry.gather(), &mut buffer)?; + Ok(String::from_utf8_lossy(&buffer).into_owned()) +} diff --git a/api/src/lib.rs b/api/src/lib.rs index 7254b3c..51ea412 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -10,6 +10,7 @@ pub mod entities; pub mod events; pub mod handlers; pub mod metadata_json; +pub mod metrics; pub mod mutations; pub mod nft_storage; pub mod objects; @@ -26,7 +27,7 @@ use dataloaders::{ CollectionMintMintHistoryLoader, CollectionMintTransfersLoader, CollectionMintsLoader, CollectionMintsOwnerLoader, CreatorsLoader, DropLoader, DropMintHistoryLoader, HoldersLoader, MetadataJsonAttributesLoader, MetadataJsonLoader, MintCreatorsLoader, MinterMintHistoryLoader, - ProjectCollectionLoader, ProjectCollectionsLoader, ProjectDropsLoader, + ProjectCollectionLoader, ProjectCollectionsLoader, ProjectDropsLoader, QueuedMintsLoader, SwitchCollectionHistoryLoader, UpdateMintHistoryLoader, }; use db::Connection; @@ -41,6 +42,7 @@ use hub_core::{ tokio, uuid::Uuid, }; +use metrics::Metrics; use mutations::Mutation; use nft_storage::NftStorageClient; use poem::{async_trait, FromRequest, Request, RequestBody}; @@ -239,6 +241,7 @@ pub struct AppState { impl AppState { #[must_use] + #[allow(clippy::too_many_arguments)] pub fn new( schema: AppSchema, connection: Connection, @@ -288,10 +291,12 @@ pub struct AppContext { collection_mint_mint_history_loader: DataLoader, collection_mint_transfers_loader: DataLoader, switch_collection_history_loader: DataLoader, + queued_mints_loader: DataLoader, } impl AppContext { #[must_use] + #[allow(clippy::similar_names)] pub fn new( db: Connection, user_id: UserID, @@ -338,6 +343,8 @@ impl AppContext { DataLoader::new(CollectionMintTransfersLoader::new(db.clone()), tokio::spawn); let switch_collection_history_loader = DataLoader::new(SwitchCollectionHistoryLoader::new(db.clone()), tokio::spawn); + let queued_mints_loader = DataLoader::new(QueuedMintsLoader::new(db.clone()), tokio::spawn); + Self { db, user_id, @@ -364,6 +371,7 @@ impl AppContext { collection_mint_mint_history_loader, collection_mint_transfers_loader, switch_collection_history_loader, + queued_mints_loader, } } } diff --git a/api/src/main.rs b/api/src/main.rs index 15dcc7c..b7c3369 100644 --- a/api/src/main.rs +++ b/api/src/main.rs @@ -5,7 +5,8 @@ use holaplex_hub_nfts::{ build_schema, db::Connection, events, - handlers::{graphql_handler, health, playground}, + handlers::{graphql_handler, health, metrics_handler, playground}, + metrics::Metrics, nft_storage::NftStorageClient, proto, Actions, AppState, Args, Services, }; @@ -38,8 +39,15 @@ pub fn main() { .await?; let credits = common.credits_cfg.build::().await?; let nft_storage = NftStorageClient::new(nft_storage)?; - let event_processor = - events::Processor::new(connection.clone(), credits.clone(), producer.clone()); + + let metrics = Metrics::new()?; + + let event_processor = events::Processor::new( + connection.clone(), + credits.clone(), + producer.clone(), + metrics.clone(), + ); let solana = Solana::new(producer.clone()); let polygon = Polygon::new(producer.clone()); @@ -72,9 +80,13 @@ pub fn main() { Server::new(TcpListener::bind(format!("0.0.0.0:{port}"))) .run( Route::new() - .at("/graphql", post(graphql_handler).with(AddData::new(state))) + .at( + "/graphql", + post(graphql_handler).with(AddData::new(state.clone())), + ) .at("/playground", get(playground)) - .at("/health", get(health)), + .at("/health", get(health)) + .at("/metrics", get(metrics_handler).with(AddData::new(metrics))), ) .await .context("failed to build graphql server") diff --git a/api/src/metrics.rs b/api/src/metrics.rs new file mode 100644 index 0000000..9533325 --- /dev/null +++ b/api/src/metrics.rs @@ -0,0 +1,47 @@ +#[allow(clippy::wildcard_imports)] +use hub_core::{ + anyhow::{anyhow, Result}, + metrics::*, +}; + +#[derive(Clone)] +pub struct Metrics { + pub registry: Registry, + pub provider: MeterProvider, + pub mint_duration_ms_bucket: Histogram, +} + +impl Metrics { + /// Res + /// # Errors + pub fn new() -> Result { + let registry = Registry::new(); + let exporter = hub_core::metrics::exporter() + .with_registry(registry.clone()) + .with_namespace("hub_nfts") + .build() + .map_err(|e| anyhow!("Failed to build exporter: {}", e))?; + + let provider = MeterProvider::builder() + .with_reader(exporter) + .with_resource(Resource::new(vec![KeyValue::new( + "service.name", + "hub-nfts", + )])) + .build(); + + let meter = provider.meter("hub-nfts"); + + let mint_duration_ms_bucket = meter + .i64_histogram("mint.time") + .with_unit(Unit::new("ms")) + .with_description("Mint duration time in milliseconds.") + .init(); + + Ok(Self { + registry, + provider, + mint_duration_ms_bucket, + }) + } +} diff --git a/api/src/mutations/collection.rs b/api/src/mutations/collection.rs index f7ad8cb..d1c0476 100644 --- a/api/src/mutations/collection.rs +++ b/api/src/mutations/collection.rs @@ -5,11 +5,11 @@ use hub_core::{ chrono::Utc, credits::{CreditsClient, TransactionId}, producer::Producer, + util::ValidateAddress, }; use reqwest::Url; use sea_orm::{prelude::*, ModelTrait, Set, TransactionTrait}; use serde::{Deserialize, Serialize}; -use solana_program::pubkey::Pubkey; use crate::{ blockchains::{polygon::Polygon, solana::Solana, CollectionEvent}, @@ -521,7 +521,7 @@ impl Mutation { return Err(Error::new("New collection must be Metaplex Certified")); } - if mint.compressed == true { + if Some(true) == mint.compressed { return Err(Error::new( "Switching collection is only supported for uncompressed mint", )); @@ -577,6 +577,11 @@ impl Mutation { } } +/// Fetches the owner's wallet address for a given project and blockchain. +/// # Returns +/// - Returns a `Result` containing the wallet address of the owner if the operation is successful. +/// # Errors +/// - Returns an error if no project wallet is found for the specified blockchain. pub async fn fetch_owner( conn: &DatabaseConnection, project: Uuid, @@ -593,7 +598,7 @@ pub async fn fetch_owner( let owner = wallet .ok_or(Error::new(format!( - "no project wallet found for {blockchain} blockchain" + "no project wallet found for {blockchain:?} blockchain" )))? .wallet_address; Ok(owner) @@ -634,6 +639,10 @@ impl CreateCollectionInput { } } +/// Validates the Solana creator verification based on project treasury wallet address and the list of creators. +/// # Errors +/// - Returns an error if any of the creators are verified but their address does not match +/// the project treasury wallet address. pub fn validate_solana_creator_verification( project_treasury_wallet_address: &str, creators: &Vec, @@ -695,8 +704,11 @@ pub fn validate_creators(blockchain: BlockchainEnum, creators: &Vec) -> Ok(()) } +/// Validates a Solana address +/// # Errors +/// - Returns an error if the provided address is not a valid Solana address. pub fn validate_solana_address(address: &str) -> Result<()> { - if Pubkey::from_str(address).is_err() { + if !ValidateAddress::is_solana_address(&address) { return Err(Error::new(format!( "{address} is not a valid Solana address" ))); @@ -705,22 +717,12 @@ pub fn validate_solana_address(address: &str) -> Result<()> { Ok(()) } +/// Validates an EVM (Ethereum Virtual Machine) address format. +/// # Errors +/// - Returns an error if the provided address does not match the required EVM address format. pub fn validate_evm_address(address: &str) -> Result<()> { - let err = Err(Error::new(format!("{address} is not a valid EVM address"))); - - // Ethereum address must start with '0x' - if !address.starts_with("0x") { - return err; - } - - // Ethereum address must be exactly 40 characters long after removing '0x' - if address.len() != 42 { - return err; - } - - // Check that the address contains only hexadecimal characters - if !address[2..].chars().all(|c| c.is_ascii_hexdigit()) { - return err; + if !ValidateAddress::is_evm_address(&address) { + return Err(Error::new(format!("{address} is not a valid EVM address"))); } Ok(()) diff --git a/api/src/mutations/drop.rs b/api/src/mutations/drop.rs index 71e0a64..63882aa 100644 --- a/api/src/mutations/drop.rs +++ b/api/src/mutations/drop.rs @@ -15,7 +15,7 @@ use crate::{ collection_creators, collections, drops, metadata_jsons, prelude::{CollectionCreators, Collections, Drops, MetadataJsons}, project_wallets, - sea_orm_active_enums::{Blockchain as BlockchainEnum, CreationStatus}, + sea_orm_active_enums::{Blockchain as BlockchainEnum, CreationStatus, DropType}, }, metadata_json::MetadataJson, objects::{Creator, Drop, MetadataJsonInput}, @@ -63,7 +63,11 @@ impl Mutation { let nfts_producer = ctx.data::>()?; let owner_address = fetch_owner(conn, input.project, input.blockchain).await?; - + let supply = if input.drop_type == DropType::Open { + Some(0) + } else { + input.supply.map(TryInto::try_into).transpose()? + }; input.validate()?; if input.blockchain == BlockchainEnum::Solana { @@ -84,7 +88,7 @@ impl Mutation { let collection_am = collections::ActiveModel { blockchain: Set(input.blockchain), - supply: Set(input.supply.map(TryFrom::try_from).transpose()?), + supply: Set(supply), creation_status: Set(CreationStatus::Pending), seller_fee_basis_points: Set(seller_fee_basis_points.try_into()?), created_by: Set(user_id), @@ -98,7 +102,14 @@ impl Mutation { .save(db) .await?; - let metadata_json = MetadataJson::new(input.metadata_json) + let metadata_jsons::Model { + name, + symbol, + uri, + description, + image, + .. + } = MetadataJson::new(input.metadata_json) .upload(nft_storage) .await? .save(collection.id, db) @@ -114,6 +125,7 @@ impl Mutation { created_by: Set(user_id), created_at: Set(Utc::now().into()), credits_deduction_id: Set(Some(credits_deduction_id)), + drop_type: Set(input.drop_type), ..Default::default() }; @@ -124,47 +136,54 @@ impl Mutation { project_id: input.project.to_string(), }; + let payload = proto::MetaplexMasterEditionTransaction { + master_edition: Some(proto::MasterEdition { + owner_address: owner_address.clone(), + supply, + name: name.clone(), + symbol, + metadata_uri: uri.clone(), + seller_fee_basis_points: seller_fee_basis_points.into(), + creators: input + .creators + .clone() + .into_iter() + .map(TryFrom::try_from) + .collect::>()?, + }), + }; + match input.blockchain { BlockchainEnum::Solana => { solana .event() - .create_drop(event_key, proto::MetaplexMasterEditionTransaction { - master_edition: Some(proto::MasterEdition { - owner_address, - supply: input.supply.map(TryInto::try_into).transpose()?, - name: metadata_json.name, - symbol: metadata_json.symbol, - metadata_uri: metadata_json.uri, - seller_fee_basis_points: seller_fee_basis_points.into(), - creators: input - .creators - .into_iter() - .map(TryFrom::try_from) - .collect::>()?, - }), - }) + .create_drop(input.drop_type, event_key, payload) .await?; }, BlockchainEnum::Polygon => { let amount = input.supply.ok_or(Error::new("supply is required"))?; polygon - .create_drop(event_key, proto::CreateEditionTransaction { - amount: amount.try_into()?, - edition_info: Some(proto::EditionInfo { - creator: input - .creators - .get(0) - .ok_or(Error::new("creator is required"))? - .clone() - .address, - collection: metadata_json.name, - uri: metadata_json.uri, - description: metadata_json.description, - image_uri: metadata_json.image, - }), - fee_receiver: owner_address.clone(), - fee_numerator: seller_fee_basis_points.into(), - }) + .create_drop( + input.drop_type, + event_key, + proto::CreateEditionTransaction { + amount: amount.try_into()?, + edition_info: Some(proto::EditionInfo { + creator: input + .creators + .get(0) + .ok_or(Error::new("creator is required"))? + .clone() + .address, + collection: name, + uri, + description, + image_uri: image, + }), + fee_receiver: owner_address, + fee_numerator: seller_fee_basis_points.into(), + }, + ) .await?; }, BlockchainEnum::Ethereum => { @@ -269,24 +288,28 @@ impl Mutation { BlockchainEnum::Solana => { solana .event() - .retry_create_drop(event_key, proto::MetaplexMasterEditionTransaction { - master_edition: Some(proto::MasterEdition { - owner_address, - supply: collection.supply.map(TryInto::try_into).transpose()?, - name: metadata_json.name, - symbol: metadata_json.symbol, - metadata_uri: metadata_json.uri, - seller_fee_basis_points: collection.seller_fee_basis_points.into(), - creators: creators - .into_iter() - .map(|c| proto::Creator { - address: c.address, - verified: c.verified, - share: c.share, - }) - .collect(), - }), - }) + .retry_create_drop( + drop.drop_type, + event_key, + proto::MetaplexMasterEditionTransaction { + master_edition: Some(proto::MasterEdition { + owner_address, + supply: collection.supply.map(TryInto::try_into).transpose()?, + name: metadata_json.name, + symbol: metadata_json.symbol, + metadata_uri: metadata_json.uri, + seller_fee_basis_points: collection.seller_fee_basis_points.into(), + creators: creators + .into_iter() + .map(|c| proto::Creator { + address: c.address, + verified: c.verified, + share: c.share, + }) + .collect(), + }), + }, + ) .await?; }, BlockchainEnum::Polygon => { @@ -296,7 +319,7 @@ impl Mutation { polygon .event() - .retry_create_drop(event_key, proto::CreateEditionTransaction { + .retry_create_drop(drop.drop_type, event_key, proto::CreateEditionTransaction { edition_info: None, amount, fee_receiver: owner_address, @@ -569,17 +592,21 @@ impl Mutation { solana .event() - .update_drop(event_key, proto::MetaplexMasterEditionTransaction { - master_edition: Some(proto::MasterEdition { - owner_address, - supply: collection.supply.map(TryInto::try_into).transpose()?, - name: metadata_json_model.name, - symbol: metadata_json_model.symbol, - metadata_uri: metadata_json_model.uri, - seller_fee_basis_points: collection.seller_fee_basis_points.into(), - creators, - }), - }) + .update_drop( + drop_model.drop_type, + event_key, + proto::MetaplexMasterEditionTransaction { + master_edition: Some(proto::MasterEdition { + owner_address, + supply: collection.supply.map(TryInto::try_into).transpose()?, + name: metadata_json_model.name, + symbol: metadata_json_model.symbol, + metadata_uri: metadata_json_model.uri, + seller_fee_basis_points: collection.seller_fee_basis_points.into(), + creators, + }), + }, + ) .await?; }, BlockchainEnum::Polygon => { @@ -595,15 +622,19 @@ impl Mutation { polygon .event() - .update_drop(event_key, proto::UpdateEdtionTransaction { - edition_info: Some(EditionInfo { - description: metadata_json_model.description, - image_uri: metadata_json_model.image, - collection: metadata_json_model.name, - uri: metadata_json_model.uri, - creator, - }), - }) + .update_drop( + drop_model.drop_type, + event_key, + proto::UpdateEdtionTransaction { + edition_info: Some(EditionInfo { + description: metadata_json_model.description, + image_uri: metadata_json_model.image, + collection: metadata_json_model.name, + uri: metadata_json_model.uri, + creator, + }), + }, + ) .await?; }, BlockchainEnum::Ethereum => { @@ -633,7 +664,7 @@ async fn fetch_owner( let owner = wallet .ok_or(Error::new(format!( - "no project wallet found for {blockchain} blockchain" + "no project wallet found for {blockchain:?} blockchain" )))? .wallet_address; Ok(owner) @@ -644,7 +675,7 @@ pub struct CreateDropPayload { drop: Drop, } -#[derive(Debug, Clone, Serialize, Deserialize, InputObject)] +#[derive(Debug, Clone, InputObject)] pub struct CreateDropInput { pub project: Uuid, pub price: Option, @@ -655,6 +686,8 @@ pub struct CreateDropInput { pub blockchain: BlockchainEnum, pub creators: Vec, pub metadata_json: MetadataJsonInput, + #[graphql(name = "type", default)] + pub drop_type: DropType, } impl CreateDropInput { @@ -670,7 +703,7 @@ impl CreateDropInput { /// # Errors /// - Err with an appropriate error message if any validation fails. pub fn validate(&self) -> Result<()> { - if self.supply == Some(0) { + if self.supply == Some(0) && self.drop_type == DropType::Edition { return Err(Error::new("Supply must be greater than 0 or undefined")); }; diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index 263bd3a..94a4b45 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -6,16 +6,24 @@ use hub_core::{ credits::{CreditsClient, TransactionId}, producer::Producer, }; -use sea_orm::{prelude::*, JoinType, QuerySelect, Set, TransactionTrait}; +use sea_orm::{ + prelude::*, + sea_query::{Func, SimpleExpr}, + JoinType, Order, QueryOrder, QuerySelect, Set, TransactionTrait, +}; use super::collection::{ fetch_owner, validate_creators, validate_json, validate_solana_creator_verification, }; use crate::{ - blockchains::{polygon::Polygon, solana::Solana, CollectionEvent, DropEvent}, + blockchains::{ + polygon::Polygon, + solana::{MintDropTransaction, Solana}, + CollectionEvent, DropEvent, + }, entities::{ - collection_mints, collections, drops, mint_creators, mint_histories, - prelude::{CollectionMints, Collections, Drops}, + collection_creators, collection_mints, collections, drops, mint_creators, mint_histories, + prelude::{CollectionCreators, CollectionMints, Collections, Drops}, project_wallets, sea_orm_active_enums::{Blockchain as BlockchainEnum, CreationStatus}, update_histories, @@ -96,7 +104,7 @@ impl Mutation { let owner_address = wallet .ok_or(Error::new(format!( - "no project wallet found for {} blockchain", + "no project wallet found for {:?} blockchain", collection.blockchain )))? .wallet_address; @@ -114,7 +122,7 @@ impl Mutation { // insert a collection mint record into database let collection_mint_active_model = collection_mints::ActiveModel { collection_id: Set(collection.id), - owner: Set(input.recipient.clone()), + owner: Set(Some(input.recipient.clone())), creation_status: Set(CreationStatus::Pending), seller_fee_basis_points: Set(collection.seller_fee_basis_points), created_by: Set(user_id), @@ -139,12 +147,15 @@ impl Mutation { solana .event() - .mint_drop(event_key, proto::MintMetaplexEditionTransaction { - recipient_address: input.recipient.to_string(), - owner_address: owner_address.to_string(), - edition, - collection_id: collection.id.to_string(), - }) + .mint_drop( + event_key, + MintDropTransaction::Edition(proto::MintMetaplexEditionTransaction { + recipient_address: input.recipient.to_string(), + owner_address: owner_address.to_string(), + edition, + collection_id: collection.id.to_string(), + }), + ) .await?; }, BlockchainEnum::Polygon => { @@ -253,7 +264,11 @@ impl Mutation { let drop_model = drop.ok_or(Error::new("drop not found"))?; - let recipient = collection_mint_model.owner.clone(); + let recipient = collection_mint_model + .owner + .clone() + .ok_or(Error::new("collection mint does not have an owner"))?; + let edition = collection_mint_model.edition; let project_id = drop_model.project_id; @@ -269,7 +284,7 @@ impl Mutation { let owner_address = wallet .ok_or(Error::new(format!( - "no project wallet found for {} blockchain", + "no project wallet found for {:?} blockchain", collection.blockchain )))? .wallet_address; @@ -294,12 +309,15 @@ impl Mutation { BlockchainEnum::Solana => { solana .event() - .retry_mint_drop(event_key, proto::MintMetaplexEditionTransaction { - recipient_address: recipient.to_string(), - owner_address: owner_address.to_string(), - edition, - collection_id: collection.id.to_string(), - }) + .retry_mint_drop( + event_key, + MintDropTransaction::Edition(proto::MintMetaplexEditionTransaction { + recipient_address: recipient.to_string(), + owner_address: owner_address.to_string(), + edition, + collection_id: collection.id.to_string(), + }), + ) .await?; }, BlockchainEnum::Polygon => { @@ -398,11 +416,11 @@ impl Mutation { // insert a collection mint record into database let collection_mint_active_model = collection_mints::ActiveModel { collection_id: Set(collection.id), - owner: Set(input.recipient.clone()), + owner: Set(Some(input.recipient.clone())), creation_status: Set(CreationStatus::Pending), seller_fee_basis_points: Set(collection.seller_fee_basis_points), created_by: Set(user_id), - compressed: Set(compressed), + compressed: Set(Some(compressed)), credits_deduction_id: Set(Some(credits_deduction_id)), ..Default::default() }; @@ -542,7 +560,7 @@ impl Mutation { return Err(Error::new("Mint is an edition and cannot be updated")); } - if mint.compressed { + if Some(true) == mint.compressed { return Err(Error::new("Mint is compressed and cannot be updated")); } @@ -726,7 +744,8 @@ impl Mutation { }) } - // Retries a mint which failed by passing its ID. + /// Retries a mint which failed by passing its ID. + /// # Errors pub async fn retry_mint_to_collection( &self, ctx: &Context<'_>, @@ -764,9 +783,16 @@ impl Mutation { let collection = collection.ok_or(Error::new("collection not found"))?; - let recipient = collection_mint_model.owner.clone(); + let recipient = collection_mint_model + .owner + .clone() + .ok_or(Error::new("collection mint does not have an owner"))?; + let project_id = collection.project_id; let blockchain = collection.blockchain; + let compressed = collection_mint_model.compressed.ok_or(Error::new( + "collection mint does not have a compressed value", + ))?; let owner_address = fetch_owner(conn, project_id, blockchain).await?; @@ -810,7 +836,7 @@ impl Mutation { creators: creators.into_iter().map(Into::into).collect(), }), recipient_address: recipient.to_string(), - compressed: collection_mint_model.compressed, + compressed, collection_id: collection_mint_model.collection_id.to_string(), }) .await?; @@ -824,6 +850,399 @@ impl Mutation { collection_mint: collection_mint_model.into(), }) } + + // Add a mint to the queue for a drop. + // The queued mint can be minted by calling `mint_queued` mutation for specific mint + // or `mint_random_queued_to_drop` for random mint. + async fn queue_mint_to_drop( + &self, + ctx: &Context<'_>, + input: QueueMintToDropInput, + ) -> Result { + let AppContext { db, user_id, .. } = ctx.data::()?; + + let conn = db.get(); + let nft_storage = ctx.data::()?; + let nfts_producer = ctx.data::>()?; + + let UserID(id) = user_id; + let user_id = id.ok_or(Error::new("X-USER-ID header not found"))?; + + let (drop, collection) = drops::Entity::find_by_id(input.drop) + .find_also_related(Collections) + .one(conn) + .await? + .ok_or(Error::new("drop not found"))?; + + let collection_model = collection.ok_or(Error::new("collection not found"))?; + + let mut collection_am: collections::ActiveModel = collection_model.clone().into(); + + collection_am.supply = Set(collection_model.supply.map(|supply| supply.add(1))); + + collection_am.update(conn).await?; + + let mint = collection_mints::ActiveModel { + collection_id: Set(drop.collection_id), + owner: Set(None), + creation_status: Set(CreationStatus::Queued), + created_by: Set(user_id), + compressed: Set(None), + seller_fee_basis_points: Set(collection_model.seller_fee_basis_points), + ..Default::default() + }; + + let mint_model = mint.insert(conn).await?; + + MetadataJson::new(input.metadata_json) + .upload(nft_storage) + .await? + .save(mint_model.id, db) + .await?; + + let creators = CollectionCreators::find() + .filter(collection_creators::Column::CollectionId.eq(collection_model.id)) + .all(conn) + .await?; + + let mint_creators: Vec<_> = creators + .iter() + .map(|creator| mint_creators::ActiveModel { + collection_mint_id: Set(mint_model.id), + address: Set(creator.address.clone()), + verified: Set(creator.verified), + share: Set(creator.share), + }) + .collect(); + + mint_creators::Entity::insert_many(mint_creators) + .exec(conn) + .await?; + + nfts_producer + .send( + Some(&NftEvents { + event: Some(NftEvent::DropMinted(MintCreation { + drop_id: drop.id.to_string(), + status: NftCreationStatus::Queued as i32, + })), + }), + Some(&NftEventKey { + id: mint_model.id.to_string(), + project_id: drop.project_id.to_string(), + user_id: user_id.to_string(), + }), + ) + .await?; + + Ok(QueueMintToDropPayload { + collection_mint: mint_model.into(), + }) + } + + /// This mutation mints a specific queued drop mint. + async fn mint_queued( + &self, + ctx: &Context<'_>, + input: MintQueuedInput, + ) -> Result { + let AppContext { + db, + user_id, + organization_id, + balance, + .. + } = ctx.data::()?; + let credits = ctx.data::>()?; + let conn = db.get(); + let solana = ctx.data::()?; + let nfts_producer = ctx.data::>()?; + + let UserID(id) = user_id; + let OrganizationId(org) = organization_id; + + let user_id = id.ok_or(Error::new("X-USER-ID header not found"))?; + let org_id = org.ok_or(Error::new("X-ORGANIZATION-ID header not found"))?; + let balance = balance + .0 + .ok_or(Error::new("X-CREDIT-BALANCE header not found"))?; + + let (mint, collection) = collection_mints::Entity::find_by_id_with_collection(input.mint) + .one(conn) + .await? + .ok_or(Error::new("collection mint not found"))?; + + if mint.creation_status != CreationStatus::Queued { + return Err(Error::new("mint is not queued")); + } + + let collection = collection.ok_or(Error::new("collection not found"))?; + + let project_id = collection.project_id; + let blockchain = collection.blockchain; + + let owner_address = fetch_owner(conn, project_id, blockchain).await?; + + let MetadataJson { + metadata_json, uri, .. + } = MetadataJson::fetch(mint.id, db).await?; + + let event_key = NftEventKey { + id: mint.id.to_string(), + user_id: user_id.to_string(), + project_id: project_id.to_string(), + }; + + let creators = mint_creators::Entity::find_by_collection_mint_id(mint.id) + .all(conn) + .await?; + + let action = if input.compressed { + Actions::MintCompressed + } else { + Actions::Mint + }; + + let TransactionId(deduction_id) = credits + .submit_pending_deduction( + org_id, + user_id, + action, + collection.blockchain.into(), + balance, + ) + .await?; + + let mut collection_am = collections::ActiveModel::from(collection.clone()); + collection_am.total_mints = Set(collection.total_mints.add(1)); + collection_am.update(conn).await?; + + let mut mint_am: collection_mints::ActiveModel = mint.into(); + + mint_am.creation_status = Set(CreationStatus::Pending); + mint_am.credits_deduction_id = Set(Some(deduction_id)); + mint_am.compressed = Set(Some(input.compressed)); + mint_am.owner = Set(Some(input.recipient.clone())); + mint_am.seller_fee_basis_points = Set(collection.seller_fee_basis_points); + + let mint = mint_am.update(conn).await?; + + match collection.blockchain { + BlockchainEnum::Solana => { + solana + .event() + .mint_drop( + event_key, + MintDropTransaction::Open(proto::MintMetaplexMetadataTransaction { + metadata: Some(MetaplexMetadata { + owner_address, + name: metadata_json.name, + symbol: metadata_json.symbol, + metadata_uri: uri + .ok_or(Error::new("No metadata json uri found"))?, + seller_fee_basis_points: mint.seller_fee_basis_points.into(), + creators: creators.into_iter().map(Into::into).collect(), + }), + recipient_address: input.recipient.to_string(), + compressed: input.compressed, + collection_id: collection.id.to_string(), + }), + ) + .await?; + }, + BlockchainEnum::Ethereum | BlockchainEnum::Polygon => { + return Err(Error::new("blockchain not supported as this time")); + }, + }; + + let drop = drops::Entity::find() + .filter(drops::Column::CollectionId.eq(collection.id)) + .one(conn) + .await? + .ok_or(Error::new("drop not found"))?; + + nfts_producer + .send( + Some(&NftEvents { + event: Some(NftEvent::DropMinted(MintCreation { + drop_id: drop.id.to_string(), + status: NftCreationStatus::InProgress as i32, + })), + }), + Some(&NftEventKey { + id: mint.id.to_string(), + project_id: drop.project_id.to_string(), + user_id: user_id.to_string(), + }), + ) + .await?; + + let mint_history_am = mint_histories::ActiveModel { + mint_id: Set(mint.id), + wallet: Set(input.recipient), + collection_id: Set(collection.id), + tx_signature: Set(None), + status: Set(CreationStatus::Pending), + created_at: Set(Utc::now().into()), + ..Default::default() + }; + + mint_history_am.insert(conn).await?; + + Ok(MintQueuedPayload { + collection_mint: mint.into(), + }) + } + + /// This mutation mints a random queued drop mint. + async fn mint_random_queued_to_drop( + &self, + ctx: &Context<'_>, + input: MintRandomQueuedInput, + ) -> Result { + let AppContext { + db, + user_id, + organization_id, + balance, + .. + } = ctx.data::()?; + let credits = ctx.data::>()?; + let conn = db.get(); + let solana = ctx.data::()?; + let nfts_producer = ctx.data::>()?; + + let UserID(id) = user_id; + let OrganizationId(org) = organization_id; + + let user_id = id.ok_or(Error::new("X-USER-ID header not found"))?; + let org_id = org.ok_or(Error::new("X-ORGANIZATION-ID header not found"))?; + let balance = balance + .0 + .ok_or(Error::new("X-CREDIT-BALANCE header not found"))?; + + let drop = drops::Entity::find_by_id(input.drop) + .one(conn) + .await? + .ok_or(Error::new("drop not found"))?; + + let (mint, collection) = CollectionMints::find() + .join( + JoinType::InnerJoin, + collection_mints::Relation::Collections.def(), + ) + .select_also(collections::Entity) + .filter(collection_mints::Column::CollectionId.eq(drop.collection_id)) + .filter(collection_mints::Column::CreationStatus.eq(CreationStatus::Queued)) + .order_by(SimpleExpr::FunctionCall(Func::random()), Order::Asc) + .one(conn) + .await? + .ok_or(Error::new("No Queued mint found for the drop"))?; + + let collection = collection.ok_or(Error::new("collection not found"))?; + + let project_id = collection.project_id; + let blockchain = collection.blockchain; + + let owner_address = fetch_owner(conn, project_id, blockchain).await?; + + let MetadataJson { + metadata_json, uri, .. + } = MetadataJson::fetch(mint.id, db).await?; + + let event_key = NftEventKey { + id: mint.id.to_string(), + user_id: user_id.to_string(), + project_id: project_id.to_string(), + }; + + let creators = mint_creators::Entity::find_by_collection_mint_id(mint.id) + .all(conn) + .await?; + + let TransactionId(deduction_id) = credits + .submit_pending_deduction( + org_id, + user_id, + Actions::Mint, + collection.blockchain.into(), + balance, + ) + .await?; + + let mut collection_am = collections::ActiveModel::from(collection.clone()); + collection_am.total_mints = Set(collection.total_mints.add(1)); + collection_am.update(conn).await?; + + let mut mint_am: collection_mints::ActiveModel = mint.into(); + + mint_am.creation_status = Set(CreationStatus::Pending); + mint_am.credits_deduction_id = Set(Some(deduction_id)); + mint_am.compressed = Set(Some(input.compressed)); + mint_am.owner = Set(Some(input.recipient.clone())); + mint_am.seller_fee_basis_points = Set(collection.seller_fee_basis_points); + + let mint = mint_am.update(conn).await?; + + match collection.blockchain { + BlockchainEnum::Solana => { + solana + .event() + .mint_drop( + event_key, + MintDropTransaction::Open(proto::MintMetaplexMetadataTransaction { + metadata: Some(MetaplexMetadata { + owner_address, + name: metadata_json.name, + symbol: metadata_json.symbol, + metadata_uri: uri.ok_or(Error::new("No metadata json uri"))?, + seller_fee_basis_points: mint.seller_fee_basis_points.into(), + creators: creators.into_iter().map(Into::into).collect(), + }), + recipient_address: input.recipient.to_string(), + compressed: input.compressed, + collection_id: collection.id.to_string(), + }), + ) + .await?; + }, + BlockchainEnum::Ethereum | BlockchainEnum::Polygon => { + return Err(Error::new("blockchain not supported as this time")); + }, + }; + + let mint_history_am = mint_histories::ActiveModel { + mint_id: Set(mint.id), + wallet: Set(input.recipient), + collection_id: Set(collection.id), + tx_signature: Set(None), + status: Set(CreationStatus::Pending), + created_at: Set(Utc::now().into()), + ..Default::default() + }; + + mint_history_am.insert(conn).await?; + + nfts_producer + .send( + Some(&NftEvents { + event: Some(NftEvent::DropMinted(MintCreation { + drop_id: drop.id.to_string(), + status: NftCreationStatus::InProgress as i32, + })), + }), + Some(&NftEventKey { + id: mint.id.to_string(), + project_id: drop.project_id.to_string(), + user_id: user_id.to_string(), + }), + ) + .await?; + + Ok(MintQueuedPayload { + collection_mint: mint.into(), + }) + } } fn validate_compress(blockchain: BlockchainEnum, compressed: bool) -> Result<(), Error> { @@ -973,3 +1392,38 @@ pub struct RetryUpdateMintInput { pub struct RetryUpdateMintPayload { status: CreationStatus, } + +/// Represents input data for `queue_mint_to_drop` mutation +#[derive(Debug, Clone, InputObject)] +pub struct QueueMintToDropInput { + drop: Uuid, + metadata_json: MetadataJsonInput, +} + +/// Represents payload data for `queue_mint_to_drop` mutation +#[derive(Debug, Clone, SimpleObject)] +pub struct QueueMintToDropPayload { + collection_mint: CollectionMint, +} + +/// Represents input data for `mint_queued` mutation +#[derive(Debug, Clone, InputObject)] +pub struct MintQueuedInput { + mint: Uuid, + recipient: String, + compressed: bool, +} + +/// Represents payload data for `mint_queued` mutation +#[derive(Debug, Clone, SimpleObject)] +pub struct MintQueuedPayload { + collection_mint: CollectionMint, +} + +/// Represents input data for `mint_random_queued` mutation +#[derive(Debug, Clone, InputObject)] +pub struct MintRandomQueuedInput { + drop: Uuid, + recipient: String, + compressed: bool, +} diff --git a/api/src/mutations/transfer.rs b/api/src/mutations/transfer.rs index 98ea103..5da8778 100644 --- a/api/src/mutations/transfer.rs +++ b/api/src/mutations/transfer.rs @@ -64,7 +64,10 @@ impl Mutation { let collection = collection.ok_or(Error::new("collection not found"))?; input.validate_recipient_address(collection.blockchain)?; - let owner_address = collection_mint_model.owner.clone(); + let owner_address = collection_mint_model + .owner + .clone() + .ok_or(Error::new("NFT is not owned by any wallet"))?; CustomerWallets::find_by_address(owner_address.clone()) .one(conn) diff --git a/api/src/objects/collection_mint.rs b/api/src/objects/collection_mint.rs index a7c6b21..8893cd6 100644 --- a/api/src/objects/collection_mint.rs +++ b/api/src/objects/collection_mint.rs @@ -25,7 +25,7 @@ pub struct CollectionMint { /// On EVM chains it is the concatenation of the contract address and the token id `{contractAddress}:{tokenId}`. pub address: Option, /// The wallet address of the owner of the NFT. - pub owner: String, + pub owner: Option, /// The status of the NFT creation. pub creation_status: CreationStatus, /// The unique ID of the creator of the NFT. @@ -41,7 +41,7 @@ pub struct CollectionMint { /// credits deduction id pub credits_deduction_id: Option, /// Indicates if the NFT is compressed. Compression is only supported on Solana. - pub compressed: bool, + pub compressed: Option, } #[ComplexObject] diff --git a/api/src/objects/drop.rs b/api/src/objects/drop.rs index 2231872..500aed5 100644 --- a/api/src/objects/drop.rs +++ b/api/src/objects/drop.rs @@ -1,10 +1,13 @@ -use async_graphql::{Context, Enum, Object, Result}; +use async_graphql::{Context, Enum, Error, Object, Result}; use hub_core::chrono::Utc; use sea_orm::entity::prelude::*; -use super::Collection; +use super::{Collection, CollectionMint}; use crate::{ - entities::{collections, drops, mint_histories, sea_orm_active_enums::CreationStatus}, + entities::{ + collections, drops, mint_histories, + sea_orm_active_enums::{CreationStatus, DropType}, + }, AppContext, }; /// An NFT campaign that controls the minting rules for a collection, such as its start date and end date. @@ -28,6 +31,11 @@ impl Drop { self.drop.id } + // The type of the drop. + async fn drop_type(&self) -> DropType { + self.drop.drop_type + } + /// The identifier of the project to which the drop is associated. async fn project_id(&self) -> Uuid { self.drop.project_id @@ -88,10 +96,11 @@ impl Drop { let paused_at = self.drop.paused_at; let shutdown_at = self.drop.shutdown_at; + let total_mints = self.collection.total_mints; let minted = self .collection .supply - .map(|supply| supply == self.collection.total_mints); + .map(|supply| supply == total_mints && total_mints > 0); match ( scheduled, @@ -121,9 +130,19 @@ impl Drop { (_, _, Some(false), ..) | (_, _, None, _, _, CreationStatus::Created) => { Ok(DropStatus::Minting) }, + (_, _, _, _, _, CreationStatus::Queued) => Err(Error::new("Invalid Drop Status")), } } + async fn queued_mints(&self, ctx: &Context<'_>) -> Result>> { + let AppContext { + queued_mints_loader, + .. + } = ctx.data::()?; + + queued_mints_loader.load_one(self.drop.id).await + } + #[graphql(deprecation = "Use `mint_histories` under `Collection` Object instead.")] /// A list of all NFT purchases from this drop. async fn purchases(&self, ctx: &Context<'_>) -> Result>> { diff --git a/api/src/objects/holder.rs b/api/src/objects/holder.rs index e33aed4..c417a7d 100644 --- a/api/src/objects/holder.rs +++ b/api/src/objects/holder.rs @@ -31,7 +31,7 @@ impl Holder { .unwrap_or_default(); Ok(mints.into_iter().fold(Vec::new(), |mut acc, mint| { - if mint.owner == self.address { + if mint.owner == Some(self.address.clone()) { acc.push(mint.id); } diff --git a/migration/Cargo.toml b/migration/Cargo.toml index 3a06bbc..6ab8d30 100644 --- a/migration/Cargo.toml +++ b/migration/Cargo.toml @@ -22,11 +22,11 @@ name = "migration" [dependencies] -tokio = { version = "1.22.0", features = ["macros"] } +tokio = { version = "1.32.0", features = ["macros"] } [dependencies.sea-orm-migration] -version = "^0.10.0" +version = "0.12.2" features = [ "runtime-tokio-rustls", - "sqlx-postgres", -] + "sqlx-postgres", +] \ No newline at end of file diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 5ec6e56..46e80fd 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -53,6 +53,11 @@ mod m20230725_144506_drop_solana_collections_table; mod m20230807_090847_create_histories_table; mod m20230818_163948_downcase_polygon_addresses; mod m20230821_131630_create_switch_collection_histories_table; +mod m20230905_100852_add_type_to_drop; +mod m20230910_204731_add_queued_variant_to_mints_status; +mod m20230910_212742_make_owner_address_optional_for_mint; +mod m20230911_144938_make_compressed_column_optional; +mod m20230915_111128_create_mints_creation_status_idx; pub struct Migrator; @@ -113,6 +118,11 @@ impl MigratorTrait for Migrator { Box::new(m20230807_090847_create_histories_table::Migration), Box::new(m20230818_163948_downcase_polygon_addresses::Migration), Box::new(m20230821_131630_create_switch_collection_histories_table::Migration), + Box::new(m20230905_100852_add_type_to_drop::Migration), + Box::new(m20230910_204731_add_queued_variant_to_mints_status::Migration), + Box::new(m20230910_212742_make_owner_address_optional_for_mint::Migration), + Box::new(m20230911_144938_make_compressed_column_optional::Migration), + Box::new(m20230915_111128_create_mints_creation_status_idx::Migration), ] } } diff --git a/migration/src/m20230905_100852_add_type_to_drop.rs b/migration/src/m20230905_100852_add_type_to_drop.rs new file mode 100644 index 0000000..7db9fdb --- /dev/null +++ b/migration/src/m20230905_100852_add_type_to_drop.rs @@ -0,0 +1,66 @@ +use sea_orm_migration::{prelude::*, sea_query::extension::postgres::Type}; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_type( + Type::create() + .as_enum(DropType::Type) + .values([DropType::Edition, DropType::Open]) + .to_owned(), + ) + .await?; + + manager + .alter_table( + Table::alter() + .table(Drops::Table) + .add_column_if_not_exists( + ColumnDef::new(Drops::DropType) + .custom(DropType::Type) + .default("edition") + .not_null(), + ) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(Drops::Table) + .drop_column(Drops::DropType) + .to_owned(), + ) + .await + } +} + +#[derive(Iden)] +enum Drops { + Table, + DropType, +} + +pub enum DropType { + Type, + Edition, + Open, +} + +impl Iden for DropType { + fn unquoted(&self, s: &mut dyn std::fmt::Write) { + write!(s, "{}", match self { + Self::Type => "drop_type", + Self::Edition => "edition", + Self::Open => "open", + }) + .unwrap(); + } +} diff --git a/migration/src/m20230910_204731_add_queued_variant_to_mints_status.rs b/migration/src/m20230910_204731_add_queued_variant_to_mints_status.rs new file mode 100644 index 0000000..e2b4095 --- /dev/null +++ b/migration/src/m20230910_204731_add_queued_variant_to_mints_status.rs @@ -0,0 +1,24 @@ +use sea_orm_migration::{prelude::*, sea_query::extension::postgres::Type}; + +use crate::m20230214_212301_create_collections_table::CreationStatus; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_type( + Type::alter() + .name(CreationStatus::Type) + .add_value(Alias::new("queued")) + .to_owned(), + ) + .await + } + + async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { + Ok(()) + } +} diff --git a/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs b/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs new file mode 100644 index 0000000..93dc88f --- /dev/null +++ b/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs @@ -0,0 +1,35 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(CollectionMints::Table) + .modify_column(ColumnDef::new(CollectionMints::Owner).text().null()) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(CollectionMints::Table) + .modify_column(ColumnDef::new(CollectionMints::Owner).text().not_null()) + .to_owned(), + ) + .await + } +} + +#[derive(Iden)] +enum CollectionMints { + Table, + Owner, +} diff --git a/migration/src/m20230911_144938_make_compressed_column_optional.rs b/migration/src/m20230911_144938_make_compressed_column_optional.rs new file mode 100644 index 0000000..a4305cf --- /dev/null +++ b/migration/src/m20230911_144938_make_compressed_column_optional.rs @@ -0,0 +1,39 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(CollectionMints::Table) + .modify_column(ColumnDef::new(CollectionMints::Compressed).boolean().null()) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(CollectionMints::Table) + .modify_column( + ColumnDef::new(CollectionMints::Compressed) + .boolean() + .not_null(), + ) + .to_owned(), + ) + .await + } +} + +#[derive(Iden)] +enum CollectionMints { + Table, + Compressed, +} diff --git a/migration/src/m20230915_111128_create_mints_creation_status_idx.rs b/migration/src/m20230915_111128_create_mints_creation_status_idx.rs new file mode 100644 index 0000000..5b603af --- /dev/null +++ b/migration/src/m20230915_111128_create_mints_creation_status_idx.rs @@ -0,0 +1,26 @@ +use sea_orm_migration::prelude::*; + +use crate::m20230220_223223_create_collection_mints_table::CollectionMints; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_index( + IndexCreateStatement::new() + .name("collection-mints-creation-status-idx") + .table(CollectionMints::Table) + .col(CollectionMints::CreationStatus) + .index_type(IndexType::BTree) + .to_owned(), + ) + .await + } + + async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { + Ok(()) + } +}