From d17f94bf46210517c7ee10a8b014d7ffe34f0020 Mon Sep 17 00:00:00 2001 From: Ivan Reshetnikov Date: Tue, 30 Jul 2024 16:55:26 +0200 Subject: [PATCH] feat: publish verify attestation (#82) --- examples/http_client.rs | 1 + examples/webhook.rs | 1 + examples/websocket_client.rs | 1 + relay_client/src/http.rs | 2 ++ relay_client/src/websocket.rs | 2 ++ relay_rpc/src/rpc.rs | 7 +++++++ relay_rpc/src/rpc/tests.rs | 14 +++++++++++--- relay_rpc/src/rpc/watch.rs | 5 ++++- 8 files changed, 29 insertions(+), 4 deletions(-) diff --git a/examples/http_client.rs b/examples/http_client.rs index 32e2743..e629543 100644 --- a/examples/http_client.rs +++ b/examples/http_client.rs @@ -52,6 +52,7 @@ async fn main() -> anyhow::Result<()> { .publish( topic.clone(), message.clone(), + None, 1100, Duration::from_secs(30), false, diff --git a/examples/webhook.rs b/examples/webhook.rs index eba14f5..6b18ea2 100644 --- a/examples/webhook.rs +++ b/examples/webhook.rs @@ -194,6 +194,7 @@ async fn main() -> anyhow::Result<()> { .publish( topic.clone(), message.clone(), + None, 1100, Duration::from_secs(30), false, diff --git a/examples/websocket_client.rs b/examples/websocket_client.rs index a49e88b..8003b6f 100644 --- a/examples/websocket_client.rs +++ b/examples/websocket_client.rs @@ -93,6 +93,7 @@ async fn main() -> anyhow::Result<()> { .publish( topic.clone(), Arc::from("Hello WalletConnect!"), + None, 0, Duration::from_secs(60), false, diff --git a/relay_client/src/http.rs b/relay_client/src/http.rs index b2466e2..475292e 100644 --- a/relay_client/src/http.rs +++ b/relay_client/src/http.rs @@ -105,6 +105,7 @@ impl Client { &self, topic: Topic, message: impl Into>, + attestation: impl Into>>, tag: u32, ttl: Duration, prompt: bool, @@ -120,6 +121,7 @@ impl Client { self.request(rpc::Publish { topic, message: message.into(), + attestation: attestation.into(), ttl_secs, tag, prompt, diff --git a/relay_client/src/websocket.rs b/relay_client/src/websocket.rs index 3a1fccc..29bb2f5 100644 --- a/relay_client/src/websocket.rs +++ b/relay_client/src/websocket.rs @@ -156,6 +156,7 @@ impl Client { &self, topic: Topic, message: impl Into>, + attestation: impl Into>>, tag: u32, ttl: Duration, prompt: bool, @@ -163,6 +164,7 @@ impl Client { let (request, response) = create_request(Publish { topic, message: message.into(), + attestation: attestation.into(), ttl_secs: ttl.as_secs() as u32, tag, prompt, diff --git a/relay_rpc/src/rpc.rs b/relay_rpc/src/rpc.rs index a50fc2a..751eaec 100644 --- a/relay_rpc/src/rpc.rs +++ b/relay_rpc/src/rpc.rs @@ -529,6 +529,9 @@ pub struct Publish { /// Message to publish. pub message: Arc, + #[serde(default, skip_serializing_if = "is_default")] + pub attestation: Option>, + /// Duration for which the message should be kept in the mailbox if it can't /// be delivered, in seconds. #[serde(rename = "ttl")] @@ -556,6 +559,7 @@ impl Publish { data: SubscriptionData { topic: self.topic.clone(), message: self.message.clone(), + attestation: self.attestation.clone(), published_at, tag: self.tag, }, @@ -728,6 +732,9 @@ pub struct SubscriptionData { /// The message for the subscription. pub message: Arc, + #[serde(default, skip_serializing_if = "is_default")] + pub attestation: Option>, + /// Message publish timestamp in UTC milliseconds. pub published_at: i64, diff --git a/relay_rpc/src/rpc/tests.rs b/relay_rpc/src/rpc/tests.rs index 85395b9..80da24d 100644 --- a/relay_rpc/src/rpc/tests.rs +++ b/relay_rpc/src/rpc/tests.rs @@ -7,6 +7,7 @@ fn request() { Params::Publish(Publish { topic: "topic".into(), message: "payload".into(), + attestation: Some(Arc::from("attestation_payload")), ttl_secs: 12, tag: 0, prompt: false, @@ -17,7 +18,7 @@ fn request() { assert_eq!( &serialized, - r#"{"id":1,"jsonrpc":"2.0","method":"irn_publish","params":{"topic":"topic","message":"payload","ttl":12,"tag":0}}"# + r#"{"id":1,"jsonrpc":"2.0","method":"irn_publish","params":{"topic":"topic","message":"payload","attestation":"attestation_payload","ttl":12,"tag":0}}"# ); let deserialized: Payload = serde_json::from_str(&serialized).unwrap(); @@ -91,6 +92,7 @@ fn subscription() { let data = SubscriptionData { topic: "test_topic".into(), message: "test_message".into(), + attestation: Some(Arc::from("test_attestation")), published_at: 123, tag: 1000, }; @@ -104,7 +106,7 @@ fn subscription() { assert_eq!( &serialized, - r#"{"id":1,"jsonrpc":"2.0","method":"irn_subscription","params":{"id":"test_id","data":{"topic":"test_topic","message":"test_message","publishedAt":123,"tag":1000}}}"# + r#"{"id":1,"jsonrpc":"2.0","method":"irn_subscription","params":{"id":"test_id","data":{"topic":"test_topic","message":"test_message","attestation":"test_attestation","publishedAt":123,"tag":1000}}}"# ); let deserialized: Payload = serde_json::from_str(&serialized).unwrap(); @@ -127,7 +129,6 @@ fn batch_receive() { )); let serialized = serde_json::to_string(&payload).unwrap(); - eprintln!("{serialized}"); assert_eq!( &serialized, @@ -289,6 +290,7 @@ fn validation() { params: Params::Publish(Publish { topic: topic.clone(), message: message.clone(), + attestation: None, ttl_secs: 0, tag: 0, prompt: false, @@ -303,6 +305,7 @@ fn validation() { params: Params::Publish(Publish { topic: topic.clone(), message: message.clone(), + attestation: None, ttl_secs: 0, tag: 0, prompt: false, @@ -317,6 +320,7 @@ fn validation() { params: Params::Publish(Publish { topic: topic.clone(), message: message.clone(), + attestation: None, ttl_secs: 0, tag: 0, prompt: false, @@ -331,6 +335,7 @@ fn validation() { params: Params::Publish(Publish { topic: Topic::from("invalid"), message: message.clone(), + attestation: None, ttl_secs: 0, tag: 0, prompt: false, @@ -407,6 +412,7 @@ fn validation() { data: SubscriptionData { topic: topic.clone(), message: message.clone(), + attestation: None, published_at: 123, tag: 1000, }, @@ -423,6 +429,7 @@ fn validation() { data: SubscriptionData { topic: topic.clone(), message: message.clone(), + attestation: None, published_at: 123, tag: 1000, }, @@ -439,6 +446,7 @@ fn validation() { data: SubscriptionData { topic: Topic::from("invalid"), message, + attestation: None, published_at: 123, tag: 1000, }, diff --git a/relay_rpc/src/rpc/watch.rs b/relay_rpc/src/rpc/watch.rs index 26686b3..1ced9d5 100644 --- a/relay_rpc/src/rpc/watch.rs +++ b/relay_rpc/src/rpc/watch.rs @@ -85,6 +85,8 @@ pub struct WatchEventPayload { pub topic: Topic, /// The published message. pub message: Arc, + /// The Verify attestation JWT. + pub attestation: Option>, /// Message publishing timestamp. pub published_at: i64, /// Message tag. @@ -224,6 +226,7 @@ mod test { status: WatchStatus::Accepted, topic, message: Arc::from("test message"), + attestation: Some(Arc::from("test attestation")), published_at: iat.timestamp(), tag: 1100, }, @@ -233,7 +236,7 @@ mod test { // lowercase. assert_eq!( serde_json::to_string(&claims).unwrap(), - r#"{"iss":"did:key:z6Mku3wsRZTAHjr6xrYWVUfyGeNSNz1GJRVfazp3N76AL9gE","aud":"wss://relay.walletconnect.com","sub":"https://example.com","iat":946684800,"exp":32503680000,"act":"irn_watchEvent","typ":"subscriber","whu":"https://example.com","evt":{"messageId":12345678,"status":"accepted","topic":"474e88153f4db893de42c35e1891dc0e37a02e11961385de0475460fb48b8639","message":"test message","publishedAt":946684800,"tag":1100}}"# + r#"{"iss":"did:key:z6Mku3wsRZTAHjr6xrYWVUfyGeNSNz1GJRVfazp3N76AL9gE","aud":"wss://relay.walletconnect.com","sub":"https://example.com","iat":946684800,"exp":32503680000,"act":"irn_watchEvent","typ":"subscriber","whu":"https://example.com","evt":{"messageId":12345678,"status":"accepted","topic":"474e88153f4db893de42c35e1891dc0e37a02e11961385de0475460fb48b8639","message":"test message","attestation":"test attestation","publishedAt":946684800,"tag":1100}}"# ); // Verify that the claims can be encoded and decoded correctly.