diff --git a/.github/workflows/xmtp_api_grpc_gateway_test.yaml b/.github/workflows/xmtp_api_grpc_gateway_test.yaml new file mode 100644 index 000000000..3e284f862 --- /dev/null +++ b/.github/workflows/xmtp_api_grpc_gateway_test.yaml @@ -0,0 +1,14 @@ +on: + push: + branches: + - main + pull_request: +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: nanasess/setup-chromedriver@master + - run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + - run: wasm-pack test --headless --chrome + working-directory: xmtp_api_grpc_gateway diff --git a/Cargo.lock b/Cargo.lock index c19c81239..b2313aecc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2264,7 +2264,7 @@ dependencies = [ "http", "hyper", "log", - "rustls 0.21.1", + "rustls 0.21.7", "rustls-native-certs", "tokio", "tokio-rustls 0.24.0", @@ -3804,9 +3804,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ "base64 0.21.1", "bytes 1.4.0", @@ -3827,7 +3827,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.1", + "rustls 0.21.7", "rustls-pemfile", "serde", "serde_json", @@ -3840,7 +3840,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.22.6", + "webpki-roots 0.25.2", "winreg", ] @@ -3998,13 +3998,13 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.1" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", - "rustls-webpki", + "rustls-webpki 0.101.4", "sct", ] @@ -4039,6 +4039,16 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustls-webpki" +version = "0.101.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.12" @@ -4800,7 +4810,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" dependencies = [ - "rustls 0.21.1", + "rustls 0.21.7", "tokio", ] @@ -5380,9 +5390,15 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa54963694b65584e170cf5dc46aeb4dcaa5584e652ff5f3952e56d66aff0125" dependencies = [ - "rustls-webpki", + "rustls-webpki 0.100.1", ] +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + [[package]] name = "which" version = "4.4.0" @@ -5604,11 +5620,12 @@ dependencies = [ [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi 0.3.9", + "cfg-if 1.0.0", + "windows-sys 0.48.0", ] [[package]] @@ -5683,8 +5700,9 @@ dependencies = [ "url", "walletconnect", "xmtp", + "xmtp_api_grpc", "xmtp_cryptography", - "xmtp_networking", + "xmtp_proto", ] [[package]] @@ -5718,25 +5736,7 @@ dependencies = [ ] [[package]] -name = "xmtp_cryptography" -version = "0.1.0" -dependencies = [ - "ecdsa 0.15.1", - "ethers", - "ethers-core 2.0.4", - "hex", - "k256 0.12.0", - "rand 0.8.5", - "rand_chacha 0.3.1", - "serde", - "sha2 0.10.7", - "sha3 0.10.8", - "thiserror", - "tokio", -] - -[[package]] -name = "xmtp_networking" +name = "xmtp_api_grpc" version = "0.1.0" dependencies = [ "base64 0.21.1", @@ -5754,14 +5754,32 @@ dependencies = [ "tower", "uuid 1.3.3", "webpki-roots 0.23.0", - "xmtp", "xmtp_proto", ] +[[package]] +name = "xmtp_cryptography" +version = "0.1.0" +dependencies = [ + "ecdsa 0.15.1", + "ethers", + "ethers-core 2.0.4", + "hex", + "k256 0.12.0", + "rand 0.8.5", + "rand_chacha 0.3.1", + "serde", + "sha2 0.10.7", + "sha3 0.10.8", + "thiserror", + "tokio", +] + [[package]] name = "xmtp_proto" version = "0.1.0" dependencies = [ + "async-trait", "pbjson", "pbjson-types", "prost", diff --git a/Cargo.toml b/Cargo.toml index 85d9442d3..89a2dd8a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,20 +4,16 @@ members = [ "examples/cli", "xmtp", "xmtp_cryptography", - "xmtp_networking", -# TODO: replace ^ with: -# "xmtp_api_grpc", -# "xmtp_api_grpc_gateway", + "xmtp_api_grpc", "xmtp_proto", ] -# Exclude since -# 1) no reason to share profile with other core crates -# 2) moreover, bindings_swift and xmtp_dh need their own size-optimized profile +# Exclude since `bindings_swift` and `bindings_wasm` need specific profiles. exclude = [ "bindings_ffi", "bindings_js", "bindings_wasm", + "xmtp_api_grpc_gateway", ] # Make the feature resolver explicit. diff --git a/README.md b/README.md index 07f20ab57..2122eea29 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,8 @@ Start Docker Desktop. - [`xmtp`](https://github.com/xmtp/libxmtp/tree/main/xmtp): Pure Rust implementation of XMTP APIs, agnostic to any per-language or per-platform binding - [`xmtp_cryptography`](https://github.com/xmtp/libxmtp/tree/main/xmtp_cryptography): Cryptographic operations -- [`xmtp_networking`](https://github.com/xmtp/libxmtp/tree/main/xmtp_networking): API client for XMTP's gRPC API, using code fromĀ `xmtp_proto` +- [`xmtp_api_grpc`](https://github.com/xmtp/libxmtp/tree/main/xmtp_api_grpc): API client for XMTP's gRPC API, using code from `xmtp_proto` +- [`xmtp_api_grpc_gateway`](https://github.com/xmtp/libxmtp/tree/main/xmtp_api_grpc_gateway): API client for XMTP's gRPC Gateway API, using code from `xmtp_proto` (in progress) - [`xmtp_proto`](https://github.com/xmtp/libxmtp/tree/main/xmtp_proto): Generated code for handling XMTP protocol buffers - [`examples/cli`](https://github.com/xmtp/libxmtp/tree/main/examples/cli): Example XMTP console client. Use the CLI to try out sending double ratchet messages on the XMTP `dev` network. - [`examples/android/xmtpv3_example`](https://github.com/xmtp/libxmtp/tree/main/examples/android/xmtpv3_example): Example Android app (in progress) diff --git a/bindings_ffi/Cargo.toml b/bindings_ffi/Cargo.toml index 9500f5062..cfcf0f801 100644 --- a/bindings_ffi/Cargo.toml +++ b/bindings_ffi/Cargo.toml @@ -18,7 +18,7 @@ uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "cae8edc45ba5b56b uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "cae8edc45ba5b56bfcbf35b60c1ab6a97d1bf9da" } xmtp = { path = "../xmtp", features = ["grpc", "native"] } xmtp_cryptography = { path = "../xmtp_cryptography" } -xmtp_networking = { path = "../xmtp_networking" } +xmtp_api_grpc = { path = "../xmtp_api_grpc" } [build_dependencies] uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "cae8edc45ba5b56bfcbf35b60c1ab6a97d1bf9da", features = [ diff --git a/bindings_ffi/src/lib.rs b/bindings_ffi/src/lib.rs index 3e89eb642..c557fd691 100644 --- a/bindings_ffi/src/lib.rs +++ b/bindings_ffi/src/lib.rs @@ -12,7 +12,7 @@ use xmtp::conversation::{ListMessagesOptions, SecretConversation}; use xmtp::conversations::Conversations; use xmtp::storage::{EncryptedMessageStore, EncryptionKey, StorageOption, StoredMessage}; use xmtp::types::Address; -use xmtp_networking::grpc_api_helper::Client as TonicApiClient; +use xmtp_api_grpc::grpc_api_helper::Client as TonicApiClient; use crate::inbox_owner::RustInboxOwner; pub use crate::inbox_owner::SigningError; @@ -314,7 +314,7 @@ mod tests { create_client( Box::new(MockLogger {}), Box::new(ffi_inbox_owner), - xmtp_networking::LOCALHOST_ADDRESS.to_string(), + xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, None, None, @@ -339,7 +339,7 @@ mod tests { let client_a = create_client( Box::new(MockLogger {}), Box::new(ffi_inbox_owner.clone()), - xmtp_networking::LOCALHOST_ADDRESS.to_string(), + xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path.to_string_lossy().to_string()), None, @@ -353,7 +353,7 @@ mod tests { let client_b = create_client( Box::new(MockLogger {}), Box::new(ffi_inbox_owner), - xmtp_networking::LOCALHOST_ADDRESS.to_string(), + xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path.to_string_lossy().to_string()), None, @@ -381,7 +381,7 @@ mod tests { let client_a = create_client( Box::new(MockLogger {}), Box::new(ffi_inbox_owner.clone()), - xmtp_networking::LOCALHOST_ADDRESS.to_string(), + xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path.to_string_lossy().to_string()), Some(key), @@ -397,7 +397,7 @@ mod tests { let result_errored = create_client( Box::new(MockLogger {}), Box::new(ffi_inbox_owner), - xmtp_networking::LOCALHOST_ADDRESS.to_string(), + xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path.to_string_lossy().to_string()), Some(other_key.to_vec()), diff --git a/bindings_wasm/Cargo.toml b/bindings_wasm/Cargo.toml index 7fc8ced31..73184ee6c 100644 --- a/bindings_wasm/Cargo.toml +++ b/bindings_wasm/Cargo.toml @@ -15,6 +15,7 @@ prost = { version = "0.11", features = ["prost-derive"] } prost-types = "0.11" wasm-bindgen = "0.2.87" wasm-bindgen-futures = "0.4.37" +xmtp_api_grpc_gateway = { path = "../xmtp_api_grpc_gateway" } xmtp_cryptography = { path = "../xmtp_cryptography" } xmtp_proto = { path = "../xmtp_proto", features = ["proto_full"] } diff --git a/bindings_wasm/README.md b/bindings_wasm/README.md index de37be264..abf8e834b 100644 --- a/bindings_wasm/README.md +++ b/bindings_wasm/README.md @@ -5,5 +5,5 @@ This code is still under development. - `$ cd bindings_wasm` -- `$ wasm-pack test --headless chrome` +- `$ wasm-pack test --headless --chrome` - `$ wasm-pack build` diff --git a/bindings_wasm/src/lib.rs b/bindings_wasm/src/lib.rs index db323fcf8..395736078 100644 --- a/bindings_wasm/src/lib.rs +++ b/bindings_wasm/src/lib.rs @@ -1,15 +1,25 @@ -use wasm_bindgen::prelude::*; +use wasm_bindgen::prelude::{wasm_bindgen, JsError}; +use xmtp_api_grpc_gateway::XmtpGrpcGatewayClient; #[wasm_bindgen] pub struct WasmXmtpClient { - // TODO + api: XmtpGrpcGatewayClient, + // inbox_owner: WasmInboxOwner, +} + +impl WasmXmtpClient { + pub fn api(&self) -> &XmtpGrpcGatewayClient { + &self.api + } } #[wasm_bindgen] impl WasmXmtpClient { #[wasm_bindgen(constructor)] - pub fn new() -> Result { + pub fn new(url: String) -> Result { // TODO - Ok(WasmXmtpClient {}) + Ok(WasmXmtpClient { + api: XmtpGrpcGatewayClient::new(url), + }) } } diff --git a/bindings_wasm/tests/web.rs b/bindings_wasm/tests/web.rs index 60dca6d62..0093c2696 100644 --- a/bindings_wasm/tests/web.rs +++ b/bindings_wasm/tests/web.rs @@ -2,6 +2,7 @@ extern crate bindings_wasm; extern crate wasm_bindgen_test; use bindings_wasm::*; use prost::Message; +use wasm_bindgen::prelude::*; use wasm_bindgen_test::*; use xmtp_cryptography::signature::RecoverableSignature; use xmtp_proto::xmtp::message_api::v1::Envelope; @@ -9,11 +10,22 @@ use xmtp_proto::xmtp::message_api::v1::Envelope; // Only run these tests in a browser. wasm_bindgen_test_configure!(run_in_browser); +#[wasm_bindgen] +extern "C" { + // Use `js_namespace` here to bind `console.log(..)` instead of just + // `log(..)` + #[wasm_bindgen(js_namespace = console)] + fn log(s: &str); +} + #[wasm_bindgen_test] pub fn test_client_construction() { - let client = WasmXmtpClient::new(); + let xmtp_url: String = "http://localhost:5555".to_string(); + let client = WasmXmtpClient::new(xmtp_url).unwrap_or_else(|_error| { + panic!("client should be constructed"); + }); // TODO: assert things about the client once it does anything. - assert!(matches!(client, Ok(_))); + client.api(); } #[wasm_bindgen_test] diff --git a/examples/cli/Cargo.toml b/examples/cli/Cargo.toml index f86987cf3..2242528eb 100644 --- a/examples/cli/Cargo.toml +++ b/examples/cli/Cargo.toml @@ -21,6 +21,7 @@ url = "2.3.1" walletconnect = {git="https://github.com/nlordell/walletconnect-rs.git", features=["qr", "transport"]} xmtp = { path = "../../xmtp", features = ["grpc", "native"] } xmtp_cryptography = { path = "../../xmtp_cryptography"} -xmtp_networking = { path = "../../xmtp_networking"} +xmtp_api_grpc = { path = "../../xmtp_api_grpc" } +xmtp_proto = { path = "../../xmtp_proto", features = ["proto_full", "grpc"] } timeago = "0.4.1" diff --git a/examples/cli/cli-client.rs b/examples/cli/cli-client.rs index 6eaa2e210..162ad8718 100644 --- a/examples/cli/cli-client.rs +++ b/examples/cli/cli-client.rs @@ -23,11 +23,11 @@ use xmtp::conversations::Conversations; use xmtp::storage::{ now, EncryptedMessageStore, EncryptionKey, MessageState, StorageError, StorageOption, }; -use xmtp::types::networking::XmtpApiClient; use xmtp::InboxOwner; +use xmtp_api_grpc::grpc_api_helper::Client as ApiClient; use xmtp_cryptography::signature::{h160addr_to_string, RecoverableSignature, SignatureError}; use xmtp_cryptography::utils::{rng, seeded_rng, LocalWallet}; -use xmtp_networking::grpc_api_helper::Client as ApiClient; +use xmtp_proto::api_client::XmtpApiClient; type Client = xmtp::client::Client; type ClientBuilder = xmtp::builder::ClientBuilder; diff --git a/xmtp/src/builder.rs b/xmtp/src/builder.rs index 6ddeb7080..817fa548e 100644 --- a/xmtp/src/builder.rs +++ b/xmtp/src/builder.rs @@ -3,13 +3,13 @@ use crate::{ association::{Association, AssociationError, AssociationText}, client::{Client, Network}, storage::{now, EncryptedMessageStore, StoredUser}, - types::networking::XmtpApiClient, types::Address, InboxOwner, Store, }; use crate::{Fetch, StorageError}; use log::info; use thiserror::Error; +use xmtp_proto::api_client::XmtpApiClient; #[derive(Error, Debug)] pub enum ClientBuilderError { diff --git a/xmtp/src/client.rs b/xmtp/src/client.rs index 2fead991f..43935d066 100644 --- a/xmtp/src/client.rs +++ b/xmtp/src/client.rs @@ -15,13 +15,13 @@ use crate::{ now, DbConnection, EncryptedMessageStore, StorageError, StoredInstallation, StoredSession, StoredUser, }, - types::networking::{PublishRequest, QueryRequest, XmtpApiClient}, types::Address, utils::{build_envelope, build_user_contact_topic, key_fingerprint}, Store, }; use std::collections::HashMap; -use xmtp_proto::xmtp::message_api::v1::Envelope; +use xmtp_proto::api_client::XmtpApiClient; +use xmtp_proto::xmtp::message_api::v1::{Envelope, PublishRequest, QueryRequest}; const INSTALLATION_REFRESH_INTERVAL_NS: i64 = 0; @@ -44,7 +44,7 @@ pub enum ClientError { #[error("dieselError: {0}")] Ddd(#[from] diesel::result::Error), #[error("Query failed: {0}")] - QueryError(#[from] crate::types::networking::Error), + QueryError(#[from] xmtp_proto::api_client::Error), #[error("generic:{0}")] Generic(String), } diff --git a/xmtp/src/conversation.rs b/xmtp/src/conversation.rs index 9bdc8cc3c..e37b43d8f 100644 --- a/xmtp/src/conversation.rs +++ b/xmtp/src/conversation.rs @@ -8,10 +8,11 @@ use crate::{ now, DbConnection, MessageState, NewStoredMessage, StorageError, StoredConversation, StoredMessage, StoredUser, }, - types::networking::XmtpApiClient, types::Address, Client, Store, }; +use xmtp_proto::api_client::XmtpApiClient; +use xmtp_proto::xmtp::message_api::v1::PublishRequest; use prost::{DecodeError, Message}; // use async_trait::async_trait; @@ -36,7 +37,7 @@ pub enum ConversationError { #[error("Session: {0}")] Session(#[from] SessionError), #[error("Network error: {0}")] - Networking(#[from] crate::types::networking::Error), + Networking(#[from] xmtp_proto::api_client::Error), #[error("Payload:{0}")] Payload(#[from] PayloadError), #[error("error:{0}")] diff --git a/xmtp/src/conversations.rs b/xmtp/src/conversations.rs index 20e625b06..b739396f7 100644 --- a/xmtp/src/conversations.rs +++ b/xmtp/src/conversations.rs @@ -5,6 +5,7 @@ use futures::executor::block_on; use log::info; use prost::Message; use vodozemac::olm::{self, OlmMessage}; +use xmtp_proto::api_client::XmtpApiClient; use xmtp_proto::xmtp::{ message_api::v1::{Envelope, PublishRequest}, v3::message_contents::{ @@ -22,7 +23,6 @@ use crate::{ OutboundPayloadState, RefreshJob, RefreshJobKind, StorageError, StoredConversation, StoredMessage, StoredOutboundPayload, StoredSession, }, - types::networking::XmtpApiClient, utils::{base64_encode, build_installation_message_topic}, Client, }; @@ -397,6 +397,7 @@ impl Conversations { #[cfg(test)] mod tests { use prost::Message; + use xmtp_proto::api_client::XmtpApiClient; use xmtp_proto::xmtp::message_api::v1::QueryRequest; use crate::{ @@ -405,7 +406,6 @@ mod tests { conversations::Conversations, storage::{now, MessageState, StoredMessage}, test_utils::test_utils::{gen_test_client, gen_test_conversation, gen_two_test_clients}, - types::networking::XmtpApiClient, utils::build_installation_message_topic, }; diff --git a/xmtp/src/lib.rs b/xmtp/src/lib.rs index ce3e86fdf..aca727d50 100644 --- a/xmtp/src/lib.rs +++ b/xmtp/src/lib.rs @@ -60,13 +60,11 @@ pub trait InboxOwner { #[cfg(test)] mod tests { - use crate::{ - builder::ClientBuilder, - types::networking::{PublishRequest, QueryRequest, XmtpApiClient}, - }; + use crate::builder::ClientBuilder; use std::time::{SystemTime, UNIX_EPOCH}; use uuid::Uuid; - use xmtp_proto::xmtp::message_api::v1::Envelope; + use xmtp_proto::api_client::XmtpApiClient; + use xmtp_proto::xmtp::message_api::v1::{Envelope, PublishRequest, QueryRequest}; fn gen_test_envelope(topic: String) -> Envelope { let time_since_epoch = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); diff --git a/xmtp/src/mock_xmtp_api_client.rs b/xmtp/src/mock_xmtp_api_client.rs index 4470073f8..ab6ce71c0 100644 --- a/xmtp/src/mock_xmtp_api_client.rs +++ b/xmtp/src/mock_xmtp_api_client.rs @@ -1,9 +1,9 @@ -use crate::types::networking::*; use async_trait::async_trait; use std::{ collections::HashMap, sync::{Arc, Mutex}, }; +use xmtp_proto::api_client::*; pub struct MockXmtpApiSubscription {} @@ -53,7 +53,8 @@ impl Clone for MockXmtpApiClient { } } -#[async_trait] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] impl XmtpApiClient for MockXmtpApiClient { type Subscription = MockXmtpApiSubscription; @@ -96,4 +97,8 @@ impl XmtpApiClient for MockXmtpApiClient { async fn subscribe(&self, _request: SubscribeRequest) -> Result { Err(Error::new(ErrorKind::SubscribeError)) } + + async fn batch_query(&self, request: BatchQueryRequest) -> Result { + Err(Error::new(ErrorKind::BatchQueryError)) + } } diff --git a/xmtp/src/test_utils.rs b/xmtp/src/test_utils.rs index 519df5088..37daf313c 100644 --- a/xmtp/src/test_utils.rs +++ b/xmtp/src/test_utils.rs @@ -1,9 +1,10 @@ #[cfg(test)] pub mod test_utils { use crate::{ - conversation::SecretConversation, mock_xmtp_api_client::MockXmtpApiClient, - types::networking::XmtpApiClient, Client, ClientBuilder, + conversation::SecretConversation, mock_xmtp_api_client::MockXmtpApiClient, Client, + ClientBuilder, }; + use xmtp_proto::api_client::XmtpApiClient; async fn gen_test_client_internal(api_client: MockXmtpApiClient) -> Client { let mut client = ClientBuilder::new_test() diff --git a/xmtp/src/types.rs b/xmtp/src/types.rs index e1303acf2..0a73a89b1 100644 --- a/xmtp/src/types.rs +++ b/xmtp/src/types.rs @@ -1,99 +1,2 @@ pub type Address = String; pub type InstallationId = String; - -pub mod networking { - use async_trait::async_trait; - use std::{error::Error as StdError, fmt}; - - pub use xmtp_proto::xmtp::message_api::v1::{ - Envelope, PagingInfo, PublishRequest, PublishResponse, QueryRequest, QueryResponse, - SubscribeRequest, - }; - - #[derive(Debug)] - pub enum ErrorKind { - SetupError, - PublishError, - QueryError, - SubscribeError, - } - - type ErrorSource = Box; - - pub struct Error { - kind: ErrorKind, - source: Option, - } - - impl Error { - pub fn new(kind: ErrorKind) -> Self { - Self { kind, source: None } - } - - pub fn with(mut self, source: impl Into) -> Self { - self.source = Some(source.into()); - self - } - } - - impl fmt::Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut f = f.debug_tuple("xmtp::error::Error"); - - f.field(&self.kind); - - if let Some(source) = &self.source { - f.field(source); - } - - f.finish() - } - } - - impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(match &self.kind { - ErrorKind::SetupError => "setup error", - ErrorKind::PublishError => "publish error", - ErrorKind::QueryError => "query error", - ErrorKind::SubscribeError => "subscribe error", - })?; - if self.source().is_some() { - f.write_str(": ")?; - f.write_str(&self.source().unwrap().to_string())?; - } - Ok(()) - } - } - - impl StdError for Error { - fn source(&self) -> Option<&(dyn StdError + 'static)> { - self.source - .as_ref() - .map(|source| &**source as &(dyn StdError + 'static)) - } - } - - pub trait XmtpApiSubscription { - fn is_closed(&self) -> bool; - fn get_messages(&self) -> Vec; - fn close_stream(&mut self); - } - - #[async_trait] - pub trait XmtpApiClient { - type Subscription: XmtpApiSubscription; - - fn set_app_version(&mut self, version: String); - - async fn publish( - &self, - token: String, - request: PublishRequest, - ) -> Result; - - async fn query(&self, request: QueryRequest) -> Result; - - async fn subscribe(&self, request: SubscribeRequest) -> Result; - } -} diff --git a/xmtp_networking/Cargo.toml b/xmtp_api_grpc/Cargo.toml similarity index 93% rename from xmtp_networking/Cargo.toml rename to xmtp_api_grpc/Cargo.toml index 8bee20f21..c96c41b77 100644 --- a/xmtp_networking/Cargo.toml +++ b/xmtp_api_grpc/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "xmtp_networking" +name = "xmtp_api_grpc" version = "0.1.0" edition = "2021" @@ -7,7 +7,6 @@ edition = "2021" [dependencies] tonic = "^0.9" -xmtp = { path = "../xmtp" } xmtp_proto = { path = "../xmtp_proto", features = ["proto_full", "grpc"] } prost = { version = "^0.11", features = ["prost-derive"] } tokio = { version = "1.24", features = ["macros", "rt-multi-thread", "time"] } diff --git a/xmtp_networking/src/grpc_api_helper.rs b/xmtp_api_grpc/src/grpc_api_helper.rs similarity index 97% rename from xmtp_networking/src/grpc_api_helper.rs rename to xmtp_api_grpc/src/grpc_api_helper.rs index c4996df04..dcc9a95ce 100644 --- a/xmtp_networking/src/grpc_api_helper.rs +++ b/xmtp_api_grpc/src/grpc_api_helper.rs @@ -9,7 +9,7 @@ use tokio_rustls::rustls::{ClientConfig, OwnedTrustAnchor, RootCertStore}; use tonic::async_trait; use tonic::Status; use tonic::{metadata::MetadataValue, transport::Channel, Request, Streaming}; -use xmtp::types::networking::{Error, ErrorKind, XmtpApiClient, XmtpApiSubscription}; +use xmtp_proto::api_client::{Error, ErrorKind, XmtpApiClient, XmtpApiSubscription}; use xmtp_proto::xmtp::message_api::v1::{ message_api_client::MessageApiClient, BatchQueryRequest, BatchQueryResponse, Envelope, PublishRequest, PublishResponse, QueryRequest, QueryResponse, SubscribeRequest, @@ -182,13 +182,8 @@ impl XmtpApiClient for Client { Err(e) => Err(Error::new(ErrorKind::QueryError).with(e)), } } -} -impl Client { - pub async fn batch_query( - &self, - request: BatchQueryRequest, - ) -> Result { + async fn batch_query(&self, request: BatchQueryRequest) -> Result { let mut tonic_request = Request::new(request); tonic_request .metadata_mut() diff --git a/xmtp_networking/src/lib.rs b/xmtp_api_grpc/src/lib.rs similarity index 97% rename from xmtp_networking/src/lib.rs rename to xmtp_api_grpc/src/lib.rs index bf101d95d..1ae3b43d2 100644 --- a/xmtp_networking/src/lib.rs +++ b/xmtp_api_grpc/src/lib.rs @@ -10,8 +10,7 @@ mod tests { use std::time::{SystemTime, UNIX_EPOCH}; use super::*; - use xmtp::types::networking::XmtpApiClient; - use xmtp::types::networking::XmtpApiSubscription; + use xmtp_proto::api_client::{XmtpApiClient, XmtpApiSubscription}; use xmtp_proto::xmtp::message_api::v1::{ BatchQueryRequest, Envelope, PublishRequest, QueryRequest, SubscribeRequest, }; diff --git a/xmtp_api_grpc_gateway/Cargo.lock b/xmtp_api_grpc_gateway/Cargo.lock new file mode 100644 index 000000000..0ad29120b --- /dev/null +++ b/xmtp_api_grpc_gateway/Cargo.lock @@ -0,0 +1,1366 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "async-trait" +version = "0.1.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.31", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.9", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "linux-raw-sys" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl" +version = "0.10.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +dependencies = [ + "bitflags 2.4.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.31", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "pbjson" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048f9ac93c1eab514f9470c4bc8d97ca2a0a236b84f45cc19d69a59fc11467f6" +dependencies = [ + "base64 0.13.1", + "serde", +] + +[[package]] +name = "pbjson-build" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdbb7b706f2afc610f3853550cdbbf6372fd324824a087806bd4480ea4996e24" +dependencies = [ + "heck", + "itertools", + "prost", + "prost-types", +] + +[[package]] +name = "pbjson-types" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a88c8d87f99a4ac14325e7a4c24af190fca261956e3b82dd7ed67e77e6c7043" +dependencies = [ + "bytes", + "chrono", + "pbjson", + "pbjson-build", + "prost", + "prost-build", + "serde", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.0.0", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "reqwest" +version = "0.11.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +dependencies = [ + "base64 0.21.3", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.31", +] + +[[package]] +name = "serde_json" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2 0.5.3", + "windows-sys", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.31", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.31", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys", +] + +[[package]] +name = "xmtp_api_grpc_gateway" +version = "0.1.0" +dependencies = [ + "async-trait", + "prost", + "prost-types", + "reqwest", + "wasm-bindgen-test", + "xmtp_proto", +] + +[[package]] +name = "xmtp_proto" +version = "0.1.0" +dependencies = [ + "async-trait", + "pbjson", + "pbjson-types", + "prost", + "prost-types", + "serde", +] diff --git a/xmtp_api_grpc_gateway/Cargo.toml b/xmtp_api_grpc_gateway/Cargo.toml new file mode 100644 index 000000000..4288c561c --- /dev/null +++ b/xmtp_api_grpc_gateway/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "xmtp_api_grpc_gateway" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +async-trait = "0.1.68" +prost = { version = "0.11", features = ["prost-derive"] } +prost-types = "0.11" +reqwest = { version = "0.11.20", features = ["json"] } +wasm-bindgen = "0.2.87" +wasm-bindgen-futures = "0.4.37" +xmtp_cryptography = { path = "../xmtp_cryptography" } +xmtp_proto = { path = "../xmtp_proto", features = ["proto_full"] } + +[dev-dependencies] +uuid = { version = "1.3.1", features = ["v4"] } +wasm-bindgen-test = "0.3.34" diff --git a/xmtp_api_grpc_gateway/README.md b/xmtp_api_grpc_gateway/README.md new file mode 100644 index 000000000..9aa73d207 --- /dev/null +++ b/xmtp_api_grpc_gateway/README.md @@ -0,0 +1,8 @@ +# XMTP Api Client using GRPC Gateway + +# WARNING: DO NOT USE FOR PRODUCTION XMTP CLIENTS + +This code is still under development. + +- `$ cd xmtp_api_grpc_gateway` +- `$ wasm-pack test --headless --chrome` diff --git a/xmtp_api_grpc_gateway/src/lib.rs b/xmtp_api_grpc_gateway/src/lib.rs new file mode 100644 index 000000000..9b526a4d4 --- /dev/null +++ b/xmtp_api_grpc_gateway/src/lib.rs @@ -0,0 +1,102 @@ +use async_trait::async_trait; +use xmtp_proto::api_client::{Error, ErrorKind, XmtpApiClient, XmtpApiSubscription}; +use xmtp_proto::xmtp::message_api::v1::{ + BatchQueryRequest, BatchQueryResponse, Envelope, PublishRequest, PublishResponse, QueryRequest, + QueryResponse, SubscribeRequest, +}; + +// TODO: consider moving these (and other address const) into `xmtp_proto` +pub const LOCALHOST_ADDRESS: &str = "http://localhost:5555"; +pub const DEV_ADDRESS: &str = "https://dev.xmtp.network:5555"; + +pub struct XmtpGrpcGatewayClient { + url: String, + http: reqwest::Client, +} + +impl XmtpGrpcGatewayClient { + pub fn new(url: String) -> Self { + XmtpGrpcGatewayClient { + url, + http: reqwest::Client::new(), + } + } +} + +#[async_trait(?Send)] +impl XmtpApiClient for XmtpGrpcGatewayClient { + type Subscription = XmtpGrpcGatewaySubscription; + + fn set_app_version(&mut self, _version: String) { + // TODO + } + + async fn publish( + &self, + token: String, + request: PublishRequest, + ) -> Result { + let res: PublishResponse = self + .http + .post(&format!("{}/message/v1/publish", self.url)) + .bearer_auth(token) + .json(&request) + .send() + .await + .map_err(|e| Error::new(ErrorKind::PublishError).with(e))? + .json() + .await + .map_err(|e| Error::new(ErrorKind::PublishError).with(e))?; + Ok(res) + } + + async fn subscribe( + &self, + _request: SubscribeRequest, + ) -> Result { + // TODO + Err(Error::new(ErrorKind::SubscribeError)) + } + + async fn query(&self, request: QueryRequest) -> Result { + let res: QueryResponse = self + .http + .post(&format!("{}/message/v1/query", self.url)) + .json(&request) + .send() + .await + .map_err(|e| Error::new(ErrorKind::QueryError).with(e))? + .json() + .await + .map_err(|e| Error::new(ErrorKind::QueryError).with(e))?; + Ok(res) + } + + async fn batch_query(&self, request: BatchQueryRequest) -> Result { + let res: BatchQueryResponse = self + .http + .post(&format!("{}/message/v1/batch-query", self.url)) + .json(&request) + .send() + .await + .map_err(|e| Error::new(ErrorKind::BatchQueryError).with(e))? + .json() + .await + .map_err(|e| Error::new(ErrorKind::BatchQueryError).with(e))?; + Ok(res) + } +} + +// TODO: implement JSON segmented streaming +pub struct XmtpGrpcGatewaySubscription {} +impl XmtpApiSubscription for XmtpGrpcGatewaySubscription { + fn is_closed(&self) -> bool { + true + } + + fn get_messages(&self) -> Vec { + vec![] + } + + fn close_stream(&mut self) {} +} diff --git a/xmtp_api_grpc_gateway/tests/wasm_test.rs b/xmtp_api_grpc_gateway/tests/wasm_test.rs new file mode 100644 index 000000000..6c86889f7 --- /dev/null +++ b/xmtp_api_grpc_gateway/tests/wasm_test.rs @@ -0,0 +1,120 @@ +use wasm_bindgen_test::*; +use xmtp_api_grpc_gateway::XmtpGrpcGatewayClient; +use xmtp_proto::api_client::XmtpApiClient; +use xmtp_proto::xmtp::message_api::v1::{ + BatchQueryRequest, Envelope, PublishRequest, QueryRequest, +}; + +// Only run these tests in a browser. +wasm_bindgen_test_configure!(run_in_browser); + +#[wasm_bindgen_test] +pub async fn test_query_publish_query() { + let xmtp_url: String = "http://localhost:5555".to_string(); + let topic = uuid::Uuid::new_v4(); + let auth_token = ""; // TODO + + let api = XmtpGrpcGatewayClient::new(xmtp_url); + let q = QueryRequest { + content_topics: vec![topic.to_string()], + ..QueryRequest::default() + }; + + // At first there's nothing there. + let res = api.query(q.clone()).await.expect("successfully queried"); + assert_eq!(0, res.envelopes.len()); + + // But after we publish something... + api.publish( + auth_token.to_string(), + PublishRequest { + envelopes: vec![Envelope { + content_topic: topic.to_string(), + message: vec![1, 2, 3, 4], + timestamp_ns: 1234, + }], + }, + ) + .await + .expect("published"); + + // ... then we should see it in the query. + let res = api.query(q.clone()).await.expect("successfully queried"); + assert_eq!(1, res.envelopes.len()); + assert_eq!(topic.to_string(), res.envelopes[0].content_topic); + assert_eq!(1234, res.envelopes[0].timestamp_ns); + assert_eq!(vec![1, 2, 3, 4], res.envelopes[0].message); +} + +#[wasm_bindgen_test] +pub async fn test_batch_query_publish_batch_query() { + let xmtp_url: String = "http://localhost:5555".to_string(); + let api = XmtpGrpcGatewayClient::new(xmtp_url); + let topic1 = uuid::Uuid::new_v4(); + let topic2 = uuid::Uuid::new_v4(); + let auth_token = ""; // TODO + + // First we issue this batch query and get no results. + let batch_q = BatchQueryRequest { + requests: vec![ + QueryRequest { + content_topics: vec![topic1.to_string()], + ..QueryRequest::default() + }, + QueryRequest { + content_topics: vec![topic2.to_string()], + ..QueryRequest::default() + }, + ], + }; + let res = api + .batch_query(batch_q.clone()) + .await + .expect("successfully batch queried"); + assert_eq!(2, res.responses.len()); + assert_eq!(0, res.responses[0].envelopes.len()); + assert_eq!(0, res.responses[1].envelopes.len()); + + // Now we publish to both of the topics... + api.publish( + auth_token.to_string(), + PublishRequest { + envelopes: vec![ + Envelope { + content_topic: topic1.to_string(), + message: vec![1, 1, 1, 1], + timestamp_ns: 1111, + }, + Envelope { + content_topic: topic2.to_string(), + message: vec![2, 2, 2, 2], + timestamp_ns: 2222, + }, + ], + }, + ) + .await + .expect("published to both of them"); + + // ... so when we batch query again we should see the results. + let res = api + .batch_query(batch_q.clone()) + .await + .expect("successfully batch queried again"); + assert_eq!(2, res.responses.len()); + assert_eq!(1, res.responses[0].envelopes.len()); + assert_eq!(1, res.responses[1].envelopes.len()); + let e1: Envelope; + let e2: Envelope; + if res.responses[0].envelopes[0].content_topic == topic1.to_string() { + e1 = res.responses[0].envelopes[0].clone(); + e2 = res.responses[1].envelopes[0].clone(); + } else { + e1 = res.responses[1].envelopes[0].clone(); + e2 = res.responses[0].envelopes[0].clone(); + } + assert_eq!(1111, e1.timestamp_ns); + assert_eq!(2222, e2.timestamp_ns); + assert_eq!(vec![1, 1, 1, 1], e1.message); + assert_eq!(vec![2, 2, 2, 2], e2.message); +} diff --git a/xmtp_proto/Cargo.toml b/xmtp_proto/Cargo.toml index 42d23382b..6228b923c 100644 --- a/xmtp_proto/Cargo.toml +++ b/xmtp_proto/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-trait = "0.1.68" prost = { version = "0.11", features = ["prost-derive"] } # Only necessary if using Protobuf well-known types: prost-types = "0.11" diff --git a/xmtp_proto/src/api_client.rs b/xmtp_proto/src/api_client.rs new file mode 100644 index 000000000..b3805bfe3 --- /dev/null +++ b/xmtp_proto/src/api_client.rs @@ -0,0 +1,100 @@ +use async_trait::async_trait; +use std::{error::Error as StdError, fmt}; + +pub use super::xmtp::message_api::v1::{ + BatchQueryRequest, BatchQueryResponse, Envelope, PagingInfo, PublishRequest, PublishResponse, + QueryRequest, QueryResponse, SubscribeRequest, +}; + +#[derive(Debug)] +pub enum ErrorKind { + SetupError, + PublishError, + QueryError, + SubscribeError, + BatchQueryError, +} + +type ErrorSource = Box; + +pub struct Error { + kind: ErrorKind, + source: Option, +} + +impl Error { + pub fn new(kind: ErrorKind) -> Self { + Self { kind, source: None } + } + + pub fn with(mut self, source: impl Into) -> Self { + self.source = Some(source.into()); + self + } +} + +impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut f = f.debug_tuple("xmtp::error::Error"); + + f.field(&self.kind); + + if let Some(source) = &self.source { + f.field(source); + } + + f.finish() + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match &self.kind { + ErrorKind::SetupError => "setup error", + ErrorKind::PublishError => "publish error", + ErrorKind::QueryError => "query error", + ErrorKind::SubscribeError => "subscribe error", + ErrorKind::BatchQueryError => "batch query error", + })?; + if self.source().is_some() { + f.write_str(": ")?; + f.write_str(&self.source().unwrap().to_string())?; + } + Ok(()) + } +} + +impl StdError for Error { + fn source(&self) -> Option<&(dyn StdError + 'static)> { + self.source + .as_ref() + .map(|source| &**source as &(dyn StdError + 'static)) + } +} + +pub trait XmtpApiSubscription { + fn is_closed(&self) -> bool; + fn get_messages(&self) -> Vec; + fn close_stream(&mut self); +} + +// Wasm futures don't have `Send` or `Sync` bounds. +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait XmtpApiClient { + type Subscription: XmtpApiSubscription; + + fn set_app_version(&mut self, version: String); + + async fn publish( + &self, + token: String, + request: PublishRequest, + ) -> Result; + + async fn subscribe(&self, request: SubscribeRequest) -> Result; + + async fn query(&self, request: QueryRequest) -> Result; + + async fn batch_query(&self, request: BatchQueryRequest) -> Result; +} diff --git a/xmtp_proto/src/lib.rs b/xmtp_proto/src/lib.rs index 8ba6203d3..4bd33083f 100644 --- a/xmtp_proto/src/lib.rs +++ b/xmtp_proto/src/lib.rs @@ -1 +1,3 @@ include!("gen/mod.rs"); +#[cfg(feature = "xmtp-message_api-v1")] +pub mod api_client;