Parakeet is a Rust-based Bluesky AppView aiming to implement most of the functionality required to support the Bluesky client

feat(consumer): validate handles on #identity events

yes i did write an atproto handle resolver lmao

Changed files
+1179 -25
consumer
did-resolver
+912 -13
Cargo.lock
··· 109 109 ] 110 110 111 111 [[package]] 112 + name = "atomic-waker" 113 + version = "1.1.2" 114 + source = "registry+https://github.com/rust-lang/crates.io-index" 115 + checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 116 + 117 + [[package]] 112 118 name = "autocfg" 113 119 version = "1.4.0" 114 120 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 126 132 "miniz_oxide", 127 133 "object", 128 134 "rustc-demangle", 129 - "windows-targets", 135 + "windows-targets 0.52.6", 130 136 ] 131 137 132 138 [[package]] ··· 216 222 "num-traits", 217 223 "serde", 218 224 "wasm-bindgen", 219 - "windows-targets", 225 + "windows-targets 0.52.6", 220 226 ] 221 227 222 228 [[package]] ··· 312 318 dependencies = [ 313 319 "chrono", 314 320 "ciborium", 321 + "did-resolver", 315 322 "diesel", 316 323 "diesel-async", 317 324 "eyre", ··· 459 466 checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" 460 467 461 468 [[package]] 469 + name = "did-resolver" 470 + version = "0.1.0" 471 + dependencies = [ 472 + "hickory-resolver", 473 + "reqwest", 474 + "serde", 475 + "serde_json", 476 + "thiserror 2.0.11", 477 + ] 478 + 479 + [[package]] 462 480 name = "diesel" 463 481 version = "2.2.6" 464 482 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 521 539 ] 522 540 523 541 [[package]] 542 + name = "displaydoc" 543 + version = "0.2.5" 544 + source = "registry+https://github.com/rust-lang/crates.io-index" 545 + checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 546 + dependencies = [ 547 + "proc-macro2", 548 + "quote", 549 + "syn", 550 + ] 551 + 552 + [[package]] 524 553 name = "dsl_auto_type" 525 554 version = "0.1.2" 526 555 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 539 568 version = "1.13.0" 540 569 source = "registry+https://github.com/rust-lang/crates.io-index" 541 570 checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 571 + 572 + [[package]] 573 + name = "encoding_rs" 574 + version = "0.8.35" 575 + source = "registry+https://github.com/rust-lang/crates.io-index" 576 + checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" 577 + dependencies = [ 578 + "cfg-if", 579 + ] 580 + 581 + [[package]] 582 + name = "enum-as-inner" 583 + version = "0.6.1" 584 + source = "registry+https://github.com/rust-lang/crates.io-index" 585 + checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" 586 + dependencies = [ 587 + "heck", 588 + "proc-macro2", 589 + "quote", 590 + "syn", 591 + ] 542 592 543 593 [[package]] 544 594 name = "equivalent" ··· 614 664 checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 615 665 616 666 [[package]] 667 + name = "form_urlencoded" 668 + version = "1.2.1" 669 + source = "registry+https://github.com/rust-lang/crates.io-index" 670 + checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 671 + dependencies = [ 672 + "percent-encoding", 673 + ] 674 + 675 + [[package]] 617 676 name = "futures" 618 677 version = "0.3.31" 619 678 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 730 789 checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 731 790 732 791 [[package]] 792 + name = "h2" 793 + version = "0.4.7" 794 + source = "registry+https://github.com/rust-lang/crates.io-index" 795 + checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" 796 + dependencies = [ 797 + "atomic-waker", 798 + "bytes", 799 + "fnv", 800 + "futures-core", 801 + "futures-sink", 802 + "http", 803 + "indexmap", 804 + "slab", 805 + "tokio", 806 + "tokio-util", 807 + "tracing", 808 + ] 809 + 810 + [[package]] 733 811 name = "half" 734 812 version = "2.4.1" 735 813 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 758 836 checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 759 837 760 838 [[package]] 839 + name = "hickory-proto" 840 + version = "0.24.2" 841 + source = "registry+https://github.com/rust-lang/crates.io-index" 842 + checksum = "447afdcdb8afb9d0a852af6dc65d9b285ce720ed7a59e42a8bf2e931c67bc1b5" 843 + dependencies = [ 844 + "async-trait", 845 + "cfg-if", 846 + "data-encoding", 847 + "enum-as-inner", 848 + "futures-channel", 849 + "futures-io", 850 + "futures-util", 851 + "idna", 852 + "ipnet", 853 + "once_cell", 854 + "rand", 855 + "thiserror 1.0.69", 856 + "tinyvec", 857 + "tokio", 858 + "tracing", 859 + "url", 860 + ] 861 + 862 + [[package]] 863 + name = "hickory-resolver" 864 + version = "0.24.2" 865 + source = "registry+https://github.com/rust-lang/crates.io-index" 866 + checksum = "0a2e2aba9c389ce5267d31cf1e4dace82390ae276b0b364ea55630b1fa1b44b4" 867 + dependencies = [ 868 + "cfg-if", 869 + "futures-util", 870 + "hickory-proto", 871 + "ipconfig", 872 + "lru-cache", 873 + "once_cell", 874 + "parking_lot", 875 + "rand", 876 + "resolv-conf", 877 + "smallvec", 878 + "thiserror 1.0.69", 879 + "tokio", 880 + "tracing", 881 + ] 882 + 883 + [[package]] 761 884 name = "hmac" 762 885 version = "0.12.1" 763 886 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 767 890 ] 768 891 769 892 [[package]] 893 + name = "hostname" 894 + version = "0.3.1" 895 + source = "registry+https://github.com/rust-lang/crates.io-index" 896 + checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" 897 + dependencies = [ 898 + "libc", 899 + "match_cfg", 900 + "winapi", 901 + ] 902 + 903 + [[package]] 770 904 name = "http" 771 905 version = "1.2.0" 772 906 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 778 912 ] 779 913 780 914 [[package]] 915 + name = "http-body" 916 + version = "1.0.1" 917 + source = "registry+https://github.com/rust-lang/crates.io-index" 918 + checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 919 + dependencies = [ 920 + "bytes", 921 + "http", 922 + ] 923 + 924 + [[package]] 925 + name = "http-body-util" 926 + version = "0.1.2" 927 + source = "registry+https://github.com/rust-lang/crates.io-index" 928 + checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 929 + dependencies = [ 930 + "bytes", 931 + "futures-util", 932 + "http", 933 + "http-body", 934 + "pin-project-lite", 935 + ] 936 + 937 + [[package]] 781 938 name = "httparse" 782 939 version = "1.9.5" 783 940 source = "registry+https://github.com/rust-lang/crates.io-index" 784 941 checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" 785 942 786 943 [[package]] 944 + name = "hyper" 945 + version = "1.6.0" 946 + source = "registry+https://github.com/rust-lang/crates.io-index" 947 + checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 948 + dependencies = [ 949 + "bytes", 950 + "futures-channel", 951 + "futures-util", 952 + "h2", 953 + "http", 954 + "http-body", 955 + "httparse", 956 + "itoa", 957 + "pin-project-lite", 958 + "smallvec", 959 + "tokio", 960 + "want", 961 + ] 962 + 963 + [[package]] 964 + name = "hyper-rustls" 965 + version = "0.27.5" 966 + source = "registry+https://github.com/rust-lang/crates.io-index" 967 + checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" 968 + dependencies = [ 969 + "futures-util", 970 + "http", 971 + "hyper", 972 + "hyper-util", 973 + "rustls", 974 + "rustls-pki-types", 975 + "tokio", 976 + "tokio-rustls", 977 + "tower-service", 978 + ] 979 + 980 + [[package]] 981 + name = "hyper-tls" 982 + version = "0.6.0" 983 + source = "registry+https://github.com/rust-lang/crates.io-index" 984 + checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" 985 + dependencies = [ 986 + "bytes", 987 + "http-body-util", 988 + "hyper", 989 + "hyper-util", 990 + "native-tls", 991 + "tokio", 992 + "tokio-native-tls", 993 + "tower-service", 994 + ] 995 + 996 + [[package]] 997 + name = "hyper-util" 998 + version = "0.1.10" 999 + source = "registry+https://github.com/rust-lang/crates.io-index" 1000 + checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" 1001 + dependencies = [ 1002 + "bytes", 1003 + "futures-channel", 1004 + "futures-util", 1005 + "http", 1006 + "http-body", 1007 + "hyper", 1008 + "pin-project-lite", 1009 + "socket2", 1010 + "tokio", 1011 + "tower-service", 1012 + "tracing", 1013 + ] 1014 + 1015 + [[package]] 787 1016 name = "iana-time-zone" 788 1017 version = "0.1.61" 789 1018 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 807 1036 ] 808 1037 809 1038 [[package]] 1039 + name = "icu_collections" 1040 + version = "1.5.0" 1041 + source = "registry+https://github.com/rust-lang/crates.io-index" 1042 + checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 1043 + dependencies = [ 1044 + "displaydoc", 1045 + "yoke", 1046 + "zerofrom", 1047 + "zerovec", 1048 + ] 1049 + 1050 + [[package]] 1051 + name = "icu_locid" 1052 + version = "1.5.0" 1053 + source = "registry+https://github.com/rust-lang/crates.io-index" 1054 + checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 1055 + dependencies = [ 1056 + "displaydoc", 1057 + "litemap", 1058 + "tinystr", 1059 + "writeable", 1060 + "zerovec", 1061 + ] 1062 + 1063 + [[package]] 1064 + name = "icu_locid_transform" 1065 + version = "1.5.0" 1066 + source = "registry+https://github.com/rust-lang/crates.io-index" 1067 + checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 1068 + dependencies = [ 1069 + "displaydoc", 1070 + "icu_locid", 1071 + "icu_locid_transform_data", 1072 + "icu_provider", 1073 + "tinystr", 1074 + "zerovec", 1075 + ] 1076 + 1077 + [[package]] 1078 + name = "icu_locid_transform_data" 1079 + version = "1.5.0" 1080 + source = "registry+https://github.com/rust-lang/crates.io-index" 1081 + checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 1082 + 1083 + [[package]] 1084 + name = "icu_normalizer" 1085 + version = "1.5.0" 1086 + source = "registry+https://github.com/rust-lang/crates.io-index" 1087 + checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 1088 + dependencies = [ 1089 + "displaydoc", 1090 + "icu_collections", 1091 + "icu_normalizer_data", 1092 + "icu_properties", 1093 + "icu_provider", 1094 + "smallvec", 1095 + "utf16_iter", 1096 + "utf8_iter", 1097 + "write16", 1098 + "zerovec", 1099 + ] 1100 + 1101 + [[package]] 1102 + name = "icu_normalizer_data" 1103 + version = "1.5.0" 1104 + source = "registry+https://github.com/rust-lang/crates.io-index" 1105 + checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 1106 + 1107 + [[package]] 1108 + name = "icu_properties" 1109 + version = "1.5.1" 1110 + source = "registry+https://github.com/rust-lang/crates.io-index" 1111 + checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 1112 + dependencies = [ 1113 + "displaydoc", 1114 + "icu_collections", 1115 + "icu_locid_transform", 1116 + "icu_properties_data", 1117 + "icu_provider", 1118 + "tinystr", 1119 + "zerovec", 1120 + ] 1121 + 1122 + [[package]] 1123 + name = "icu_properties_data" 1124 + version = "1.5.0" 1125 + source = "registry+https://github.com/rust-lang/crates.io-index" 1126 + checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 1127 + 1128 + [[package]] 1129 + name = "icu_provider" 1130 + version = "1.5.0" 1131 + source = "registry+https://github.com/rust-lang/crates.io-index" 1132 + checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 1133 + dependencies = [ 1134 + "displaydoc", 1135 + "icu_locid", 1136 + "icu_provider_macros", 1137 + "stable_deref_trait", 1138 + "tinystr", 1139 + "writeable", 1140 + "yoke", 1141 + "zerofrom", 1142 + "zerovec", 1143 + ] 1144 + 1145 + [[package]] 1146 + name = "icu_provider_macros" 1147 + version = "1.5.0" 1148 + source = "registry+https://github.com/rust-lang/crates.io-index" 1149 + checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 1150 + dependencies = [ 1151 + "proc-macro2", 1152 + "quote", 1153 + "syn", 1154 + ] 1155 + 1156 + [[package]] 810 1157 name = "ident_case" 811 1158 version = "1.0.1" 812 1159 source = "registry+https://github.com/rust-lang/crates.io-index" 813 1160 checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 814 1161 815 1162 [[package]] 1163 + name = "idna" 1164 + version = "1.0.3" 1165 + source = "registry+https://github.com/rust-lang/crates.io-index" 1166 + checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 1167 + dependencies = [ 1168 + "idna_adapter", 1169 + "smallvec", 1170 + "utf8_iter", 1171 + ] 1172 + 1173 + [[package]] 1174 + name = "idna_adapter" 1175 + version = "1.2.0" 1176 + source = "registry+https://github.com/rust-lang/crates.io-index" 1177 + checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 1178 + dependencies = [ 1179 + "icu_normalizer", 1180 + "icu_properties", 1181 + ] 1182 + 1183 + [[package]] 816 1184 name = "indenter" 817 1185 version = "0.3.3" 818 1186 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 835 1203 checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" 836 1204 837 1205 [[package]] 1206 + name = "ipconfig" 1207 + version = "0.3.2" 1208 + source = "registry+https://github.com/rust-lang/crates.io-index" 1209 + checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" 1210 + dependencies = [ 1211 + "socket2", 1212 + "widestring", 1213 + "windows-sys 0.48.0", 1214 + "winreg", 1215 + ] 1216 + 1217 + [[package]] 838 1218 name = "ipld-core" 839 1219 version = "0.4.1" 840 1220 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 844 1224 "serde", 845 1225 "serde_bytes", 846 1226 ] 1227 + 1228 + [[package]] 1229 + name = "ipnet" 1230 + version = "2.11.0" 1231 + source = "registry+https://github.com/rust-lang/crates.io-index" 1232 + checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" 847 1233 848 1234 [[package]] 849 1235 name = "iroh-car" ··· 896 1282 checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" 897 1283 898 1284 [[package]] 1285 + name = "linked-hash-map" 1286 + version = "0.5.6" 1287 + source = "registry+https://github.com/rust-lang/crates.io-index" 1288 + checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 1289 + 1290 + [[package]] 899 1291 name = "linux-raw-sys" 900 1292 version = "0.4.15" 901 1293 source = "registry+https://github.com/rust-lang/crates.io-index" 902 1294 checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 1295 + 1296 + [[package]] 1297 + name = "litemap" 1298 + version = "0.7.4" 1299 + source = "registry+https://github.com/rust-lang/crates.io-index" 1300 + checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" 903 1301 904 1302 [[package]] 905 1303 name = "lock_api" ··· 918 1316 checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" 919 1317 920 1318 [[package]] 1319 + name = "lru-cache" 1320 + version = "0.1.2" 1321 + source = "registry+https://github.com/rust-lang/crates.io-index" 1322 + checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" 1323 + dependencies = [ 1324 + "linked-hash-map", 1325 + ] 1326 + 1327 + [[package]] 1328 + name = "match_cfg" 1329 + version = "0.1.0" 1330 + source = "registry+https://github.com/rust-lang/crates.io-index" 1331 + checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" 1332 + 1333 + [[package]] 921 1334 name = "md-5" 922 1335 version = "0.10.6" 923 1336 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 934 1347 checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 935 1348 936 1349 [[package]] 1350 + name = "mime" 1351 + version = "0.3.17" 1352 + source = "registry+https://github.com/rust-lang/crates.io-index" 1353 + checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 1354 + 1355 + [[package]] 937 1356 name = "miniz_oxide" 938 1357 version = "0.8.3" 939 1358 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1142 1561 "libc", 1143 1562 "redox_syscall", 1144 1563 "smallvec", 1145 - "windows-targets", 1564 + "windows-targets 0.52.6", 1146 1565 ] 1147 1566 1148 1567 [[package]] ··· 1271 1690 ] 1272 1691 1273 1692 [[package]] 1693 + name = "quick-error" 1694 + version = "1.2.3" 1695 + source = "registry+https://github.com/rust-lang/crates.io-index" 1696 + checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 1697 + 1698 + [[package]] 1274 1699 name = "quote" 1275 1700 version = "1.0.38" 1276 1701 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1319 1744 ] 1320 1745 1321 1746 [[package]] 1747 + name = "reqwest" 1748 + version = "0.12.12" 1749 + source = "registry+https://github.com/rust-lang/crates.io-index" 1750 + checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" 1751 + dependencies = [ 1752 + "base64", 1753 + "bytes", 1754 + "encoding_rs", 1755 + "futures-core", 1756 + "futures-util", 1757 + "h2", 1758 + "http", 1759 + "http-body", 1760 + "http-body-util", 1761 + "hyper", 1762 + "hyper-rustls", 1763 + "hyper-tls", 1764 + "hyper-util", 1765 + "ipnet", 1766 + "js-sys", 1767 + "log", 1768 + "mime", 1769 + "native-tls", 1770 + "once_cell", 1771 + "percent-encoding", 1772 + "pin-project-lite", 1773 + "rustls-pemfile", 1774 + "serde", 1775 + "serde_json", 1776 + "serde_urlencoded", 1777 + "sync_wrapper", 1778 + "system-configuration", 1779 + "tokio", 1780 + "tokio-native-tls", 1781 + "tower", 1782 + "tower-service", 1783 + "url", 1784 + "wasm-bindgen", 1785 + "wasm-bindgen-futures", 1786 + "web-sys", 1787 + "windows-registry", 1788 + ] 1789 + 1790 + [[package]] 1791 + name = "resolv-conf" 1792 + version = "0.7.0" 1793 + source = "registry+https://github.com/rust-lang/crates.io-index" 1794 + checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" 1795 + dependencies = [ 1796 + "hostname", 1797 + "quick-error", 1798 + ] 1799 + 1800 + [[package]] 1801 + name = "ring" 1802 + version = "0.17.8" 1803 + source = "registry+https://github.com/rust-lang/crates.io-index" 1804 + checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 1805 + dependencies = [ 1806 + "cc", 1807 + "cfg-if", 1808 + "getrandom", 1809 + "libc", 1810 + "spin", 1811 + "untrusted", 1812 + "windows-sys 0.52.0", 1813 + ] 1814 + 1815 + [[package]] 1322 1816 name = "rustc-demangle" 1323 1817 version = "0.1.24" 1324 1818 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1338 1832 ] 1339 1833 1340 1834 [[package]] 1835 + name = "rustls" 1836 + version = "0.23.22" 1837 + source = "registry+https://github.com/rust-lang/crates.io-index" 1838 + checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7" 1839 + dependencies = [ 1840 + "once_cell", 1841 + "rustls-pki-types", 1842 + "rustls-webpki", 1843 + "subtle", 1844 + "zeroize", 1845 + ] 1846 + 1847 + [[package]] 1848 + name = "rustls-pemfile" 1849 + version = "2.2.0" 1850 + source = "registry+https://github.com/rust-lang/crates.io-index" 1851 + checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" 1852 + dependencies = [ 1853 + "rustls-pki-types", 1854 + ] 1855 + 1856 + [[package]] 1857 + name = "rustls-pki-types" 1858 + version = "1.11.0" 1859 + source = "registry+https://github.com/rust-lang/crates.io-index" 1860 + checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" 1861 + 1862 + [[package]] 1863 + name = "rustls-webpki" 1864 + version = "0.102.8" 1865 + source = "registry+https://github.com/rust-lang/crates.io-index" 1866 + checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 1867 + dependencies = [ 1868 + "ring", 1869 + "rustls-pki-types", 1870 + "untrusted", 1871 + ] 1872 + 1873 + [[package]] 1341 1874 name = "rustversion" 1342 1875 version = "1.0.19" 1343 1876 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1468 2001 ] 1469 2002 1470 2003 [[package]] 2004 + name = "serde_urlencoded" 2005 + version = "0.7.1" 2006 + source = "registry+https://github.com/rust-lang/crates.io-index" 2007 + checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 2008 + dependencies = [ 2009 + "form_urlencoded", 2010 + "itoa", 2011 + "ryu", 2012 + "serde", 2013 + ] 2014 + 2015 + [[package]] 1471 2016 name = "sha1" 1472 2017 version = "0.10.6" 1473 2018 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1545 2090 ] 1546 2091 1547 2092 [[package]] 2093 + name = "spin" 2094 + version = "0.9.8" 2095 + source = "registry+https://github.com/rust-lang/crates.io-index" 2096 + checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 2097 + 2098 + [[package]] 2099 + name = "stable_deref_trait" 2100 + version = "1.2.0" 2101 + source = "registry+https://github.com/rust-lang/crates.io-index" 2102 + checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 2103 + 2104 + [[package]] 1548 2105 name = "stringprep" 1549 2106 version = "0.1.5" 1550 2107 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1579 2136 ] 1580 2137 1581 2138 [[package]] 2139 + name = "sync_wrapper" 2140 + version = "1.0.2" 2141 + source = "registry+https://github.com/rust-lang/crates.io-index" 2142 + checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 2143 + dependencies = [ 2144 + "futures-core", 2145 + ] 2146 + 2147 + [[package]] 2148 + name = "synstructure" 2149 + version = "0.13.1" 2150 + source = "registry+https://github.com/rust-lang/crates.io-index" 2151 + checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 2152 + dependencies = [ 2153 + "proc-macro2", 2154 + "quote", 2155 + "syn", 2156 + ] 2157 + 2158 + [[package]] 2159 + name = "system-configuration" 2160 + version = "0.6.1" 2161 + source = "registry+https://github.com/rust-lang/crates.io-index" 2162 + checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" 2163 + dependencies = [ 2164 + "bitflags", 2165 + "core-foundation", 2166 + "system-configuration-sys", 2167 + ] 2168 + 2169 + [[package]] 2170 + name = "system-configuration-sys" 2171 + version = "0.6.0" 2172 + source = "registry+https://github.com/rust-lang/crates.io-index" 2173 + checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" 2174 + dependencies = [ 2175 + "core-foundation-sys", 2176 + "libc", 2177 + ] 2178 + 2179 + [[package]] 1582 2180 name = "tempfile" 1583 2181 version = "3.15.0" 1584 2182 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1643 2241 ] 1644 2242 1645 2243 [[package]] 2244 + name = "tinystr" 2245 + version = "0.7.6" 2246 + source = "registry+https://github.com/rust-lang/crates.io-index" 2247 + checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 2248 + dependencies = [ 2249 + "displaydoc", 2250 + "zerovec", 2251 + ] 2252 + 2253 + [[package]] 1646 2254 name = "tinyvec" 1647 2255 version = "1.8.1" 1648 2256 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1723 2331 ] 1724 2332 1725 2333 [[package]] 2334 + name = "tokio-rustls" 2335 + version = "0.26.1" 2336 + source = "registry+https://github.com/rust-lang/crates.io-index" 2337 + checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" 2338 + dependencies = [ 2339 + "rustls", 2340 + "tokio", 2341 + ] 2342 + 2343 + [[package]] 1726 2344 name = "tokio-tungstenite" 1727 2345 version = "0.26.1" 1728 2346 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1784 2402 ] 1785 2403 1786 2404 [[package]] 2405 + name = "tower" 2406 + version = "0.5.2" 2407 + source = "registry+https://github.com/rust-lang/crates.io-index" 2408 + checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 2409 + dependencies = [ 2410 + "futures-core", 2411 + "futures-util", 2412 + "pin-project-lite", 2413 + "sync_wrapper", 2414 + "tokio", 2415 + "tower-layer", 2416 + "tower-service", 2417 + ] 2418 + 2419 + [[package]] 2420 + name = "tower-layer" 2421 + version = "0.3.3" 2422 + source = "registry+https://github.com/rust-lang/crates.io-index" 2423 + checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 2424 + 2425 + [[package]] 2426 + name = "tower-service" 2427 + version = "0.3.3" 2428 + source = "registry+https://github.com/rust-lang/crates.io-index" 2429 + checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 2430 + 2431 + [[package]] 1787 2432 name = "tracing" 1788 2433 version = "0.1.41" 1789 2434 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1841 2486 ] 1842 2487 1843 2488 [[package]] 2489 + name = "try-lock" 2490 + version = "0.2.5" 2491 + source = "registry+https://github.com/rust-lang/crates.io-index" 2492 + checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 2493 + 2494 + [[package]] 1844 2495 name = "tungstenite" 1845 2496 version = "0.26.1" 1846 2497 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1914 2565 checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" 1915 2566 1916 2567 [[package]] 2568 + name = "untrusted" 2569 + version = "0.9.0" 2570 + source = "registry+https://github.com/rust-lang/crates.io-index" 2571 + checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 2572 + 2573 + [[package]] 2574 + name = "url" 2575 + version = "2.5.4" 2576 + source = "registry+https://github.com/rust-lang/crates.io-index" 2577 + checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 2578 + dependencies = [ 2579 + "form_urlencoded", 2580 + "idna", 2581 + "percent-encoding", 2582 + ] 2583 + 2584 + [[package]] 1917 2585 name = "utf-8" 1918 2586 version = "0.7.6" 1919 2587 source = "registry+https://github.com/rust-lang/crates.io-index" 1920 2588 checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 2589 + 2590 + [[package]] 2591 + name = "utf16_iter" 2592 + version = "1.0.5" 2593 + source = "registry+https://github.com/rust-lang/crates.io-index" 2594 + checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 2595 + 2596 + [[package]] 2597 + name = "utf8_iter" 2598 + version = "1.0.4" 2599 + source = "registry+https://github.com/rust-lang/crates.io-index" 2600 + checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 1921 2601 1922 2602 [[package]] 1923 2603 name = "utf8parse" ··· 1954 2634 ] 1955 2635 1956 2636 [[package]] 2637 + name = "want" 2638 + version = "0.3.1" 2639 + source = "registry+https://github.com/rust-lang/crates.io-index" 2640 + checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 2641 + dependencies = [ 2642 + "try-lock", 2643 + ] 2644 + 2645 + [[package]] 1957 2646 name = "wasi" 1958 2647 version = "0.11.0+wasi-snapshot-preview1" 1959 2648 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1989 2678 "quote", 1990 2679 "syn", 1991 2680 "wasm-bindgen-shared", 2681 + ] 2682 + 2683 + [[package]] 2684 + name = "wasm-bindgen-futures" 2685 + version = "0.4.50" 2686 + source = "registry+https://github.com/rust-lang/crates.io-index" 2687 + checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" 2688 + dependencies = [ 2689 + "cfg-if", 2690 + "js-sys", 2691 + "once_cell", 2692 + "wasm-bindgen", 2693 + "web-sys", 1992 2694 ] 1993 2695 1994 2696 [[package]] ··· 2045 2747 ] 2046 2748 2047 2749 [[package]] 2750 + name = "widestring" 2751 + version = "1.1.0" 2752 + source = "registry+https://github.com/rust-lang/crates.io-index" 2753 + checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" 2754 + 2755 + [[package]] 2048 2756 name = "winapi" 2049 2757 version = "0.3.9" 2050 2758 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2081 2789 source = "registry+https://github.com/rust-lang/crates.io-index" 2082 2790 checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 2083 2791 dependencies = [ 2084 - "windows-targets", 2792 + "windows-targets 0.52.6", 2793 + ] 2794 + 2795 + [[package]] 2796 + name = "windows-registry" 2797 + version = "0.2.0" 2798 + source = "registry+https://github.com/rust-lang/crates.io-index" 2799 + checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" 2800 + dependencies = [ 2801 + "windows-result", 2802 + "windows-strings", 2803 + "windows-targets 0.52.6", 2804 + ] 2805 + 2806 + [[package]] 2807 + name = "windows-result" 2808 + version = "0.2.0" 2809 + source = "registry+https://github.com/rust-lang/crates.io-index" 2810 + checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" 2811 + dependencies = [ 2812 + "windows-targets 0.52.6", 2813 + ] 2814 + 2815 + [[package]] 2816 + name = "windows-strings" 2817 + version = "0.1.0" 2818 + source = "registry+https://github.com/rust-lang/crates.io-index" 2819 + checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" 2820 + dependencies = [ 2821 + "windows-result", 2822 + "windows-targets 0.52.6", 2823 + ] 2824 + 2825 + [[package]] 2826 + name = "windows-sys" 2827 + version = "0.48.0" 2828 + source = "registry+https://github.com/rust-lang/crates.io-index" 2829 + checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2830 + dependencies = [ 2831 + "windows-targets 0.48.5", 2085 2832 ] 2086 2833 2087 2834 [[package]] ··· 2090 2837 source = "registry+https://github.com/rust-lang/crates.io-index" 2091 2838 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2092 2839 dependencies = [ 2093 - "windows-targets", 2840 + "windows-targets 0.52.6", 2094 2841 ] 2095 2842 2096 2843 [[package]] ··· 2099 2846 source = "registry+https://github.com/rust-lang/crates.io-index" 2100 2847 checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2101 2848 dependencies = [ 2102 - "windows-targets", 2849 + "windows-targets 0.52.6", 2850 + ] 2851 + 2852 + [[package]] 2853 + name = "windows-targets" 2854 + version = "0.48.5" 2855 + source = "registry+https://github.com/rust-lang/crates.io-index" 2856 + checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2857 + dependencies = [ 2858 + "windows_aarch64_gnullvm 0.48.5", 2859 + "windows_aarch64_msvc 0.48.5", 2860 + "windows_i686_gnu 0.48.5", 2861 + "windows_i686_msvc 0.48.5", 2862 + "windows_x86_64_gnu 0.48.5", 2863 + "windows_x86_64_gnullvm 0.48.5", 2864 + "windows_x86_64_msvc 0.48.5", 2103 2865 ] 2104 2866 2105 2867 [[package]] ··· 2108 2870 source = "registry+https://github.com/rust-lang/crates.io-index" 2109 2871 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2110 2872 dependencies = [ 2111 - "windows_aarch64_gnullvm", 2112 - "windows_aarch64_msvc", 2113 - "windows_i686_gnu", 2873 + "windows_aarch64_gnullvm 0.52.6", 2874 + "windows_aarch64_msvc 0.52.6", 2875 + "windows_i686_gnu 0.52.6", 2114 2876 "windows_i686_gnullvm", 2115 - "windows_i686_msvc", 2116 - "windows_x86_64_gnu", 2117 - "windows_x86_64_gnullvm", 2118 - "windows_x86_64_msvc", 2877 + "windows_i686_msvc 0.52.6", 2878 + "windows_x86_64_gnu 0.52.6", 2879 + "windows_x86_64_gnullvm 0.52.6", 2880 + "windows_x86_64_msvc 0.52.6", 2119 2881 ] 2120 2882 2121 2883 [[package]] 2122 2884 name = "windows_aarch64_gnullvm" 2885 + version = "0.48.5" 2886 + source = "registry+https://github.com/rust-lang/crates.io-index" 2887 + checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2888 + 2889 + [[package]] 2890 + name = "windows_aarch64_gnullvm" 2123 2891 version = "0.52.6" 2124 2892 source = "registry+https://github.com/rust-lang/crates.io-index" 2125 2893 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2126 2894 2127 2895 [[package]] 2128 2896 name = "windows_aarch64_msvc" 2897 + version = "0.48.5" 2898 + source = "registry+https://github.com/rust-lang/crates.io-index" 2899 + checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2900 + 2901 + [[package]] 2902 + name = "windows_aarch64_msvc" 2129 2903 version = "0.52.6" 2130 2904 source = "registry+https://github.com/rust-lang/crates.io-index" 2131 2905 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2132 2906 2133 2907 [[package]] 2134 2908 name = "windows_i686_gnu" 2909 + version = "0.48.5" 2910 + source = "registry+https://github.com/rust-lang/crates.io-index" 2911 + checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2912 + 2913 + [[package]] 2914 + name = "windows_i686_gnu" 2135 2915 version = "0.52.6" 2136 2916 source = "registry+https://github.com/rust-lang/crates.io-index" 2137 2917 checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" ··· 2144 2924 2145 2925 [[package]] 2146 2926 name = "windows_i686_msvc" 2927 + version = "0.48.5" 2928 + source = "registry+https://github.com/rust-lang/crates.io-index" 2929 + checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2930 + 2931 + [[package]] 2932 + name = "windows_i686_msvc" 2147 2933 version = "0.52.6" 2148 2934 source = "registry+https://github.com/rust-lang/crates.io-index" 2149 2935 checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2936 + 2937 + [[package]] 2938 + name = "windows_x86_64_gnu" 2939 + version = "0.48.5" 2940 + source = "registry+https://github.com/rust-lang/crates.io-index" 2941 + checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2150 2942 2151 2943 [[package]] 2152 2944 name = "windows_x86_64_gnu" ··· 2156 2948 2157 2949 [[package]] 2158 2950 name = "windows_x86_64_gnullvm" 2951 + version = "0.48.5" 2952 + source = "registry+https://github.com/rust-lang/crates.io-index" 2953 + checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2954 + 2955 + [[package]] 2956 + name = "windows_x86_64_gnullvm" 2159 2957 version = "0.52.6" 2160 2958 source = "registry+https://github.com/rust-lang/crates.io-index" 2161 2959 checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2162 2960 2163 2961 [[package]] 2164 2962 name = "windows_x86_64_msvc" 2963 + version = "0.48.5" 2964 + source = "registry+https://github.com/rust-lang/crates.io-index" 2965 + checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2966 + 2967 + [[package]] 2968 + name = "windows_x86_64_msvc" 2165 2969 version = "0.52.6" 2166 2970 source = "registry+https://github.com/rust-lang/crates.io-index" 2167 2971 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" ··· 2176 2980 ] 2177 2981 2178 2982 [[package]] 2983 + name = "winreg" 2984 + version = "0.50.0" 2985 + source = "registry+https://github.com/rust-lang/crates.io-index" 2986 + checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 2987 + dependencies = [ 2988 + "cfg-if", 2989 + "windows-sys 0.48.0", 2990 + ] 2991 + 2992 + [[package]] 2993 + name = "write16" 2994 + version = "1.0.0" 2995 + source = "registry+https://github.com/rust-lang/crates.io-index" 2996 + checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 2997 + 2998 + [[package]] 2999 + name = "writeable" 3000 + version = "0.5.5" 3001 + source = "registry+https://github.com/rust-lang/crates.io-index" 3002 + checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 3003 + 3004 + [[package]] 2179 3005 name = "yansi" 2180 3006 version = "1.0.1" 2181 3007 source = "registry+https://github.com/rust-lang/crates.io-index" 2182 3008 checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" 2183 3009 2184 3010 [[package]] 3011 + name = "yoke" 3012 + version = "0.7.5" 3013 + source = "registry+https://github.com/rust-lang/crates.io-index" 3014 + checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 3015 + dependencies = [ 3016 + "serde", 3017 + "stable_deref_trait", 3018 + "yoke-derive", 3019 + "zerofrom", 3020 + ] 3021 + 3022 + [[package]] 3023 + name = "yoke-derive" 3024 + version = "0.7.5" 3025 + source = "registry+https://github.com/rust-lang/crates.io-index" 3026 + checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 3027 + dependencies = [ 3028 + "proc-macro2", 3029 + "quote", 3030 + "syn", 3031 + "synstructure", 3032 + ] 3033 + 3034 + [[package]] 2185 3035 name = "zerocopy" 2186 3036 version = "0.7.35" 2187 3037 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2201 3051 "quote", 2202 3052 "syn", 2203 3053 ] 3054 + 3055 + [[package]] 3056 + name = "zerofrom" 3057 + version = "0.1.5" 3058 + source = "registry+https://github.com/rust-lang/crates.io-index" 3059 + checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" 3060 + dependencies = [ 3061 + "zerofrom-derive", 3062 + ] 3063 + 3064 + [[package]] 3065 + name = "zerofrom-derive" 3066 + version = "0.1.5" 3067 + source = "registry+https://github.com/rust-lang/crates.io-index" 3068 + checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" 3069 + dependencies = [ 3070 + "proc-macro2", 3071 + "quote", 3072 + "syn", 3073 + "synstructure", 3074 + ] 3075 + 3076 + [[package]] 3077 + name = "zeroize" 3078 + version = "1.8.1" 3079 + source = "registry+https://github.com/rust-lang/crates.io-index" 3080 + checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 3081 + 3082 + [[package]] 3083 + name = "zerovec" 3084 + version = "0.10.4" 3085 + source = "registry+https://github.com/rust-lang/crates.io-index" 3086 + checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 3087 + dependencies = [ 3088 + "yoke", 3089 + "zerofrom", 3090 + "zerovec-derive", 3091 + ] 3092 + 3093 + [[package]] 3094 + name = "zerovec-derive" 3095 + version = "0.10.3" 3096 + source = "registry+https://github.com/rust-lang/crates.io-index" 3097 + checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 3098 + dependencies = [ 3099 + "proc-macro2", 3100 + "quote", 3101 + "syn", 3102 + ]
+1
Cargo.toml
··· 3 3 4 4 members = [ 5 5 "consumer", 6 + "did-resolver", 6 7 "parakeet", 7 8 "parakeet-db", 8 9 "parakeet-lexgen"
+1
consumer/Cargo.toml
··· 6 6 [dependencies] 7 7 chrono = { version = "0.4.39", features = ["serde"] } 8 8 ciborium = "0.2.2" 9 + did-resolver = { path = "../did-resolver" } 9 10 diesel = { version = "2.2.6", features = ["chrono", "serde_json"] } 10 11 diesel-async = { version = "0.5.2", features = ["deadpool", "postgres"] } 11 12 eyre = "0.6.12"
+1
consumer/src/config.rs
··· 15 15 pub struct Config { 16 16 pub relay_source: String, 17 17 pub database_url: String, 18 + pub plc_directory: Option<String>, 18 19 }
+32 -9
consumer/src/indexer/mod.rs
··· 1 1 use crate::firehose::{AtpAccountEvent, AtpCommitEvent, AtpIdentityEvent, CommitOp, FirehoseEvent}; 2 2 use crate::indexer::types::{CollectionType, RecordTypes}; 3 + use did_resolver::Resolver; 3 4 use diesel_async::pooled_connection::deadpool::Pool; 4 5 use diesel_async::{AsyncConnection, AsyncPgConnection}; 5 6 use futures::StreamExt; 6 7 use ipld_core::cid::Cid; 7 8 use parakeet_db::types::{ActorStatus, ActorSyncState}; 8 9 use std::collections::HashMap; 10 + use std::sync::Arc; 9 11 use tokio::sync::mpsc::Receiver; 10 12 use tracing::{instrument, Instrument}; 11 13 ··· 16 18 pub async fn relay_indexer( 17 19 pool: Pool<AsyncPgConnection>, 18 20 mut rx: Receiver<FirehoseEvent>, 21 + resolver: Arc<Resolver>, 19 22 ) -> eyre::Result<()> { 20 23 let mut conn = pool.get().await?; 21 24 22 25 while let Some(event) = rx.recv().await { 23 26 let res = match event { 24 - FirehoseEvent::Identity(identity) => index_identity(&mut conn, identity).await, 27 + FirehoseEvent::Identity(identity) => { 28 + index_identity(&mut conn, &resolver, identity).await 29 + } 25 30 FirehoseEvent::Account(account) => index_account(&mut conn, account).await, 26 31 FirehoseEvent::Commit(commit) => { 27 32 let span = tracing::info_span!( ··· 50 55 #[instrument(skip_all, fields(seq = identity.seq, repo=identity.did))] 51 56 async fn index_identity( 52 57 conn: &mut AsyncPgConnection, 58 + resolver: &Resolver, 53 59 identity: AtpIdentityEvent, 54 60 ) -> eyre::Result<()> { 55 - db::upsert_actor( 56 - conn, 57 - &identity.did, 58 - Some(identity.handle), 59 - None, 60 - identity.time, 61 - ) 62 - .await?; 61 + let Some(did_doc) = resolver.resolve_did(&identity.did).await? else { 62 + eyre::bail!("missing did doc"); 63 + }; 64 + 65 + let Some(handle) = did_doc 66 + .also_known_as 67 + .and_then(|aka| aka.first().cloned()) 68 + .and_then(|handle| handle.strip_prefix("at://").map(String::from)) 69 + else { 70 + eyre::bail!("DID doc contained no handle"); 71 + }; 72 + 73 + // in theory, we can use com.atproto.identity.resolveHandle against a PDS, but that seems 74 + // like a way to end up with really sus handles. 75 + let Some(handle_did) = resolver.resolve_handle(&handle).await? else { 76 + eyre::bail!("Failed to resolve did for handle {handle}"); 77 + }; 78 + 79 + let new_handle = if handle_did != identity.did { 80 + None 81 + } else { 82 + Some(identity.handle) 83 + }; 84 + 85 + db::upsert_actor(conn, &identity.did, new_handle, None, identity.time).await?; 63 86 64 87 Ok(()) 65 88 }
+10 -3
consumer/src/main.rs
··· 1 - use diesel_async::AsyncPgConnection; 2 - use diesel_async::pooled_connection::AsyncDieselConnectionManager; 1 + use std::sync::Arc; 3 2 use diesel_async::pooled_connection::deadpool::Pool; 3 + use diesel_async::pooled_connection::AsyncDieselConnectionManager; 4 + use diesel_async::AsyncPgConnection; 4 5 use tokio::sync::mpsc::Sender; 6 + use did_resolver::{Resolver, ResolverOpts}; 5 7 6 8 mod config; 7 9 mod firehose; ··· 17 19 let db_mgr = AsyncDieselConnectionManager::<AsyncPgConnection>::new(&conf.database_url); 18 20 let pool = Pool::builder(db_mgr).build()?; 19 21 22 + let resolver = Arc::new(Resolver::new(ResolverOpts { 23 + plc_directory: conf.plc_directory, 24 + ..Default::default() 25 + })?); 26 + 20 27 let (tx, rx) = tokio::sync::mpsc::channel::<firehose::FirehoseEvent>(64); 21 28 22 29 let relay_firehose = firehose::FirehoseConsumer::new_relay(&conf.relay_source, None).await?; 23 30 24 31 let firehose_handle = tokio::spawn(relay_consumer(relay_firehose, tx)); 25 - let indexer_handle = tokio::spawn(indexer::relay_indexer(pool.clone(), rx)); 32 + let indexer_handle = tokio::spawn(indexer::relay_indexer(pool.clone(), rx, resolver.clone())); 26 33 27 34 let (firehose_res, indexer_res) = tokio::try_join!{ 28 35 firehose_handle,
+11
did-resolver/Cargo.toml
··· 1 + [package] 2 + name = "did-resolver" 3 + version = "0.1.0" 4 + edition = "2021" 5 + 6 + [dependencies] 7 + hickory-resolver = "0.24.2" 8 + reqwest = { version = "0.12.12", features = ["json", "native-tls"] } 9 + serde = { version = "1.0.217", features = ["derive"] } 10 + serde_json = "1.0.134" 11 + thiserror = "2.0.11"
+19
did-resolver/src/error.rs
··· 1 + use thiserror::Error; 2 + 3 + #[derive(Debug, Error)] 4 + pub enum Error { 5 + #[error("did was not in expected format did:method:identifier")] 6 + BadDidFormat, 7 + #[error("{0}")] 8 + Dns(#[from] hickory_resolver::error::ResolveError), 9 + #[error("{0}")] 10 + Http(#[from] reqwest::Error), 11 + #[error("the did endpoint returned a server error")] 12 + ServerError, 13 + #[error("document request timed out")] 14 + Timeout, 15 + #[error("too many redirects")] 16 + TooManyRedirects, 17 + #[error("did method was not plc or web: {0}")] 18 + UnsupportedDidMethod(String), 19 + }
+160
did-resolver/src/lib.rs
··· 1 + use error::Error; 2 + use hickory_resolver::proto::serialize::binary::BinEncodable; 3 + use hickory_resolver::TokioAsyncResolver; 4 + use reqwest::{Client, StatusCode}; 5 + 6 + pub mod error; 7 + pub mod types; 8 + 9 + const DEFAULT_DUR: std::time::Duration = std::time::Duration::from_secs(3); 10 + const DEFAULT_PLC: &str = "https://plc.directory"; 11 + 12 + #[derive(Default)] 13 + pub struct ResolverOpts { 14 + pub plc_directory: Option<String>, 15 + pub timeout: Option<std::time::Duration>, 16 + } 17 + 18 + pub struct Resolver { 19 + client: Client, 20 + plc: String, 21 + dns: TokioAsyncResolver, 22 + } 23 + 24 + impl Resolver { 25 + pub fn new(opts: ResolverOpts) -> Result<Self, Error> { 26 + let dns = hickory_resolver::AsyncResolver::tokio_from_system_conf()?; 27 + 28 + Ok(Resolver { 29 + client: Client::builder() 30 + .timeout(opts.timeout.unwrap_or(DEFAULT_DUR)) 31 + .build()?, 32 + plc: opts.plc_directory.unwrap_or(DEFAULT_PLC.to_string()), 33 + dns, 34 + }) 35 + } 36 + 37 + pub async fn resolve_did(&self, did: &str) -> Result<Option<types::DidDocument>, Error> { 38 + let did_parts = did.splitn(3, ':').collect::<Vec<&str>>(); 39 + 40 + if did_parts.len() != 3 { 41 + return Err(Error::BadDidFormat); 42 + } 43 + 44 + if did_parts[0] != "did" { 45 + return Err(Error::BadDidFormat); 46 + } 47 + 48 + match did_parts[1] { 49 + "plc" => self.resolve_did_plc(did).await, 50 + "web" => self.resolve_did_web(did_parts[2]).await, 51 + method => Err(Error::UnsupportedDidMethod(method.to_string())), 52 + } 53 + } 54 + 55 + async fn resolve_did_plc(&self, did: &str) -> Result<Option<types::DidDocument>, Error> { 56 + let res = self 57 + .client 58 + .get(format!("{}/{did}", self.plc)) 59 + .send() 60 + .await?; 61 + 62 + let status = res.status(); 63 + 64 + if status.is_server_error() { 65 + return Err(Error::ServerError); 66 + } 67 + 68 + if status == StatusCode::NOT_FOUND || status == StatusCode::GONE { 69 + return Ok(None); 70 + } 71 + 72 + let did_doc = res.json().await?; 73 + Ok(Some(did_doc)) 74 + } 75 + 76 + async fn resolve_did_web(&self, id: &str) -> Result<Option<types::DidDocument>, Error> { 77 + let res = match self 78 + .client 79 + .get(format!("{id}/.well-known/did.json")) 80 + .send() 81 + .await 82 + { 83 + Ok(res) => res, 84 + Err(err) => { 85 + if err.is_timeout() { 86 + return Err(Error::Timeout); 87 + } else if err.is_redirect() { 88 + return Err(Error::TooManyRedirects); 89 + } 90 + return Err(Error::Http(err)); 91 + } 92 + }; 93 + 94 + let status = res.status(); 95 + 96 + if status.is_server_error() { 97 + return Err(Error::ServerError); 98 + } 99 + 100 + if status == StatusCode::NOT_FOUND { 101 + return Ok(None); 102 + } 103 + 104 + let did_doc = res.json().await?; 105 + Ok(Some(did_doc)) 106 + } 107 + 108 + pub async fn resolve_handle(&self, handle: &str) -> Result<Option<String>, Error> { 109 + // we want one of these to succeed 110 + let http = self.resolve_handle_http(handle).await; 111 + let dns = self.resolve_handle_dns(handle).await; 112 + 113 + match (http, dns) { 114 + (Ok(http), Ok(dns)) => Ok(dns.or(http)), 115 + (http, dns) => http.or(dns), 116 + } 117 + } 118 + 119 + async fn resolve_handle_http(&self, handle: &str) -> Result<Option<String>, Error> { 120 + let res = self 121 + .client 122 + .get(format!("https://{handle}/.well-known/atproto-did")) 123 + .send() 124 + .await? 125 + .error_for_status()?; 126 + 127 + let did = res.text().await?; 128 + 129 + Ok(Some(did)) 130 + } 131 + 132 + async fn resolve_handle_dns(&self, handle: &str) -> Result<Option<String>, Error> { 133 + let res = match self.dns.txt_lookup(format!("_atproto.{handle}")).await { 134 + Ok(txt) => txt, 135 + Err(err) => { 136 + return match err.kind() { 137 + hickory_resolver::error::ResolveErrorKind::NoRecordsFound { .. } => Ok(None), 138 + _ => Err(err.into()), 139 + } 140 + } 141 + }; 142 + 143 + let Some(first) = res.as_lookup().records().first() else { 144 + return Ok(None); 145 + }; 146 + 147 + let Some(Ok(data)) = first.data().and_then(|v| v.as_txt()).map(|v| v.to_bytes()) else { 148 + return Ok(None); 149 + }; 150 + 151 + let Some(string_data) = String::from_utf8_lossy(&data) 152 + .strip_prefix("$did=") 153 + .map(|v| v.to_string()) 154 + else { 155 + return Ok(None); 156 + }; 157 + 158 + Ok(Some(string_data)) 159 + } 160 + }
+32
did-resolver/src/types.rs
··· 1 + use serde::Deserialize; 2 + 3 + #[derive(Debug, Deserialize)] 4 + #[serde(rename_all = "camelCase")] 5 + pub struct DidDocument { 6 + #[serde(rename = "@context")] 7 + pub context: Vec<String>, 8 + pub id: String, 9 + /// Ordered set (no duplicates) of aliases and names for this account, in the form of URIs 10 + pub also_known_as: Option<Vec<String>>, 11 + pub service: Option<Vec<DidService>>, 12 + pub verification_method: Option<Vec<DidVerificationMethod>>, 13 + } 14 + 15 + #[derive(Debug, Deserialize)] 16 + #[serde(rename_all = "camelCase")] 17 + pub struct DidService { 18 + pub id: String, 19 + #[serde(rename = "type")] 20 + pub ty: String, 21 + pub service_endpoint: String, 22 + } 23 + 24 + #[derive(Debug, Deserialize)] 25 + #[serde(rename_all = "camelCase")] 26 + pub struct DidVerificationMethod { 27 + pub id: String, 28 + #[serde(rename = "type")] 29 + pub ty: String, 30 + pub controller: String, 31 + pub public_key_multibase: String, 32 + }