diff options
| -rw-r--r-- | Cargo.lock | 527 | ||||
| -rw-r--r-- | grasp-audit/Cargo.toml | 4 | ||||
| -rw-r--r-- | grasp-audit/src/client.rs | 19 | ||||
| -rw-r--r-- | grasp-audit/src/specs/grasp01/nip11_document.rs | 189 | ||||
| -rw-r--r-- | src/http/mod.rs | 27 | ||||
| -rw-r--r-- | src/http/nip11.rs | 146 | ||||
| -rw-r--r-- | tests/nip11_document.rs | 62 |
7 files changed, 923 insertions, 51 deletions
| @@ -165,6 +165,12 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" | |||
| 165 | 165 | ||
| 166 | [[package]] | 166 | [[package]] |
| 167 | name = "base64" | 167 | name = "base64" |
| 168 | version = "0.21.7" | ||
| 169 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 170 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" | ||
| 171 | |||
| 172 | [[package]] | ||
| 173 | name = "base64" | ||
| 168 | version = "0.22.1" | 174 | version = "0.22.1" |
| 169 | source = "registry+https://github.com/rust-lang/crates.io-index" | 175 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 170 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" | 176 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" |
| @@ -227,6 +233,12 @@ dependencies = [ | |||
| 227 | 233 | ||
| 228 | [[package]] | 234 | [[package]] |
| 229 | name = "bitflags" | 235 | name = "bitflags" |
| 236 | version = "1.3.2" | ||
| 237 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 238 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" | ||
| 239 | |||
| 240 | [[package]] | ||
| 241 | name = "bitflags" | ||
| 230 | version = "2.10.0" | 242 | version = "2.10.0" |
| 231 | source = "registry+https://github.com/rust-lang/crates.io-index" | 243 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 232 | checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" | 244 | checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" |
| @@ -381,6 +393,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 381 | checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" | 393 | checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" |
| 382 | 394 | ||
| 383 | [[package]] | 395 | [[package]] |
| 396 | name = "core-foundation" | ||
| 397 | version = "0.9.4" | ||
| 398 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 399 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" | ||
| 400 | dependencies = [ | ||
| 401 | "core-foundation-sys", | ||
| 402 | "libc", | ||
| 403 | ] | ||
| 404 | |||
| 405 | [[package]] | ||
| 384 | name = "core-foundation-sys" | 406 | name = "core-foundation-sys" |
| 385 | version = "0.8.7" | 407 | version = "0.8.7" |
| 386 | source = "registry+https://github.com/rust-lang/crates.io-index" | 408 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -447,12 +469,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 447 | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" | 469 | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" |
| 448 | 470 | ||
| 449 | [[package]] | 471 | [[package]] |
| 472 | name = "encoding_rs" | ||
| 473 | version = "0.8.35" | ||
| 474 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 475 | checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" | ||
| 476 | dependencies = [ | ||
| 477 | "cfg-if", | ||
| 478 | ] | ||
| 479 | |||
| 480 | [[package]] | ||
| 450 | name = "equivalent" | 481 | name = "equivalent" |
| 451 | version = "1.0.2" | 482 | version = "1.0.2" |
| 452 | source = "registry+https://github.com/rust-lang/crates.io-index" | 483 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 453 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" | 484 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" |
| 454 | 485 | ||
| 455 | [[package]] | 486 | [[package]] |
| 487 | name = "errno" | ||
| 488 | version = "0.3.14" | ||
| 489 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 490 | checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" | ||
| 491 | dependencies = [ | ||
| 492 | "libc", | ||
| 493 | "windows-sys 0.61.2", | ||
| 494 | ] | ||
| 495 | |||
| 496 | [[package]] | ||
| 497 | name = "fastrand" | ||
| 498 | version = "2.3.0" | ||
| 499 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 500 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" | ||
| 501 | |||
| 502 | [[package]] | ||
| 456 | name = "find-msvc-tools" | 503 | name = "find-msvc-tools" |
| 457 | version = "0.1.4" | 504 | version = "0.1.4" |
| 458 | source = "registry+https://github.com/rust-lang/crates.io-index" | 505 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -465,6 +512,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 465 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" | 512 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" |
| 466 | 513 | ||
| 467 | [[package]] | 514 | [[package]] |
| 515 | name = "foreign-types" | ||
| 516 | version = "0.3.2" | ||
| 517 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 518 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" | ||
| 519 | dependencies = [ | ||
| 520 | "foreign-types-shared", | ||
| 521 | ] | ||
| 522 | |||
| 523 | [[package]] | ||
| 524 | name = "foreign-types-shared" | ||
| 525 | version = "0.1.1" | ||
| 526 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 527 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" | ||
| 528 | |||
| 529 | [[package]] | ||
| 468 | name = "form_urlencoded" | 530 | name = "form_urlencoded" |
| 469 | version = "1.2.2" | 531 | version = "1.2.2" |
| 470 | source = "registry+https://github.com/rust-lang/crates.io-index" | 532 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -618,6 +680,8 @@ dependencies = [ | |||
| 618 | "clap", | 680 | "clap", |
| 619 | "futures", | 681 | "futures", |
| 620 | "nostr-sdk 0.43.0", | 682 | "nostr-sdk 0.43.0", |
| 683 | "regex", | ||
| 684 | "reqwest", | ||
| 621 | "serde", | 685 | "serde", |
| 622 | "serde_json", | 686 | "serde_json", |
| 623 | "thiserror 1.0.69", | 687 | "thiserror 1.0.69", |
| @@ -630,6 +694,25 @@ dependencies = [ | |||
| 630 | 694 | ||
| 631 | [[package]] | 695 | [[package]] |
| 632 | name = "h2" | 696 | name = "h2" |
| 697 | version = "0.3.27" | ||
| 698 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 699 | checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" | ||
| 700 | dependencies = [ | ||
| 701 | "bytes", | ||
| 702 | "fnv", | ||
| 703 | "futures-core", | ||
| 704 | "futures-sink", | ||
| 705 | "futures-util", | ||
| 706 | "http 0.2.12", | ||
| 707 | "indexmap", | ||
| 708 | "slab", | ||
| 709 | "tokio", | ||
| 710 | "tokio-util", | ||
| 711 | "tracing", | ||
| 712 | ] | ||
| 713 | |||
| 714 | [[package]] | ||
| 715 | name = "h2" | ||
| 633 | version = "0.4.12" | 716 | version = "0.4.12" |
| 634 | source = "registry+https://github.com/rust-lang/crates.io-index" | 717 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 635 | checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" | 718 | checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" |
| @@ -639,7 +722,7 @@ dependencies = [ | |||
| 639 | "fnv", | 722 | "fnv", |
| 640 | "futures-core", | 723 | "futures-core", |
| 641 | "futures-sink", | 724 | "futures-sink", |
| 642 | "http", | 725 | "http 1.3.1", |
| 643 | "indexmap", | 726 | "indexmap", |
| 644 | "slab", | 727 | "slab", |
| 645 | "tokio", | 728 | "tokio", |
| @@ -691,6 +774,17 @@ dependencies = [ | |||
| 691 | 774 | ||
| 692 | [[package]] | 775 | [[package]] |
| 693 | name = "http" | 776 | name = "http" |
| 777 | version = "0.2.12" | ||
| 778 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 779 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" | ||
| 780 | dependencies = [ | ||
| 781 | "bytes", | ||
| 782 | "fnv", | ||
| 783 | "itoa", | ||
| 784 | ] | ||
| 785 | |||
| 786 | [[package]] | ||
| 787 | name = "http" | ||
| 694 | version = "1.3.1" | 788 | version = "1.3.1" |
| 695 | source = "registry+https://github.com/rust-lang/crates.io-index" | 789 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 696 | checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" | 790 | checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" |
| @@ -702,12 +796,23 @@ dependencies = [ | |||
| 702 | 796 | ||
| 703 | [[package]] | 797 | [[package]] |
| 704 | name = "http-body" | 798 | name = "http-body" |
| 799 | version = "0.4.6" | ||
| 800 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 801 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" | ||
| 802 | dependencies = [ | ||
| 803 | "bytes", | ||
| 804 | "http 0.2.12", | ||
| 805 | "pin-project-lite", | ||
| 806 | ] | ||
| 807 | |||
| 808 | [[package]] | ||
| 809 | name = "http-body" | ||
| 705 | version = "1.0.1" | 810 | version = "1.0.1" |
| 706 | source = "registry+https://github.com/rust-lang/crates.io-index" | 811 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 707 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" | 812 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" |
| 708 | dependencies = [ | 813 | dependencies = [ |
| 709 | "bytes", | 814 | "bytes", |
| 710 | "http", | 815 | "http 1.3.1", |
| 711 | ] | 816 | ] |
| 712 | 817 | ||
| 713 | [[package]] | 818 | [[package]] |
| @@ -718,8 +823,8 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" | |||
| 718 | dependencies = [ | 823 | dependencies = [ |
| 719 | "bytes", | 824 | "bytes", |
| 720 | "futures-core", | 825 | "futures-core", |
| 721 | "http", | 826 | "http 1.3.1", |
| 722 | "http-body", | 827 | "http-body 1.0.1", |
| 723 | "pin-project-lite", | 828 | "pin-project-lite", |
| 724 | ] | 829 | ] |
| 725 | 830 | ||
| @@ -737,6 +842,30 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" | |||
| 737 | 842 | ||
| 738 | [[package]] | 843 | [[package]] |
| 739 | name = "hyper" | 844 | name = "hyper" |
| 845 | version = "0.14.32" | ||
| 846 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 847 | checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" | ||
| 848 | dependencies = [ | ||
| 849 | "bytes", | ||
| 850 | "futures-channel", | ||
| 851 | "futures-core", | ||
| 852 | "futures-util", | ||
| 853 | "h2 0.3.27", | ||
| 854 | "http 0.2.12", | ||
| 855 | "http-body 0.4.6", | ||
| 856 | "httparse", | ||
| 857 | "httpdate", | ||
| 858 | "itoa", | ||
| 859 | "pin-project-lite", | ||
| 860 | "socket2 0.5.10", | ||
| 861 | "tokio", | ||
| 862 | "tower-service", | ||
| 863 | "tracing", | ||
| 864 | "want", | ||
| 865 | ] | ||
| 866 | |||
| 867 | [[package]] | ||
| 868 | name = "hyper" | ||
| 740 | version = "1.8.1" | 869 | version = "1.8.1" |
| 741 | source = "registry+https://github.com/rust-lang/crates.io-index" | 870 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 742 | checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" | 871 | checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" |
| @@ -745,9 +874,9 @@ dependencies = [ | |||
| 745 | "bytes", | 874 | "bytes", |
| 746 | "futures-channel", | 875 | "futures-channel", |
| 747 | "futures-core", | 876 | "futures-core", |
| 748 | "h2", | 877 | "h2 0.4.12", |
| 749 | "http", | 878 | "http 1.3.1", |
| 750 | "http-body", | 879 | "http-body 1.0.1", |
| 751 | "httparse", | 880 | "httparse", |
| 752 | "httpdate", | 881 | "httpdate", |
| 753 | "itoa", | 882 | "itoa", |
| @@ -759,6 +888,19 @@ dependencies = [ | |||
| 759 | ] | 888 | ] |
| 760 | 889 | ||
| 761 | [[package]] | 890 | [[package]] |
| 891 | name = "hyper-tls" | ||
| 892 | version = "0.5.0" | ||
| 893 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 894 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" | ||
| 895 | dependencies = [ | ||
| 896 | "bytes", | ||
| 897 | "hyper 0.14.32", | ||
| 898 | "native-tls", | ||
| 899 | "tokio", | ||
| 900 | "tokio-native-tls", | ||
| 901 | ] | ||
| 902 | |||
| 903 | [[package]] | ||
| 762 | name = "hyper-util" | 904 | name = "hyper-util" |
| 763 | version = "0.1.18" | 905 | version = "0.1.18" |
| 764 | source = "registry+https://github.com/rust-lang/crates.io-index" | 906 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -766,9 +908,9 @@ checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" | |||
| 766 | dependencies = [ | 908 | dependencies = [ |
| 767 | "bytes", | 909 | "bytes", |
| 768 | "futures-core", | 910 | "futures-core", |
| 769 | "http", | 911 | "http 1.3.1", |
| 770 | "http-body", | 912 | "http-body 1.0.1", |
| 771 | "hyper", | 913 | "hyper 1.8.1", |
| 772 | "pin-project-lite", | 914 | "pin-project-lite", |
| 773 | "tokio", | 915 | "tokio", |
| 774 | ] | 916 | ] |
| @@ -932,6 +1074,12 @@ dependencies = [ | |||
| 932 | ] | 1074 | ] |
| 933 | 1075 | ||
| 934 | [[package]] | 1076 | [[package]] |
| 1077 | name = "ipnet" | ||
| 1078 | version = "2.11.0" | ||
| 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1080 | checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" | ||
| 1081 | |||
| 1082 | [[package]] | ||
| 935 | name = "is_terminal_polyfill" | 1083 | name = "is_terminal_polyfill" |
| 936 | version = "1.70.2" | 1084 | version = "1.70.2" |
| 937 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1085 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -966,6 +1114,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 966 | checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" | 1114 | checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" |
| 967 | 1115 | ||
| 968 | [[package]] | 1116 | [[package]] |
| 1117 | name = "linux-raw-sys" | ||
| 1118 | version = "0.11.0" | ||
| 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1120 | checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" | ||
| 1121 | |||
| 1122 | [[package]] | ||
| 969 | name = "litemap" | 1123 | name = "litemap" |
| 970 | version = "0.8.1" | 1124 | version = "0.8.1" |
| 971 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1008,6 +1162,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 1008 | checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" | 1162 | checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" |
| 1009 | 1163 | ||
| 1010 | [[package]] | 1164 | [[package]] |
| 1165 | name = "mime" | ||
| 1166 | version = "0.3.17" | ||
| 1167 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1168 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" | ||
| 1169 | |||
| 1170 | [[package]] | ||
| 1011 | name = "mio" | 1171 | name = "mio" |
| 1012 | version = "1.1.0" | 1172 | version = "1.1.0" |
| 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1173 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1019,6 +1179,23 @@ dependencies = [ | |||
| 1019 | ] | 1179 | ] |
| 1020 | 1180 | ||
| 1021 | [[package]] | 1181 | [[package]] |
| 1182 | name = "native-tls" | ||
| 1183 | version = "0.2.14" | ||
| 1184 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1185 | checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" | ||
| 1186 | dependencies = [ | ||
| 1187 | "libc", | ||
| 1188 | "log", | ||
| 1189 | "openssl", | ||
| 1190 | "openssl-probe", | ||
| 1191 | "openssl-sys", | ||
| 1192 | "schannel", | ||
| 1193 | "security-framework", | ||
| 1194 | "security-framework-sys", | ||
| 1195 | "tempfile", | ||
| 1196 | ] | ||
| 1197 | |||
| 1198 | [[package]] | ||
| 1022 | name = "negentropy" | 1199 | name = "negentropy" |
| 1023 | version = "0.5.0" | 1200 | version = "0.5.0" |
| 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1201 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1029,12 +1206,12 @@ name = "ngit-grasp" | |||
| 1029 | version = "0.1.0" | 1206 | version = "0.1.0" |
| 1030 | dependencies = [ | 1207 | dependencies = [ |
| 1031 | "anyhow", | 1208 | "anyhow", |
| 1032 | "base64", | 1209 | "base64 0.22.1", |
| 1033 | "dotenvy", | 1210 | "dotenvy", |
| 1034 | "futures-util", | 1211 | "futures-util", |
| 1035 | "grasp-audit", | 1212 | "grasp-audit", |
| 1036 | "http-body-util", | 1213 | "http-body-util", |
| 1037 | "hyper", | 1214 | "hyper 1.8.1", |
| 1038 | "hyper-util", | 1215 | "hyper-util", |
| 1039 | "nostr-relay-builder", | 1216 | "nostr-relay-builder", |
| 1040 | "nostr-sdk 0.44.1", | 1217 | "nostr-sdk 0.44.1", |
| @@ -1054,7 +1231,7 @@ version = "0.43.1" | |||
| 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1231 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1055 | checksum = "62a97d745f1bd8d5e05a978632bbb87b0614567d5142906fe7c86fb2440faac6" | 1232 | checksum = "62a97d745f1bd8d5e05a978632bbb87b0614567d5142906fe7c86fb2440faac6" |
| 1056 | dependencies = [ | 1233 | dependencies = [ |
| 1057 | "base64", | 1234 | "base64 0.22.1", |
| 1058 | "bech32", | 1235 | "bech32", |
| 1059 | "bip39", | 1236 | "bip39", |
| 1060 | "bitcoin_hashes 0.14.0", | 1237 | "bitcoin_hashes 0.14.0", |
| @@ -1077,7 +1254,7 @@ version = "0.44.1" | |||
| 1077 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1254 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1078 | checksum = "d3595fecf0e0aaacb69a0dc0101a4453f3c76eda333d6bbc49f68f64390b3d85" | 1255 | checksum = "d3595fecf0e0aaacb69a0dc0101a4453f3c76eda333d6bbc49f68f64390b3d85" |
| 1079 | dependencies = [ | 1256 | dependencies = [ |
| 1080 | "base64", | 1257 | "base64 0.22.1", |
| 1081 | "bech32", | 1258 | "bech32", |
| 1082 | "bip39", | 1259 | "bip39", |
| 1083 | "bitcoin_hashes 0.14.0", | 1260 | "bitcoin_hashes 0.14.0", |
| @@ -1243,6 +1420,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 1243 | checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" | 1420 | checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" |
| 1244 | 1421 | ||
| 1245 | [[package]] | 1422 | [[package]] |
| 1423 | name = "openssl" | ||
| 1424 | version = "0.10.75" | ||
| 1425 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1426 | checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" | ||
| 1427 | dependencies = [ | ||
| 1428 | "bitflags 2.10.0", | ||
| 1429 | "cfg-if", | ||
| 1430 | "foreign-types", | ||
| 1431 | "libc", | ||
| 1432 | "once_cell", | ||
| 1433 | "openssl-macros", | ||
| 1434 | "openssl-sys", | ||
| 1435 | ] | ||
| 1436 | |||
| 1437 | [[package]] | ||
| 1438 | name = "openssl-macros" | ||
| 1439 | version = "0.1.1" | ||
| 1440 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1441 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" | ||
| 1442 | dependencies = [ | ||
| 1443 | "proc-macro2", | ||
| 1444 | "quote", | ||
| 1445 | "syn", | ||
| 1446 | ] | ||
| 1447 | |||
| 1448 | [[package]] | ||
| 1449 | name = "openssl-probe" | ||
| 1450 | version = "0.1.6" | ||
| 1451 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1452 | checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" | ||
| 1453 | |||
| 1454 | [[package]] | ||
| 1455 | name = "openssl-sys" | ||
| 1456 | version = "0.9.111" | ||
| 1457 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1458 | checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" | ||
| 1459 | dependencies = [ | ||
| 1460 | "cc", | ||
| 1461 | "libc", | ||
| 1462 | "pkg-config", | ||
| 1463 | "vcpkg", | ||
| 1464 | ] | ||
| 1465 | |||
| 1466 | [[package]] | ||
| 1246 | name = "parking_lot" | 1467 | name = "parking_lot" |
| 1247 | version = "0.12.5" | 1468 | version = "0.12.5" |
| 1248 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1469 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1305,6 +1526,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 1305 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" | 1526 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" |
| 1306 | 1527 | ||
| 1307 | [[package]] | 1528 | [[package]] |
| 1529 | name = "pkg-config" | ||
| 1530 | version = "0.3.32" | ||
| 1531 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1532 | checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" | ||
| 1533 | |||
| 1534 | [[package]] | ||
| 1308 | name = "poly1305" | 1535 | name = "poly1305" |
| 1309 | version = "0.8.0" | 1536 | version = "0.8.0" |
| 1310 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1537 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1422,7 +1649,19 @@ version = "0.5.18" | |||
| 1422 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1649 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1423 | checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" | 1650 | checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" |
| 1424 | dependencies = [ | 1651 | dependencies = [ |
| 1425 | "bitflags", | 1652 | "bitflags 2.10.0", |
| 1653 | ] | ||
| 1654 | |||
| 1655 | [[package]] | ||
| 1656 | name = "regex" | ||
| 1657 | version = "1.12.2" | ||
| 1658 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1659 | checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" | ||
| 1660 | dependencies = [ | ||
| 1661 | "aho-corasick", | ||
| 1662 | "memchr", | ||
| 1663 | "regex-automata", | ||
| 1664 | "regex-syntax", | ||
| 1426 | ] | 1665 | ] |
| 1427 | 1666 | ||
| 1428 | [[package]] | 1667 | [[package]] |
| @@ -1443,6 +1682,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 1443 | checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" | 1682 | checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" |
| 1444 | 1683 | ||
| 1445 | [[package]] | 1684 | [[package]] |
| 1685 | name = "reqwest" | ||
| 1686 | version = "0.11.27" | ||
| 1687 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1688 | checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" | ||
| 1689 | dependencies = [ | ||
| 1690 | "base64 0.21.7", | ||
| 1691 | "bytes", | ||
| 1692 | "encoding_rs", | ||
| 1693 | "futures-core", | ||
| 1694 | "futures-util", | ||
| 1695 | "h2 0.3.27", | ||
| 1696 | "http 0.2.12", | ||
| 1697 | "http-body 0.4.6", | ||
| 1698 | "hyper 0.14.32", | ||
| 1699 | "hyper-tls", | ||
| 1700 | "ipnet", | ||
| 1701 | "js-sys", | ||
| 1702 | "log", | ||
| 1703 | "mime", | ||
| 1704 | "native-tls", | ||
| 1705 | "once_cell", | ||
| 1706 | "percent-encoding", | ||
| 1707 | "pin-project-lite", | ||
| 1708 | "rustls-pemfile", | ||
| 1709 | "serde", | ||
| 1710 | "serde_json", | ||
| 1711 | "serde_urlencoded", | ||
| 1712 | "sync_wrapper", | ||
| 1713 | "system-configuration", | ||
| 1714 | "tokio", | ||
| 1715 | "tokio-native-tls", | ||
| 1716 | "tower-service", | ||
| 1717 | "url", | ||
| 1718 | "wasm-bindgen", | ||
| 1719 | "wasm-bindgen-futures", | ||
| 1720 | "web-sys", | ||
| 1721 | "winreg", | ||
| 1722 | ] | ||
| 1723 | |||
| 1724 | [[package]] | ||
| 1446 | name = "ring" | 1725 | name = "ring" |
| 1447 | version = "0.17.14" | 1726 | version = "0.17.14" |
| 1448 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1727 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1457,6 +1736,19 @@ dependencies = [ | |||
| 1457 | ] | 1736 | ] |
| 1458 | 1737 | ||
| 1459 | [[package]] | 1738 | [[package]] |
| 1739 | name = "rustix" | ||
| 1740 | version = "1.1.2" | ||
| 1741 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1742 | checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" | ||
| 1743 | dependencies = [ | ||
| 1744 | "bitflags 2.10.0", | ||
| 1745 | "errno", | ||
| 1746 | "libc", | ||
| 1747 | "linux-raw-sys", | ||
| 1748 | "windows-sys 0.61.2", | ||
| 1749 | ] | ||
| 1750 | |||
| 1751 | [[package]] | ||
| 1460 | name = "rustls" | 1752 | name = "rustls" |
| 1461 | version = "0.23.34" | 1753 | version = "0.23.34" |
| 1462 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1754 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1471,6 +1763,15 @@ dependencies = [ | |||
| 1471 | ] | 1763 | ] |
| 1472 | 1764 | ||
| 1473 | [[package]] | 1765 | [[package]] |
| 1766 | name = "rustls-pemfile" | ||
| 1767 | version = "1.0.4" | ||
| 1768 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1769 | checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" | ||
| 1770 | dependencies = [ | ||
| 1771 | "base64 0.21.7", | ||
| 1772 | ] | ||
| 1773 | |||
| 1774 | [[package]] | ||
| 1474 | name = "rustls-pki-types" | 1775 | name = "rustls-pki-types" |
| 1475 | version = "1.13.0" | 1776 | version = "1.13.0" |
| 1476 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1777 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1512,6 +1813,15 @@ dependencies = [ | |||
| 1512 | ] | 1813 | ] |
| 1513 | 1814 | ||
| 1514 | [[package]] | 1815 | [[package]] |
| 1816 | name = "schannel" | ||
| 1817 | version = "0.1.28" | ||
| 1818 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1819 | checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" | ||
| 1820 | dependencies = [ | ||
| 1821 | "windows-sys 0.61.2", | ||
| 1822 | ] | ||
| 1823 | |||
| 1824 | [[package]] | ||
| 1515 | name = "scopeguard" | 1825 | name = "scopeguard" |
| 1516 | version = "1.2.0" | 1826 | version = "1.2.0" |
| 1517 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1827 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1550,6 +1860,29 @@ dependencies = [ | |||
| 1550 | ] | 1860 | ] |
| 1551 | 1861 | ||
| 1552 | [[package]] | 1862 | [[package]] |
| 1863 | name = "security-framework" | ||
| 1864 | version = "2.11.1" | ||
| 1865 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1866 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" | ||
| 1867 | dependencies = [ | ||
| 1868 | "bitflags 2.10.0", | ||
| 1869 | "core-foundation", | ||
| 1870 | "core-foundation-sys", | ||
| 1871 | "libc", | ||
| 1872 | "security-framework-sys", | ||
| 1873 | ] | ||
| 1874 | |||
| 1875 | [[package]] | ||
| 1876 | name = "security-framework-sys" | ||
| 1877 | version = "2.15.0" | ||
| 1878 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1879 | checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" | ||
| 1880 | dependencies = [ | ||
| 1881 | "core-foundation-sys", | ||
| 1882 | "libc", | ||
| 1883 | ] | ||
| 1884 | |||
| 1885 | [[package]] | ||
| 1553 | name = "serde" | 1886 | name = "serde" |
| 1554 | version = "1.0.228" | 1887 | version = "1.0.228" |
| 1555 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1888 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1593,6 +1926,18 @@ dependencies = [ | |||
| 1593 | ] | 1926 | ] |
| 1594 | 1927 | ||
| 1595 | [[package]] | 1928 | [[package]] |
| 1929 | name = "serde_urlencoded" | ||
| 1930 | version = "0.7.1" | ||
| 1931 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1932 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" | ||
| 1933 | dependencies = [ | ||
| 1934 | "form_urlencoded", | ||
| 1935 | "itoa", | ||
| 1936 | "ryu", | ||
| 1937 | "serde", | ||
| 1938 | ] | ||
| 1939 | |||
| 1940 | [[package]] | ||
| 1596 | name = "sha1" | 1941 | name = "sha1" |
| 1597 | version = "0.10.6" | 1942 | version = "0.10.6" |
| 1598 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1943 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1652,6 +1997,16 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" | |||
| 1652 | 1997 | ||
| 1653 | [[package]] | 1998 | [[package]] |
| 1654 | name = "socket2" | 1999 | name = "socket2" |
| 2000 | version = "0.5.10" | ||
| 2001 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2002 | checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" | ||
| 2003 | dependencies = [ | ||
| 2004 | "libc", | ||
| 2005 | "windows-sys 0.52.0", | ||
| 2006 | ] | ||
| 2007 | |||
| 2008 | [[package]] | ||
| 2009 | name = "socket2" | ||
| 1655 | version = "0.6.1" | 2010 | version = "0.6.1" |
| 1656 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2011 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1657 | checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" | 2012 | checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" |
| @@ -1690,6 +2045,12 @@ dependencies = [ | |||
| 1690 | ] | 2045 | ] |
| 1691 | 2046 | ||
| 1692 | [[package]] | 2047 | [[package]] |
| 2048 | name = "sync_wrapper" | ||
| 2049 | version = "0.1.2" | ||
| 2050 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2051 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" | ||
| 2052 | |||
| 2053 | [[package]] | ||
| 1693 | name = "synstructure" | 2054 | name = "synstructure" |
| 1694 | version = "0.13.2" | 2055 | version = "0.13.2" |
| 1695 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2056 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1701,6 +2062,40 @@ dependencies = [ | |||
| 1701 | ] | 2062 | ] |
| 1702 | 2063 | ||
| 1703 | [[package]] | 2064 | [[package]] |
| 2065 | name = "system-configuration" | ||
| 2066 | version = "0.5.1" | ||
| 2067 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2068 | checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" | ||
| 2069 | dependencies = [ | ||
| 2070 | "bitflags 1.3.2", | ||
| 2071 | "core-foundation", | ||
| 2072 | "system-configuration-sys", | ||
| 2073 | ] | ||
| 2074 | |||
| 2075 | [[package]] | ||
| 2076 | name = "system-configuration-sys" | ||
| 2077 | version = "0.5.0" | ||
| 2078 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2079 | checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" | ||
| 2080 | dependencies = [ | ||
| 2081 | "core-foundation-sys", | ||
| 2082 | "libc", | ||
| 2083 | ] | ||
| 2084 | |||
| 2085 | [[package]] | ||
| 2086 | name = "tempfile" | ||
| 2087 | version = "3.23.0" | ||
| 2088 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2089 | checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" | ||
| 2090 | dependencies = [ | ||
| 2091 | "fastrand", | ||
| 2092 | "getrandom 0.3.4", | ||
| 2093 | "once_cell", | ||
| 2094 | "rustix", | ||
| 2095 | "windows-sys 0.61.2", | ||
| 2096 | ] | ||
| 2097 | |||
| 2098 | [[package]] | ||
| 1704 | name = "thiserror" | 2099 | name = "thiserror" |
| 1705 | version = "1.0.69" | 2100 | version = "1.0.69" |
| 1706 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2101 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1786,7 +2181,7 @@ dependencies = [ | |||
| 1786 | "parking_lot", | 2181 | "parking_lot", |
| 1787 | "pin-project-lite", | 2182 | "pin-project-lite", |
| 1788 | "signal-hook-registry", | 2183 | "signal-hook-registry", |
| 1789 | "socket2", | 2184 | "socket2 0.6.1", |
| 1790 | "tokio-macros", | 2185 | "tokio-macros", |
| 1791 | "windows-sys 0.61.2", | 2186 | "windows-sys 0.61.2", |
| 1792 | ] | 2187 | ] |
| @@ -1803,6 +2198,16 @@ dependencies = [ | |||
| 1803 | ] | 2198 | ] |
| 1804 | 2199 | ||
| 1805 | [[package]] | 2200 | [[package]] |
| 2201 | name = "tokio-native-tls" | ||
| 2202 | version = "0.3.1" | ||
| 2203 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2204 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" | ||
| 2205 | dependencies = [ | ||
| 2206 | "native-tls", | ||
| 2207 | "tokio", | ||
| 2208 | ] | ||
| 2209 | |||
| 2210 | [[package]] | ||
| 1806 | name = "tokio-rustls" | 2211 | name = "tokio-rustls" |
| 1807 | version = "0.26.4" | 2212 | version = "0.26.4" |
| 1808 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2213 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1878,6 +2283,12 @@ dependencies = [ | |||
| 1878 | ] | 2283 | ] |
| 1879 | 2284 | ||
| 1880 | [[package]] | 2285 | [[package]] |
| 2286 | name = "tower-service" | ||
| 2287 | version = "0.3.3" | ||
| 2288 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2289 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" | ||
| 2290 | |||
| 2291 | [[package]] | ||
| 1881 | name = "tracing" | 2292 | name = "tracing" |
| 1882 | version = "0.1.41" | 2293 | version = "0.1.41" |
| 1883 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2294 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1952,7 +2363,7 @@ checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" | |||
| 1952 | dependencies = [ | 2363 | dependencies = [ |
| 1953 | "bytes", | 2364 | "bytes", |
| 1954 | "data-encoding", | 2365 | "data-encoding", |
| 1955 | "http", | 2366 | "http 1.3.1", |
| 1956 | "httparse", | 2367 | "httparse", |
| 1957 | "log", | 2368 | "log", |
| 1958 | "rand 0.9.2", | 2369 | "rand 0.9.2", |
| @@ -2048,6 +2459,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 2048 | checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" | 2459 | checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" |
| 2049 | 2460 | ||
| 2050 | [[package]] | 2461 | [[package]] |
| 2462 | name = "vcpkg" | ||
| 2463 | version = "0.2.15" | ||
| 2464 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2465 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" | ||
| 2466 | |||
| 2467 | [[package]] | ||
| 2051 | name = "version_check" | 2468 | name = "version_check" |
| 2052 | version = "0.9.5" | 2469 | version = "0.9.5" |
| 2053 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2470 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -2224,6 +2641,15 @@ dependencies = [ | |||
| 2224 | 2641 | ||
| 2225 | [[package]] | 2642 | [[package]] |
| 2226 | name = "windows-sys" | 2643 | name = "windows-sys" |
| 2644 | version = "0.48.0" | ||
| 2645 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2646 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" | ||
| 2647 | dependencies = [ | ||
| 2648 | "windows-targets 0.48.5", | ||
| 2649 | ] | ||
| 2650 | |||
| 2651 | [[package]] | ||
| 2652 | name = "windows-sys" | ||
| 2227 | version = "0.52.0" | 2653 | version = "0.52.0" |
| 2228 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2654 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2229 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" | 2655 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" |
| @@ -2251,6 +2677,21 @@ dependencies = [ | |||
| 2251 | 2677 | ||
| 2252 | [[package]] | 2678 | [[package]] |
| 2253 | name = "windows-targets" | 2679 | name = "windows-targets" |
| 2680 | version = "0.48.5" | ||
| 2681 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2682 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" | ||
| 2683 | dependencies = [ | ||
| 2684 | "windows_aarch64_gnullvm 0.48.5", | ||
| 2685 | "windows_aarch64_msvc 0.48.5", | ||
| 2686 | "windows_i686_gnu 0.48.5", | ||
| 2687 | "windows_i686_msvc 0.48.5", | ||
| 2688 | "windows_x86_64_gnu 0.48.5", | ||
| 2689 | "windows_x86_64_gnullvm 0.48.5", | ||
| 2690 | "windows_x86_64_msvc 0.48.5", | ||
| 2691 | ] | ||
| 2692 | |||
| 2693 | [[package]] | ||
| 2694 | name = "windows-targets" | ||
| 2254 | version = "0.52.6" | 2695 | version = "0.52.6" |
| 2255 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2696 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2256 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" | 2697 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" |
| @@ -2284,6 +2725,12 @@ dependencies = [ | |||
| 2284 | 2725 | ||
| 2285 | [[package]] | 2726 | [[package]] |
| 2286 | name = "windows_aarch64_gnullvm" | 2727 | name = "windows_aarch64_gnullvm" |
| 2728 | version = "0.48.5" | ||
| 2729 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2730 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" | ||
| 2731 | |||
| 2732 | [[package]] | ||
| 2733 | name = "windows_aarch64_gnullvm" | ||
| 2287 | version = "0.52.6" | 2734 | version = "0.52.6" |
| 2288 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2735 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2289 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" | 2736 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" |
| @@ -2296,6 +2743,12 @@ checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" | |||
| 2296 | 2743 | ||
| 2297 | [[package]] | 2744 | [[package]] |
| 2298 | name = "windows_aarch64_msvc" | 2745 | name = "windows_aarch64_msvc" |
| 2746 | version = "0.48.5" | ||
| 2747 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2748 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" | ||
| 2749 | |||
| 2750 | [[package]] | ||
| 2751 | name = "windows_aarch64_msvc" | ||
| 2299 | version = "0.52.6" | 2752 | version = "0.52.6" |
| 2300 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2753 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2301 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" | 2754 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" |
| @@ -2308,6 +2761,12 @@ checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" | |||
| 2308 | 2761 | ||
| 2309 | [[package]] | 2762 | [[package]] |
| 2310 | name = "windows_i686_gnu" | 2763 | name = "windows_i686_gnu" |
| 2764 | version = "0.48.5" | ||
| 2765 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2766 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" | ||
| 2767 | |||
| 2768 | [[package]] | ||
| 2769 | name = "windows_i686_gnu" | ||
| 2311 | version = "0.52.6" | 2770 | version = "0.52.6" |
| 2312 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2771 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2313 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" | 2772 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" |
| @@ -2332,6 +2791,12 @@ checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" | |||
| 2332 | 2791 | ||
| 2333 | [[package]] | 2792 | [[package]] |
| 2334 | name = "windows_i686_msvc" | 2793 | name = "windows_i686_msvc" |
| 2794 | version = "0.48.5" | ||
| 2795 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2796 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" | ||
| 2797 | |||
| 2798 | [[package]] | ||
| 2799 | name = "windows_i686_msvc" | ||
| 2335 | version = "0.52.6" | 2800 | version = "0.52.6" |
| 2336 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2801 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2337 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" | 2802 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" |
| @@ -2344,6 +2809,12 @@ checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" | |||
| 2344 | 2809 | ||
| 2345 | [[package]] | 2810 | [[package]] |
| 2346 | name = "windows_x86_64_gnu" | 2811 | name = "windows_x86_64_gnu" |
| 2812 | version = "0.48.5" | ||
| 2813 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2814 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" | ||
| 2815 | |||
| 2816 | [[package]] | ||
| 2817 | name = "windows_x86_64_gnu" | ||
| 2347 | version = "0.52.6" | 2818 | version = "0.52.6" |
| 2348 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2819 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2349 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" | 2820 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" |
| @@ -2356,6 +2827,12 @@ checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" | |||
| 2356 | 2827 | ||
| 2357 | [[package]] | 2828 | [[package]] |
| 2358 | name = "windows_x86_64_gnullvm" | 2829 | name = "windows_x86_64_gnullvm" |
| 2830 | version = "0.48.5" | ||
| 2831 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2832 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" | ||
| 2833 | |||
| 2834 | [[package]] | ||
| 2835 | name = "windows_x86_64_gnullvm" | ||
| 2359 | version = "0.52.6" | 2836 | version = "0.52.6" |
| 2360 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2837 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2361 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" | 2838 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" |
| @@ -2368,6 +2845,12 @@ checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" | |||
| 2368 | 2845 | ||
| 2369 | [[package]] | 2846 | [[package]] |
| 2370 | name = "windows_x86_64_msvc" | 2847 | name = "windows_x86_64_msvc" |
| 2848 | version = "0.48.5" | ||
| 2849 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2850 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" | ||
| 2851 | |||
| 2852 | [[package]] | ||
| 2853 | name = "windows_x86_64_msvc" | ||
| 2371 | version = "0.52.6" | 2854 | version = "0.52.6" |
| 2372 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2855 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2373 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" | 2856 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" |
| @@ -2379,6 +2862,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 2379 | checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" | 2862 | checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" |
| 2380 | 2863 | ||
| 2381 | [[package]] | 2864 | [[package]] |
| 2865 | name = "winreg" | ||
| 2866 | version = "0.50.0" | ||
| 2867 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2868 | checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" | ||
| 2869 | dependencies = [ | ||
| 2870 | "cfg-if", | ||
| 2871 | "windows-sys 0.48.0", | ||
| 2872 | ] | ||
| 2873 | |||
| 2874 | [[package]] | ||
| 2382 | name = "wit-bindgen" | 2875 | name = "wit-bindgen" |
| 2383 | version = "0.46.0" | 2876 | version = "0.46.0" |
| 2384 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2877 | source = "registry+https://github.com/rust-lang/crates.io-index" |
diff --git a/grasp-audit/Cargo.toml b/grasp-audit/Cargo.toml index 278c855..0bc008a 100644 --- a/grasp-audit/Cargo.toml +++ b/grasp-audit/Cargo.toml | |||
| @@ -33,6 +33,10 @@ clap = { version = "4", features = ["derive"] } | |||
| 33 | uuid = { version = "1", features = ["v4"] } | 33 | uuid = { version = "1", features = ["v4"] } |
| 34 | chrono = "0.4" | 34 | chrono = "0.4" |
| 35 | 35 | ||
| 36 | # HTTP Client | ||
| 37 | reqwest = { version = "0.11", features = ["json"] } | ||
| 38 | regex = "1" | ||
| 39 | |||
| 36 | # Logging | 40 | # Logging |
| 37 | tracing = "0.1" | 41 | tracing = "0.1" |
| 38 | tracing-subscriber = { version = "0.3", features = ["env-filter"] } | 42 | tracing-subscriber = { version = "0.3", features = ["env-filter"] } |
diff --git a/grasp-audit/src/client.rs b/grasp-audit/src/client.rs index 019f4cb..35aaccd 100644 --- a/grasp-audit/src/client.rs +++ b/grasp-audit/src/client.rs | |||
| @@ -84,6 +84,25 @@ impl AuditClient { | |||
| 84 | self.keys.public_key() | 84 | self.keys.public_key() |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | /// Get the relay URL | ||
| 88 | pub async fn relay_url(&self) -> Result<String> { | ||
| 89 | let relays = self.client.relays().await; | ||
| 90 | let relay = relays.values().next() | ||
| 91 | .ok_or_else(|| anyhow!("No relays configured"))?; | ||
| 92 | Ok(relay.url().to_string()) | ||
| 93 | } | ||
| 94 | |||
| 95 | /// Convert WebSocket URL to HTTP(S) URL for NIP-11 requests | ||
| 96 | pub fn ws_to_http_url(ws_url: &str) -> Result<String> { | ||
| 97 | if ws_url.starts_with("ws://") { | ||
| 98 | Ok(ws_url.replace("ws://", "http://")) | ||
| 99 | } else if ws_url.starts_with("wss://") { | ||
| 100 | Ok(ws_url.replace("wss://", "https://")) | ||
| 101 | } else { | ||
| 102 | Err(anyhow!("Invalid WebSocket URL: {}", ws_url)) | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 87 | /// Check if connected to relay | 106 | /// Check if connected to relay |
| 88 | pub async fn is_connected(&self) -> bool { | 107 | pub async fn is_connected(&self) -> bool { |
| 89 | // Check if we have any connected relays | 108 | // Check if we have any connected relays |
diff --git a/grasp-audit/src/specs/grasp01/nip11_document.rs b/grasp-audit/src/specs/grasp01/nip11_document.rs index be04777..bb864f2 100644 --- a/grasp-audit/src/specs/grasp01/nip11_document.rs +++ b/grasp-audit/src/specs/grasp01/nip11_document.rs | |||
| @@ -34,25 +34,53 @@ impl Nip11DocumentTests { | |||
| 34 | /// | 34 | /// |
| 35 | /// Spec: Line 11 of ../grasp/01.md | 35 | /// Spec: Line 11 of ../grasp/01.md |
| 36 | /// Requirement: MUST serve NIP-11 document | 36 | /// Requirement: MUST serve NIP-11 document |
| 37 | async fn test_nip11_document_exists(_client: &AuditClient) -> TestResult { | 37 | pub async fn test_nip11_document_exists(client: &AuditClient) -> TestResult { |
| 38 | TestResult::new( | 38 | TestResult::new( |
| 39 | "nip11_document_exists", | 39 | "nip11_document_exists", |
| 40 | "GRASP-01:nostr-relay:11", | 40 | "GRASP-01:nostr-relay:11", |
| 41 | "Serve NIP-11 relay information document", | 41 | "Serve NIP-11 relay information document", |
| 42 | ) | 42 | ) |
| 43 | .run(|| async { | 43 | .run(|| async { |
| 44 | // TODO: Implementation | ||
| 45 | // 1. Extract HTTP(S) URL from client's WebSocket URL | 44 | // 1. Extract HTTP(S) URL from client's WebSocket URL |
| 46 | // - ws://localhost:8081 -> http://localhost:8081 | 45 | let ws_url = client.relay_url().await |
| 47 | // - wss://relay.example.com -> https://relay.example.com | 46 | .map_err(|e| format!("Failed to get relay URL: {}", e))?; |
| 48 | // 2. HTTP GET to base URL with header: | 47 | let http_url = AuditClient::ws_to_http_url(&ws_url) |
| 49 | // - Accept: application/nostr+json | 48 | .map_err(|e| format!("Failed to convert WebSocket URL to HTTP: {}", e))?; |
| 49 | |||
| 50 | // 2. HTTP GET to base URL with Accept: application/nostr+json header | ||
| 51 | let http_client = reqwest::Client::new(); | ||
| 52 | let response = http_client | ||
| 53 | .get(&http_url) | ||
| 54 | .header("Accept", "application/nostr+json") | ||
| 55 | .send() | ||
| 56 | .await | ||
| 57 | .map_err(|e| format!("Failed to fetch NIP-11 document: {}", e))?; | ||
| 58 | |||
| 50 | // 3. Verify 200 OK response | 59 | // 3. Verify 200 OK response |
| 60 | if !response.status().is_success() { | ||
| 61 | return Err(format!( | ||
| 62 | "Expected 200 OK, got {} {}", | ||
| 63 | response.status().as_u16(), | ||
| 64 | response.status().canonical_reason().unwrap_or("Unknown") | ||
| 65 | )); | ||
| 66 | } | ||
| 67 | |||
| 51 | // 4. Verify response is valid JSON | 68 | // 4. Verify response is valid JSON |
| 52 | // 5. Parse as NIP-11 document | 69 | let json_text = response.text().await |
| 53 | // 6. Verify has required fields (name, description, etc.) | 70 | .map_err(|e| format!("Failed to read response body: {}", e))?; |
| 71 | |||
| 72 | let doc: serde_json::Value = serde_json::from_str(&json_text) | ||
| 73 | .map_err(|e| format!("Response is not valid JSON: {}", e))?; | ||
| 54 | 74 | ||
| 55 | Err("Not implemented yet".to_string()) | 75 | // 5. Verify has required NIP-11 fields |
| 76 | let required_fields = ["name", "description", "software", "version"]; | ||
| 77 | for field in &required_fields { | ||
| 78 | if !doc.get(field).is_some() { | ||
| 79 | return Err(format!("Missing required NIP-11 field: {}", field)); | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | Ok(()) | ||
| 56 | }) | 84 | }) |
| 57 | .await | 85 | .await |
| 58 | } | 86 | } |
| @@ -61,22 +89,68 @@ impl Nip11DocumentTests { | |||
| 61 | /// | 89 | /// |
| 62 | /// Spec: Line 12 of ../grasp/01.md | 90 | /// Spec: Line 12 of ../grasp/01.md |
| 63 | /// Requirement: MUST list supported GRASPs as string array | 91 | /// Requirement: MUST list supported GRASPs as string array |
| 64 | async fn test_nip11_supported_grasps_field(_client: &AuditClient) -> TestResult { | 92 | pub async fn test_nip11_supported_grasps_field(client: &AuditClient) -> TestResult { |
| 65 | TestResult::new( | 93 | TestResult::new( |
| 66 | "nip11_supported_grasps_field", | 94 | "nip11_supported_grasps_field", |
| 67 | "GRASP-01:nostr-relay:12", | 95 | "GRASP-01:nostr-relay:12", |
| 68 | "NIP-11 document includes supported_grasps field with GRASP-01", | 96 | "NIP-11 document includes supported_grasps field with GRASP-01", |
| 69 | ) | 97 | ) |
| 70 | .run(|| async { | 98 | .run(|| async { |
| 71 | // TODO: Implementation | 99 | // 1. Fetch NIP-11 document |
| 72 | // 1. Fetch NIP-11 document (same as above) | 100 | let ws_url = client.relay_url().await |
| 101 | .map_err(|e| format!("Failed to get relay URL: {}", e))?; | ||
| 102 | let http_url = AuditClient::ws_to_http_url(&ws_url) | ||
| 103 | .map_err(|e| format!("Failed to convert WebSocket URL to HTTP: {}", e))?; | ||
| 104 | |||
| 105 | let http_client = reqwest::Client::new(); | ||
| 106 | let response = http_client | ||
| 107 | .get(&http_url) | ||
| 108 | .header("Accept", "application/nostr+json") | ||
| 109 | .send() | ||
| 110 | .await | ||
| 111 | .map_err(|e| format!("Failed to fetch NIP-11 document: {}", e))?; | ||
| 112 | |||
| 113 | let json_text = response.text().await | ||
| 114 | .map_err(|e| format!("Failed to read response body: {}", e))?; | ||
| 115 | |||
| 116 | let doc: serde_json::Value = serde_json::from_str(&json_text) | ||
| 117 | .map_err(|e| format!("Response is not valid JSON: {}", e))?; | ||
| 118 | |||
| 73 | // 2. Verify `supported_grasps` field exists | 119 | // 2. Verify `supported_grasps` field exists |
| 74 | // 3. Verify it's a JSON array of strings | 120 | let supported_grasps = doc.get("supported_grasps") |
| 121 | .ok_or_else(|| "Missing required field: supported_grasps".to_string())?; | ||
| 122 | |||
| 123 | // 3. Verify it's a JSON array | ||
| 124 | let grasps_array = supported_grasps.as_array() | ||
| 125 | .ok_or_else(|| "supported_grasps must be an array".to_string())?; | ||
| 126 | |||
| 75 | // 4. Verify array includes "GRASP-01" | 127 | // 4. Verify array includes "GRASP-01" |
| 76 | // 5. Verify format: each entry matches pattern "GRASP-\d{2}" | 128 | let grasp_strings: Vec<String> = grasps_array |
| 77 | // 6. Document other GRASPs found (for info) | 129 | .iter() |
| 130 | .filter_map(|v| v.as_str().map(|s| s.to_string())) | ||
| 131 | .collect(); | ||
| 132 | |||
| 133 | if !grasp_strings.contains(&"GRASP-01".to_string()) { | ||
| 134 | return Err(format!( | ||
| 135 | "supported_grasps must include 'GRASP-01', found: {:?}", | ||
| 136 | grasp_strings | ||
| 137 | )); | ||
| 138 | } | ||
| 139 | |||
| 140 | // 5. Verify format: each entry should match pattern "GRASP-\d{2}" | ||
| 141 | let grasp_pattern = regex::Regex::new(r"^GRASP-\d{2}$") | ||
| 142 | .map_err(|e| format!("Failed to compile regex: {}", e))?; | ||
| 143 | |||
| 144 | for grasp in &grasp_strings { | ||
| 145 | if !grasp_pattern.is_match(grasp) { | ||
| 146 | return Err(format!( | ||
| 147 | "Invalid GRASP format: '{}' (expected GRASP-XX where XX is two digits)", | ||
| 148 | grasp | ||
| 149 | )); | ||
| 150 | } | ||
| 151 | } | ||
| 78 | 152 | ||
| 79 | Err("Not implemented yet".to_string()) | 153 | Ok(()) |
| 80 | }) | 154 | }) |
| 81 | .await | 155 | .await |
| 82 | } | 156 | } |
| @@ -85,23 +159,47 @@ impl Nip11DocumentTests { | |||
| 85 | /// | 159 | /// |
| 86 | /// Spec: Line 13 of ../grasp/01.md | 160 | /// Spec: Line 13 of ../grasp/01.md |
| 87 | /// Requirement: MUST list repository acceptance criteria | 161 | /// Requirement: MUST list repository acceptance criteria |
| 88 | async fn test_nip11_repo_acceptance_criteria_field(_client: &AuditClient) -> TestResult { | 162 | pub async fn test_nip11_repo_acceptance_criteria_field(client: &AuditClient) -> TestResult { |
| 89 | TestResult::new( | 163 | TestResult::new( |
| 90 | "nip11_repo_acceptance_criteria_field", | 164 | "nip11_repo_acceptance_criteria_field", |
| 91 | "GRASP-01:nostr-relay:13", | 165 | "GRASP-01:nostr-relay:13", |
| 92 | "NIP-11 document includes repo_acceptance_criteria field", | 166 | "NIP-11 document includes repo_acceptance_criteria field", |
| 93 | ) | 167 | ) |
| 94 | .run(|| async { | 168 | .run(|| async { |
| 95 | // TODO: Implementation | ||
| 96 | // 1. Fetch NIP-11 document | 169 | // 1. Fetch NIP-11 document |
| 170 | let ws_url = client.relay_url().await | ||
| 171 | .map_err(|e| format!("Failed to get relay URL: {}", e))?; | ||
| 172 | let http_url = AuditClient::ws_to_http_url(&ws_url) | ||
| 173 | .map_err(|e| format!("Failed to convert WebSocket URL to HTTP: {}", e))?; | ||
| 174 | |||
| 175 | let http_client = reqwest::Client::new(); | ||
| 176 | let response = http_client | ||
| 177 | .get(&http_url) | ||
| 178 | .header("Accept", "application/nostr+json") | ||
| 179 | .send() | ||
| 180 | .await | ||
| 181 | .map_err(|e| format!("Failed to fetch NIP-11 document: {}", e))?; | ||
| 182 | |||
| 183 | let json_text = response.text().await | ||
| 184 | .map_err(|e| format!("Failed to read response body: {}", e))?; | ||
| 185 | |||
| 186 | let doc: serde_json::Value = serde_json::from_str(&json_text) | ||
| 187 | .map_err(|e| format!("Response is not valid JSON: {}", e))?; | ||
| 188 | |||
| 97 | // 2. Verify `repo_acceptance_criteria` field exists | 189 | // 2. Verify `repo_acceptance_criteria` field exists |
| 98 | // 3. Verify it's a string (human-readable) | 190 | let criteria = doc.get("repo_acceptance_criteria") |
| 191 | .ok_or_else(|| "Missing required field: repo_acceptance_criteria".to_string())?; | ||
| 192 | |||
| 193 | // 3. Verify it's a string | ||
| 194 | let criteria_str = criteria.as_str() | ||
| 195 | .ok_or_else(|| "repo_acceptance_criteria must be a string".to_string())?; | ||
| 196 | |||
| 99 | // 4. Verify non-empty | 197 | // 4. Verify non-empty |
| 100 | // 5. Document the criteria (for info) | 198 | if criteria_str.trim().is_empty() { |
| 101 | // Examples: "Must list this relay in clone and relays tags" | 199 | return Err("repo_acceptance_criteria must not be empty".to_string()); |
| 102 | // "Pre-payment required via Lightning invoice" | 200 | } |
| 103 | 201 | ||
| 104 | Err("Not implemented yet".to_string()) | 202 | Ok(()) |
| 105 | }) | 203 | }) |
| 106 | .await | 204 | .await |
| 107 | } | 205 | } |
| @@ -110,24 +208,47 @@ impl Nip11DocumentTests { | |||
| 110 | /// | 208 | /// |
| 111 | /// Spec: Line 14 of ../grasp/01.md | 209 | /// Spec: Line 14 of ../grasp/01.md |
| 112 | /// Requirement: MUST include curation if curated, omit otherwise | 210 | /// Requirement: MUST include curation if curated, omit otherwise |
| 113 | async fn test_nip11_curation_field(_client: &AuditClient) -> TestResult { | 211 | pub async fn test_nip11_curation_field(client: &AuditClient) -> TestResult { |
| 114 | TestResult::new( | 212 | TestResult::new( |
| 115 | "nip11_curation_field", | 213 | "nip11_curation_field", |
| 116 | "GRASP-01:nostr-relay:14", | 214 | "GRASP-01:nostr-relay:14", |
| 117 | "NIP-11 curation field present if curated, absent otherwise", | 215 | "NIP-11 curation field present if curated, absent otherwise", |
| 118 | ) | 216 | ) |
| 119 | .run(|| async { | 217 | .run(|| async { |
| 120 | // TODO: Implementation | ||
| 121 | // 1. Fetch NIP-11 document | 218 | // 1. Fetch NIP-11 document |
| 219 | let ws_url = client.relay_url().await | ||
| 220 | .map_err(|e| format!("Failed to get relay URL: {}", e))?; | ||
| 221 | let http_url = AuditClient::ws_to_http_url(&ws_url) | ||
| 222 | .map_err(|e| format!("Failed to convert WebSocket URL to HTTP: {}", e))?; | ||
| 223 | |||
| 224 | let http_client = reqwest::Client::new(); | ||
| 225 | let response = http_client | ||
| 226 | .get(&http_url) | ||
| 227 | .header("Accept", "application/nostr+json") | ||
| 228 | .send() | ||
| 229 | .await | ||
| 230 | .map_err(|e| format!("Failed to fetch NIP-11 document: {}", e))?; | ||
| 231 | |||
| 232 | let json_text = response.text().await | ||
| 233 | .map_err(|e| format!("Failed to read response body: {}", e))?; | ||
| 234 | |||
| 235 | let doc: serde_json::Value = serde_json::from_str(&json_text) | ||
| 236 | .map_err(|e| format!("Response is not valid JSON: {}", e))?; | ||
| 237 | |||
| 122 | // 2. Check if `curation` field exists | 238 | // 2. Check if `curation` field exists |
| 123 | // 3. If present: | 239 | if let Some(curation) = doc.get("curation") { |
| 124 | // - Verify it's a non-empty string | 240 | // 3. If present: verify it's a non-empty string |
| 125 | // - Document the curation policy | 241 | let curation_str = curation.as_str() |
| 126 | // 4. If absent: | 242 | .ok_or_else(|| "curation field must be a string when present".to_string())?; |
| 127 | // - Document that no curation beyond SPAM prevention | 243 | |
| 128 | // 5. Both cases are valid per spec | 244 | if curation_str.trim().is_empty() { |
| 129 | 245 | return Err("curation field must not be empty when present".to_string()); | |
| 130 | Err("Not implemented yet".to_string()) | 246 | } |
| 247 | } | ||
| 248 | // 4. If absent: both cases are valid per spec | ||
| 249 | |||
| 250 | // 5. Both cases are valid - test passes | ||
| 251 | Ok(()) | ||
| 131 | }) | 252 | }) |
| 132 | .await | 253 | .await |
| 133 | } | 254 | } |
| @@ -163,4 +284,4 @@ mod tests { | |||
| 163 | // Don't assert all passed yet - tests not implemented | 284 | // Don't assert all passed yet - tests not implemented |
| 164 | // assert!(results.all_passed(), "Some GRASP-01 NIP-11 document tests failed"); | 285 | // assert!(results.all_passed(), "Some GRASP-01 NIP-11 document tests failed"); |
| 165 | } | 286 | } |
| 166 | } | 287 | } \ No newline at end of file |
diff --git a/src/http/mod.rs b/src/http/mod.rs index 4690790..7c0e7bb 100644 --- a/src/http/mod.rs +++ b/src/http/mod.rs | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | /// | 2 | /// |
| 3 | /// Provides hyper HTTP server with WebSocket upgrade support for the Nostr relay. | 3 | /// Provides hyper HTTP server with WebSocket upgrade support for the Nostr relay. |
| 4 | pub mod landing; | 4 | pub mod landing; |
| 5 | pub mod nip11; | ||
| 5 | 6 | ||
| 6 | use std::future::Future; | 7 | use std::future::Future; |
| 7 | use std::net::SocketAddr; | 8 | use std::net::SocketAddr; |
| @@ -46,6 +47,32 @@ impl Service<Request<Incoming>> for HttpService { | |||
| 46 | fn call(&self, req: Request<Incoming>) -> Self::Future { | 47 | fn call(&self, req: Request<Incoming>) -> Self::Future { |
| 47 | let base = Response::builder().header("server", "ngit-grasp"); | 48 | let base = Response::builder().header("server", "ngit-grasp"); |
| 48 | 49 | ||
| 50 | // Check for NIP-11 relay information request (Accept: application/nostr+json) | ||
| 51 | if let Some(accept) = req.headers().get("accept") { | ||
| 52 | if accept | ||
| 53 | .to_str() | ||
| 54 | .map(|s| s.contains("application/nostr+json")) | ||
| 55 | .unwrap_or(false) | ||
| 56 | { | ||
| 57 | let doc = nip11::RelayInformationDocument::from_config(&self.config); | ||
| 58 | let json = doc.to_json().unwrap_or_else(|e| { | ||
| 59 | tracing::error!("Failed to serialize NIP-11 document: {}", e); | ||
| 60 | "{}".to_string() | ||
| 61 | }); | ||
| 62 | |||
| 63 | tracing::debug!("Serving NIP-11 relay information document to {}", self.remote); | ||
| 64 | |||
| 65 | return Box::pin(async move { | ||
| 66 | Ok(base | ||
| 67 | .status(200) | ||
| 68 | .header("content-type", "application/nostr+json") | ||
| 69 | .header("access-control-allow-origin", "*") | ||
| 70 | .body(json) | ||
| 71 | .unwrap()) | ||
| 72 | }); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 49 | // Check if this is a WebSocket upgrade request | 76 | // Check if this is a WebSocket upgrade request |
| 50 | if let (Some(c), Some(w)) = ( | 77 | if let (Some(c), Some(w)) = ( |
| 51 | req.headers().get("connection"), | 78 | req.headers().get("connection"), |
diff --git a/src/http/nip11.rs b/src/http/nip11.rs new file mode 100644 index 0000000..a93ee5f --- /dev/null +++ b/src/http/nip11.rs | |||
| @@ -0,0 +1,146 @@ | |||
| 1 | /// NIP-11 Relay Information Document | ||
| 2 | /// | ||
| 3 | /// Implements NIP-11 relay information endpoint with GRASP-01 extensions. | ||
| 4 | /// See: https://github.com/nostr-protocol/nips/blob/master/11.md | ||
| 5 | |||
| 6 | use serde::{Deserialize, Serialize}; | ||
| 7 | use crate::config::Config; | ||
| 8 | |||
| 9 | /// NIP-11 Relay Information Document | ||
| 10 | /// | ||
| 11 | /// This structure represents the relay metadata served at the HTTP(S) endpoint | ||
| 12 | /// when the client sends `Accept: application/nostr+json` header. | ||
| 13 | #[derive(Debug, Clone, Serialize, Deserialize)] | ||
| 14 | pub struct RelayInformationDocument { | ||
| 15 | /// Relay name | ||
| 16 | pub name: String, | ||
| 17 | |||
| 18 | /// Relay description | ||
| 19 | pub description: String, | ||
| 20 | |||
| 21 | /// Relay owner's public key (hex format) | ||
| 22 | #[serde(skip_serializing_if = "Option::is_none")] | ||
| 23 | pub pubkey: Option<String>, | ||
| 24 | |||
| 25 | /// Contact information for relay admin | ||
| 26 | #[serde(skip_serializing_if = "Option::is_none")] | ||
| 27 | pub contact: Option<String>, | ||
| 28 | |||
| 29 | /// List of NIPs supported by this relay | ||
| 30 | pub supported_nips: Vec<u16>, | ||
| 31 | |||
| 32 | /// Relay software identifier | ||
| 33 | pub software: String, | ||
| 34 | |||
| 35 | /// Software version | ||
| 36 | pub version: String, | ||
| 37 | |||
| 38 | // GRASP-01 Extensions (lines 11-14 of GRASP-01 spec) | ||
| 39 | |||
| 40 | /// List of supported GRASPs (e.g., ["GRASP-01"]) | ||
| 41 | /// Required by GRASP-01 specification line 12 | ||
| 42 | pub supported_grasps: Vec<String>, | ||
| 43 | |||
| 44 | /// Repository acceptance criteria description | ||
| 45 | /// Required by GRASP-01 specification line 13 | ||
| 46 | pub repo_acceptance_criteria: String, | ||
| 47 | |||
| 48 | /// Curation policy (present if curated, absent otherwise) | ||
| 49 | /// Optional per GRASP-01 specification line 14 | ||
| 50 | #[serde(skip_serializing_if = "Option::is_none")] | ||
| 51 | pub curation: Option<String>, | ||
| 52 | } | ||
| 53 | |||
| 54 | impl RelayInformationDocument { | ||
| 55 | /// Create NIP-11 relay information document from configuration | ||
| 56 | pub fn from_config(config: &Config) -> Self { | ||
| 57 | Self { | ||
| 58 | name: config.relay_name.clone(), | ||
| 59 | description: config.relay_description.clone(), | ||
| 60 | pubkey: Some(config.owner_npub.clone()), | ||
| 61 | contact: None, // Could be added to config if needed | ||
| 62 | supported_nips: vec![ | ||
| 63 | 1, // NIP-01: Basic protocol flow | ||
| 64 | 11, // NIP-11: Relay information document (this!) | ||
| 65 | 34, // NIP-34: Git repository announcements | ||
| 66 | ], | ||
| 67 | software: env!("CARGO_PKG_NAME").to_string(), | ||
| 68 | version: env!("CARGO_PKG_VERSION").to_string(), | ||
| 69 | |||
| 70 | // GRASP-01 Extensions | ||
| 71 | supported_grasps: vec!["GRASP-01".to_string()], | ||
| 72 | repo_acceptance_criteria: format!( | ||
| 73 | "Repositories must list this relay ({}) in both 'clone' and 'relays' tags of kind 30617 announcements. \ | ||
| 74 | All other events must reference accepted repositories or accepted events.", | ||
| 75 | config.domain | ||
| 76 | ), | ||
| 77 | curation: None, // Not a curated relay - only SPAM prevention via GRASP-01 policy | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | /// Serialize to JSON string | ||
| 82 | pub fn to_json(&self) -> Result<String, serde_json::Error> { | ||
| 83 | serde_json::to_string_pretty(self) | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | #[cfg(test)] | ||
| 88 | mod tests { | ||
| 89 | use super::*; | ||
| 90 | |||
| 91 | #[test] | ||
| 92 | fn test_relay_information_document_structure() { | ||
| 93 | let config = Config { | ||
| 94 | domain: "relay.example.com".to_string(), | ||
| 95 | owner_npub: "npub1test".to_string(), | ||
| 96 | relay_name: "Test Relay".to_string(), | ||
| 97 | relay_description: "A test relay".to_string(), | ||
| 98 | git_data_path: "./data/git".to_string(), | ||
| 99 | relay_data_path: "./data/relay".to_string(), | ||
| 100 | bind_address: "127.0.0.1:8080".to_string(), | ||
| 101 | database_backend: crate::config::DatabaseBackend::Memory, | ||
| 102 | }; | ||
| 103 | |||
| 104 | let doc = RelayInformationDocument::from_config(&config); | ||
| 105 | |||
| 106 | assert_eq!(doc.name, "Test Relay"); | ||
| 107 | assert_eq!(doc.description, "A test relay"); | ||
| 108 | assert_eq!(doc.pubkey, Some("npub1test".to_string())); | ||
| 109 | assert!(doc.supported_nips.contains(&1)); | ||
| 110 | assert!(doc.supported_nips.contains(&11)); | ||
| 111 | assert!(doc.supported_nips.contains(&34)); | ||
| 112 | assert_eq!(doc.supported_grasps, vec!["GRASP-01"]); | ||
| 113 | assert!(doc.repo_acceptance_criteria.contains("relay.example.com")); | ||
| 114 | assert!(doc.curation.is_none()); | ||
| 115 | } | ||
| 116 | |||
| 117 | #[test] | ||
| 118 | fn test_relay_information_document_json() { | ||
| 119 | let config = Config { | ||
| 120 | domain: "relay.example.com".to_string(), | ||
| 121 | owner_npub: "npub1test".to_string(), | ||
| 122 | relay_name: "Test Relay".to_string(), | ||
| 123 | relay_description: "A test relay".to_string(), | ||
| 124 | git_data_path: "./data/git".to_string(), | ||
| 125 | relay_data_path: "./data/relay".to_string(), | ||
| 126 | bind_address: "127.0.0.1:8080".to_string(), | ||
| 127 | database_backend: crate::config::DatabaseBackend::Memory, | ||
| 128 | }; | ||
| 129 | |||
| 130 | let doc = RelayInformationDocument::from_config(&config); | ||
| 131 | let json = doc.to_json().expect("Failed to serialize to JSON"); | ||
| 132 | |||
| 133 | // Verify JSON contains expected fields | ||
| 134 | assert!(json.contains("\"name\"")); | ||
| 135 | assert!(json.contains("\"description\"")); | ||
| 136 | assert!(json.contains("\"supported_nips\"")); | ||
| 137 | assert!(json.contains("\"supported_grasps\"")); | ||
| 138 | assert!(json.contains("\"repo_acceptance_criteria\"")); | ||
| 139 | assert!(json.contains("GRASP-01")); | ||
| 140 | |||
| 141 | // Verify it's valid JSON by parsing | ||
| 142 | let parsed: serde_json::Value = serde_json::from_str(&json).expect("Invalid JSON"); | ||
| 143 | assert_eq!(parsed["name"], "Test Relay"); | ||
| 144 | assert_eq!(parsed["supported_grasps"][0], "GRASP-01"); | ||
| 145 | } | ||
| 146 | } \ No newline at end of file | ||
diff --git a/tests/nip11_document.rs b/tests/nip11_document.rs new file mode 100644 index 0000000..da8e9ce --- /dev/null +++ b/tests/nip11_document.rs | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | //! GRASP-01 NIP-11 Document Integration Tests | ||
| 2 | //! | ||
| 3 | //! Tests ngit-grasp relay's implementation of GRASP-01 NIP-11 relay information requirements. | ||
| 4 | //! Uses grasp-audit library to avoid code duplication. | ||
| 5 | //! | ||
| 6 | //! # Test Strategy | ||
| 7 | //! | ||
| 8 | //! - Each test runs in complete isolation with its own fresh relay instance | ||
| 9 | //! - Uses macro to eliminate boilerplate while maintaining test isolation | ||
| 10 | //! - Calls individual test methods from grasp-audit for minimal duplication | ||
| 11 | //! | ||
| 12 | //! # Running Tests | ||
| 13 | //! | ||
| 14 | //! ```bash | ||
| 15 | //! # Run all GRASP-01 NIP-11 tests | ||
| 16 | //! cargo test --test nip11_document | ||
| 17 | //! | ||
| 18 | //! # Run specific test | ||
| 19 | //! cargo test --test nip11_document test_nip11_document_exists | ||
| 20 | //! | ||
| 21 | //! # With output | ||
| 22 | //! cargo test --test nip11_document -- --nocapture | ||
| 23 | //! ``` | ||
| 24 | |||
| 25 | mod common; | ||
| 26 | |||
| 27 | use common::TestRelay; | ||
| 28 | use grasp_audit::*; | ||
| 29 | |||
| 30 | /// Macro to generate isolated integration tests | ||
| 31 | /// | ||
| 32 | /// Each test runs with its own fresh relay instance to ensure complete isolation. | ||
| 33 | /// This eliminates rate-limiting issues and ensures tests don't interfere with each other. | ||
| 34 | macro_rules! isolated_test { | ||
| 35 | ($test_name:ident) => { | ||
| 36 | #[tokio::test] | ||
| 37 | async fn $test_name() { | ||
| 38 | let relay = TestRelay::start().await; | ||
| 39 | let config = AuditConfig::ci(); | ||
| 40 | let client = AuditClient::new(relay.url(), config) | ||
| 41 | .await | ||
| 42 | .expect("Failed to create audit client"); | ||
| 43 | |||
| 44 | let result = specs::Nip11DocumentTests::$test_name(&client).await; | ||
| 45 | |||
| 46 | relay.stop().await; | ||
| 47 | |||
| 48 | assert!( | ||
| 49 | result.passed, | ||
| 50 | "{} failed: {}", | ||
| 51 | stringify!($test_name), | ||
| 52 | result.error.as_deref().unwrap_or("unknown error") | ||
| 53 | ); | ||
| 54 | } | ||
| 55 | }; | ||
| 56 | } | ||
| 57 | |||
| 58 | // Generate isolated tests for all GRASP-01 NIP-11 document tests | ||
| 59 | isolated_test!(test_nip11_document_exists); | ||
| 60 | isolated_test!(test_nip11_supported_grasps_field); | ||
| 61 | isolated_test!(test_nip11_repo_acceptance_criteria_field); | ||
| 62 | isolated_test!(test_nip11_curation_field); \ No newline at end of file | ||