X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/2ecddba37509c1328980a2d59d1e96ca2cabab53..f9a36c6e0404d06bd396b24b5ea699e49ed29b89:/client/src/jsonrpc.rs diff --git a/client/src/jsonrpc.rs b/client/src/jsonrpc.rs index f91be25e..66ef9d9d 100644 --- a/client/src/jsonrpc.rs +++ b/client/src/jsonrpc.rs @@ -1,49 +1,102 @@ use std::path::Path; -use jsonrpc_client_transports::{transports::ipc, RpcError}; -use jsonrpc_core::serde::Deserialize; -use jsonrpc_derive::rpc; +use jsonrpsee::async_client::ClientBuilder; +use jsonrpsee::core::client::{Error, SubscriptionClientT}; +use jsonrpsee::http_client::HttpClientBuilder; +use jsonrpsee::proc_macros::rpc; +use serde::Deserialize; +use serde_json::Value; use tokio::net::ToSocketAddrs; -pub type SignalCliClient = gen_client::Client; - -#[rpc(client, params = "named")] +#[rpc(client)] pub trait Rpc { - #[rpc(name = "addDevice", params = "named")] - fn add_device(&self, account: Option, uri: String) -> Result; + #[method(name = "addDevice", param_kind = map)] + async fn add_device( + &self, + account: Option, + uri: String, + ) -> Result; - #[rpc(name = "block", params = "named")] + #[method(name = "addStickerPack", param_kind = map)] + async fn add_sticker_pack( + &self, + account: Option, + uri: String, + ) -> Result; + + #[method(name = "block", param_kind = map)] fn block( &self, account: Option, recipients: Vec, #[allow(non_snake_case)] groupIds: Vec, - ) -> Result; + ) -> Result; - #[rpc(name = "deleteLocalAccountData", params = "named")] + #[method(name = "deleteLocalAccountData", param_kind = map)] fn delete_local_account_data( &self, account: Option, #[allow(non_snake_case)] ignoreRegistered: Option, - ) -> Result; + ) -> Result; - #[rpc(name = "getUserStatus", params = "named")] - fn get_user_status(&self, account: Option, recipients: Vec) -> Result; + #[method(name = "getAttachment", param_kind = map)] + fn get_attachment( + &self, + account: Option, + id: String, + recipient: Option, + #[allow(non_snake_case)] groupId: Option, + ) -> Result; - #[rpc(name = "joinGroup", params = "named")] - fn join_group(&self, account: Option, uri: String) -> Result; + #[method(name = "getAvatar", param_kind = map)] + fn get_avatar( + &self, + account: Option, + contact: Option, + profile: Option, + #[allow(non_snake_case)] groupId: Option, + ) -> Result; - #[rpc(name = "finishLink", params = "named")] + #[method(name = "getSticker", param_kind = map)] + fn get_sticker( + &self, + account: Option, + #[allow(non_snake_case)] packId: String, + #[allow(non_snake_case)] stickerId: u32, + ) -> Result; + + #[method(name = "getUserStatus", param_kind = map)] + fn get_user_status( + &self, + account: Option, + recipients: Vec, + usernames: Vec, + ) -> Result; + + #[method(name = "joinGroup", param_kind = map)] + fn join_group(&self, account: Option, uri: String) -> Result; + + #[allow(non_snake_case)] + #[method(name = "finishChangeNumber", param_kind = map)] + fn finish_change_number( + &self, + account: Option, + number: String, + verificationCode: String, + pin: Option, + ) -> Result; + + #[method(name = "finishLink", param_kind = map)] fn finish_link( &self, #[allow(non_snake_case)] deviceLinkUri: String, #[allow(non_snake_case)] deviceName: String, - ) -> Result; + ) -> Result; - #[rpc(name = "listAccounts", params = "named")] - fn list_accounts(&self) -> Result; + #[method(name = "listAccounts", param_kind = map)] + fn list_accounts(&self) -> Result; - #[rpc(name = "listContacts", params = "named")] + #[method(name = "listContacts", param_kind = map)] fn list_contacts( &self, account: Option, @@ -51,60 +104,65 @@ pub trait Rpc { #[allow(non_snake_case)] allRecipients: bool, blocked: Option, name: Option, - ) -> Result; + ) -> Result; - #[rpc(name = "listDevices", params = "named")] - fn list_devices(&self, account: Option) -> Result; + #[method(name = "listDevices", param_kind = map)] + fn list_devices(&self, account: Option) -> Result; - #[rpc(name = "listGroups", params = "named")] + #[method(name = "listGroups", param_kind = map)] fn list_groups( &self, account: Option, #[allow(non_snake_case)] groupIds: Vec, - ) -> Result; + ) -> Result; - #[rpc(name = "listIdentities", params = "named")] - fn list_identities(&self, account: Option, number: Option) -> Result; + #[method(name = "listIdentities", param_kind = map)] + fn list_identities( + &self, + account: Option, + number: Option, + ) -> Result; - #[rpc(name = "listStickerPacks", params = "named")] - fn list_sticker_packs(&self, account: Option) -> Result; + #[method(name = "listStickerPacks", param_kind = map)] + fn list_sticker_packs(&self, account: Option) -> Result; - #[rpc(name = "quitGroup", params = "named")] + #[method(name = "quitGroup", param_kind = map)] fn quit_group( &self, account: Option, #[allow(non_snake_case)] groupId: String, delete: bool, admins: Vec, - ) -> Result; + ) -> Result; - #[rpc(name = "register", params = "named")] + #[method(name = "register", param_kind = map)] fn register( &self, account: Option, voice: bool, captcha: Option, - ) -> Result; + ) -> Result; - #[rpc(name = "removeContact", params = "named")] + #[method(name = "removeContact", param_kind = map)] fn remove_contact( &self, account: Option, recipient: String, forget: bool, - ) -> Result; + hide: bool, + ) -> Result; - #[rpc(name = "removeDevice", params = "named")] + #[method(name = "removeDevice", param_kind = map)] fn remove_device( &self, account: Option, #[allow(non_snake_case)] deviceId: u32, - ) -> Result; + ) -> Result; - #[rpc(name = "removePin", params = "named")] - fn remove_pin(&self, account: Option) -> Result; + #[method(name = "removePin", param_kind = map)] + fn remove_pin(&self, account: Option) -> Result; - #[rpc(name = "remoteDelete", params = "named")] + #[method(name = "remoteDelete", param_kind = map)] fn remote_delete( &self, account: Option, @@ -112,30 +170,51 @@ pub trait Rpc { recipients: Vec, #[allow(non_snake_case)] groupIds: Vec, #[allow(non_snake_case)] noteToSelf: bool, - ) -> Result; + ) -> Result; - #[rpc(name = "send", params = "named")] + #[allow(non_snake_case)] + #[method(name = "send", param_kind = map)] fn send( &self, account: Option, recipients: Vec, - #[allow(non_snake_case)] groupIds: Vec, - #[allow(non_snake_case)] noteToSelf: bool, - #[allow(non_snake_case)] endSession: bool, + groupIds: Vec, + noteToSelf: bool, + endSession: bool, message: String, attachments: Vec, + viewOnce: bool, mentions: Vec, - #[allow(non_snake_case)] quoteTimestamp: Option, - #[allow(non_snake_case)] quoteAuthor: Option, - #[allow(non_snake_case)] quoteMessage: Option, - #[allow(non_snake_case)] quoteMention: Vec, + textStyle: Vec, + quoteTimestamp: Option, + quoteAuthor: Option, + quoteMessage: Option, + quoteMention: Vec, + quoteTextStyle: Vec, + quoteAttachment: Vec, + previewUrl: Option, + previewTitle: Option, + previewDescription: Option, + previewImage: Option, sticker: Option, - ) -> Result; + storyTimestamp: Option, + storyAuthor: Option, + editTimestamp: Option, + ) -> Result; + + #[method(name = "sendContacts", param_kind = map)] + fn send_contacts(&self, account: Option) -> Result; - #[rpc(name = "sendContacts", params = "named")] - fn send_contacts(&self, account: Option) -> Result; + #[method(name = "sendPaymentNotification", param_kind = map)] + fn send_payment_notification( + &self, + account: Option, + recipient: String, + receipt: String, + note: String, + ) -> Result; - #[rpc(name = "sendReaction", params = "named")] + #[method(name = "sendReaction", param_kind = map)] fn send_reaction( &self, account: Option, @@ -146,94 +225,117 @@ pub trait Rpc { #[allow(non_snake_case)] targetAuthor: String, #[allow(non_snake_case)] targetTimestamp: u64, remove: bool, - ) -> Result; + story: bool, + ) -> Result; - #[rpc(name = "sendReceipt", params = "named")] + #[method(name = "sendReceipt", param_kind = map)] fn send_receipt( &self, account: Option, recipient: String, #[allow(non_snake_case)] targetTimestamps: Vec, r#type: String, - ) -> Result; + ) -> Result; - #[rpc(name = "sendSyncRequest", params = "named")] - fn send_sync_request(&self, account: Option) -> Result; + #[method(name = "sendSyncRequest", param_kind = map)] + fn send_sync_request(&self, account: Option) -> Result; - #[rpc(name = "sendTyping", params = "named")] + #[method(name = "sendTyping", param_kind = map)] fn send_typing( &self, account: Option, recipients: Vec, #[allow(non_snake_case)] groupIds: Vec, stop: bool, - ) -> Result; + ) -> Result; + + #[method(name = "sendMessageRequestResponse", param_kind = map)] + fn send_message_request_response( + &self, + account: Option, + recipients: Vec, + #[allow(non_snake_case)] groupIds: Vec, + r#type: String, + ) -> Result; - #[rpc(name = "setPin", params = "named")] - fn set_pin(&self, account: Option, pin: String) -> Result; + #[method(name = "setPin", param_kind = map)] + fn set_pin(&self, account: Option, pin: String) -> Result; - #[rpc(name = "submitRateLimitChallenge", params = "named")] + #[method(name = "submitRateLimitChallenge", param_kind = map)] fn submit_rate_limit_challenge( &self, account: Option, challenge: String, captcha: String, - ) -> Result; + ) -> Result; - #[rpc(name = "startLink", params = "named")] - fn start_link(&self, account: Option) -> Result; + #[method(name = "startChangeNumber", param_kind = map)] + fn start_change_number( + &self, + account: Option, + number: String, + voice: bool, + captcha: Option, + ) -> Result; + + #[method(name = "startLink", param_kind = map)] + fn start_link(&self, account: Option) -> Result; - #[rpc(name = "trust", params = "named")] + #[method(name = "trust", param_kind = map)] fn trust( &self, account: Option, recipient: String, #[allow(non_snake_case)] trustAllKnownKeys: bool, #[allow(non_snake_case)] verifiedSafetyNumber: Option, - ) -> Result; + ) -> Result; - #[rpc(name = "unblock", params = "named")] + #[method(name = "unblock", param_kind = map)] fn unblock( &self, account: Option, recipients: Vec, #[allow(non_snake_case)] groupIds: Vec, - ) -> Result; + ) -> Result; - #[rpc(name = "unregister", params = "named")] + #[method(name = "unregister", param_kind = map)] fn unregister( &self, account: Option, #[allow(non_snake_case)] deleteAccount: bool, - ) -> Result; + ) -> Result; - #[rpc(name = "updateAccount", params = "named")] + #[allow(non_snake_case)] + #[method(name = "updateAccount", param_kind = map)] fn update_account( &self, account: Option, - #[allow(non_snake_case)] deviceName: Option, - ) -> Result; + deviceName: Option, + unrestrictedUnidentifiedSender: Option, + discoverableByNumber: Option, + numberSharing: Option, + ) -> Result; - #[rpc(name = "updateConfiguration", params = "named")] + #[method(name = "updateConfiguration", param_kind = map)] fn update_configuration( &self, account: Option, - #[allow(non_snake_case)] readReceiptes: Option, + #[allow(non_snake_case)] readReceipts: Option, #[allow(non_snake_case)] unidentifiedDeliveryIndicators: Option, #[allow(non_snake_case)] typingIndicators: Option, #[allow(non_snake_case)] linkPreviews: Option, - ) -> Result; + ) -> Result; - #[rpc(name = "updateContact", params = "named")] + #[method(name = "updateContact", param_kind = map)] fn update_contact( &self, account: Option, recipient: String, name: Option, expiration: Option, - ) -> Result; + ) -> Result; - #[rpc(name = "updateGroup", params = "named")] + #[method(name = "updateGroup", param_kind = map)] fn update_group( &self, account: Option, @@ -253,9 +355,9 @@ pub trait Rpc { #[allow(non_snake_case)] setPermissionEditDetails: Option, #[allow(non_snake_case)] setPermissionSendMessages: Option, expiration: Option, - ) -> Result; + ) -> Result; - #[rpc(name = "updateProfile", params = "named")] + #[method(name = "updateProfile", param_kind = map)] fn update_profile( &self, account: Option, @@ -263,34 +365,36 @@ pub trait Rpc { #[allow(non_snake_case)] familyName: Option, about: Option, #[allow(non_snake_case)] aboutEmoji: Option, + #[allow(non_snake_case)] mobileCoinAddress: Option, avatar: Option, #[allow(non_snake_case)] removeAvatar: bool, - ) -> Result; + ) -> Result; - #[rpc(name = "uploadStickerPack", params = "named")] - fn upload_sticker_pack(&self, account: Option, path: String) -> Result; + #[method(name = "uploadStickerPack", param_kind = map)] + fn upload_sticker_pack( + &self, + account: Option, + path: String, + ) -> Result; - #[rpc(name = "verify", params = "named")] + #[method(name = "verify", param_kind = map)] fn verify( &self, account: Option, #[allow(non_snake_case)] verificationCode: String, pin: Option, - ) -> Result; + ) -> Result; - #[pubsub( - subscription = "receive", - subscribe, - name = "subscribeReceive", - params = "named" + #[subscription( + name = "subscribeReceive" => "receive", + unsubscribe = "unsubscribeReceive", + item = Value, + param_kind = map )] - fn subscribe_receive(&self, _: Self::Metadata, _: Subscriber, account: Option); - - #[pubsub(subscription = "receive", unsubscribe, name = "unsubscribeReceive")] - fn unsubscribe_receive(&self, _: Option, _: SubscriptionId) -> Result; + async fn subscribe_receive(&self, account: Option) -> SubscriptionResult; - #[rpc(name = "version")] - fn version(&self) -> Result; + #[method(name = "version")] + fn version(&self) -> Result; } #[derive(Deserialize)] @@ -299,10 +403,23 @@ pub struct JsonLink { pub device_link_uri: String, } -pub async fn connect_tcp(tcp: impl ToSocketAddrs) -> Result { - super::tcp::connect::<_, SignalCliClient>(tcp).await +pub async fn connect_tcp( + tcp: impl ToSocketAddrs, +) -> Result { + let (sender, receiver) = super::transports::tcp::connect(tcp).await?; + + Ok(ClientBuilder::default().build_with_tokio(sender, receiver)) +} + +#[cfg(unix)] +pub async fn connect_unix( + socket_path: impl AsRef, +) -> Result { + let (sender, receiver) = super::transports::ipc::connect(socket_path).await?; + + Ok(ClientBuilder::default().build_with_tokio(sender, receiver)) } -pub async fn connect_unix(socket_path: impl AsRef) -> Result { - ipc::connect::<_, SignalCliClient>(socket_path).await +pub async fn connect_http(uri: &str) -> Result, Error> { + HttpClientBuilder::default().build(uri) }