From a225fe6b06a56146fd107afaa6ef57216ea402ea Mon Sep 17 00:00:00 2001 From: "Julien \"uj\" Abadji" Date: Sat, 23 Nov 2024 15:21:45 +0100 Subject: [PATCH 01/10] Fix firehose example (#258) * add compat layer between two cid defs * point back to updated version of atrium-api --- examples/firehose/Cargo.toml | 8 ++++++-- examples/firehose/src/cid_compat.rs | 24 ++++++++++++++++++++++++ examples/firehose/src/lib.rs | 1 + examples/firehose/src/main.rs | 13 ++++++++----- 4 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 examples/firehose/src/cid_compat.rs diff --git a/examples/firehose/Cargo.toml b/examples/firehose/Cargo.toml index 70bab61d..b51f470f 100644 --- a/examples/firehose/Cargo.toml +++ b/examples/firehose/Cargo.toml @@ -7,12 +7,16 @@ edition = "2021" [dependencies] anyhow = "1.0.80" -atrium-api = { version = "0.18.1", features = ["dag-cbor"] } +atrium-api = { version = "0.24.8" } chrono = "0.4.34" +cid_old = { package = "cid", version = "0.10.1" } +cid = { package = "cid", version = "0.11.1" } futures = "0.3.30" ipld-core = { version = "0.4.0", default-features = false, features = ["std"] } rs-car = "0.4.1" -serde_ipld_dagcbor = { version = "0.6.0", default-features = false, features = ["std"] } +serde_ipld_dagcbor = { version = "0.6.0", default-features = false, features = [ + "std", +] } tokio = { version = "1.36.0", features = ["full"] } tokio-tungstenite = { version = "0.21.0", features = ["native-tls"] } trait-variant = "0.1.1" diff --git a/examples/firehose/src/cid_compat.rs b/examples/firehose/src/cid_compat.rs new file mode 100644 index 00000000..1e1be3f4 --- /dev/null +++ b/examples/firehose/src/cid_compat.rs @@ -0,0 +1,24 @@ +use cid::{multihash::Multihash, Cid}; + +pub struct CidOld(cid_old::Cid); + +impl From for CidOld { + fn from(value: cid_old::Cid) -> Self { + Self(value) + } +} +impl TryFrom for Cid { + type Error = cid::Error; + fn try_from(value: CidOld) -> Result { + let version = match value.0.version() { + cid_old::Version::V0 => cid::Version::V0, + cid_old::Version::V1 => cid::Version::V1, + }; + + let codec = value.0.codec(); + let hash = value.0.hash(); + let hash = Multihash::from_bytes(&hash.to_bytes())?; + + Self::new(version, codec, hash) + } +} diff --git a/examples/firehose/src/lib.rs b/examples/firehose/src/lib.rs index b4e04262..420c55d2 100644 --- a/examples/firehose/src/lib.rs +++ b/examples/firehose/src/lib.rs @@ -1,2 +1,3 @@ +pub mod cid_compat; pub mod stream; pub mod subscription; diff --git a/examples/firehose/src/main.rs b/examples/firehose/src/main.rs index e70a237e..558c8d34 100644 --- a/examples/firehose/src/main.rs +++ b/examples/firehose/src/main.rs @@ -3,6 +3,7 @@ use atrium_api::app::bsky::feed::post::Record; use atrium_api::com::atproto::sync::subscribe_repos::{Commit, NSID}; use atrium_api::types::{CidLink, Collection}; use chrono::Local; +use firehose::cid_compat::CidOld; use firehose::stream::frames::Frame; use firehose::subscription::{CommitHandler, Subscription}; use futures::StreamExt; @@ -54,7 +55,12 @@ impl CommitHandler for Firehose { continue; } let (items, _) = rs_car::car_read_all(&mut commit.blocks.as_slice(), true).await?; - if let Some((_, item)) = items.iter().find(|(cid, _)| Some(CidLink(*cid)) == op.cid) { + if let Some((_, item)) = items.iter().find(|(cid, _)| { + // + // convert cid from v0.10.1 to v0.11.1 + let cid = CidOld::from(*cid).try_into().expect("couldn't convert old to new cid"); + Some(CidLink(cid)) == op.cid + }) { let record = serde_ipld_dagcbor::from_reader::(&mut item.as_slice())?; println!( "{} - {}", @@ -78,8 +84,5 @@ impl CommitHandler for Firehose { #[tokio::main] async fn main() -> Result<(), Box> { - RepoSubscription::new("bsky.network") - .await? - .run(Firehose) - .await + RepoSubscription::new("bsky.network").await?.run(Firehose).await } From 8c9eee6714ebed3985b07e2c6542af9c6f4974e8 Mon Sep 17 00:00:00 2001 From: sugyan Date: Sat, 23 Nov 2024 23:30:27 +0900 Subject: [PATCH 02/10] chore: Fix examples --- examples/concurrent/Cargo.toml | 4 ++-- examples/concurrent/src/main.rs | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/examples/concurrent/Cargo.toml b/examples/concurrent/Cargo.toml index 2f60b216..6a00735f 100644 --- a/examples/concurrent/Cargo.toml +++ b/examples/concurrent/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -atrium-api = "0.18.1" -atrium-xrpc-client = "0.4.0" +atrium-api = "0.24.8" +atrium-xrpc-client = "0.5.10" clap = { version = "4.5.1", features = ["derive"] } futures = "0.3.30" tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] } diff --git a/examples/concurrent/src/main.rs b/examples/concurrent/src/main.rs index 21e2e05a..8340b842 100644 --- a/examples/concurrent/src/main.rs +++ b/examples/concurrent/src/main.rs @@ -36,9 +36,12 @@ async fn main() -> Result<(), Box> { .app .bsky .actor - .get_profile(atrium_api::app::bsky::actor::get_profile::Parameters { - actor: actor.parse().expect("invalid actor"), - }) + .get_profile( + atrium_api::app::bsky::actor::get_profile::ParametersData { + actor: actor.parse().expect("invalid actor"), + } + .into(), + ) .await }) }) @@ -46,7 +49,7 @@ async fn main() -> Result<(), Box> { let results = join_all(handles).await; println!("{} profiles fetched!", results.len()); for (actor, result) in actors.iter().zip(results) { - println!("{actor}: {:#?}", result?); + println!("{actor}: {:?}", result?); } Ok(()) } From 3d117f32c93fa7ca184af79408cd940fca5795c7 Mon Sep 17 00:00:00 2001 From: sugyan Date: Sat, 23 Nov 2024 23:56:41 +0900 Subject: [PATCH 03/10] chore: Add docs to API --- atrium-api/src/error.rs | 2 +- atrium-api/src/types.rs | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/atrium-api/src/error.rs b/atrium-api/src/error.rs index d20f4832..836c27cb 100644 --- a/atrium-api/src/error.rs +++ b/atrium-api/src/error.rs @@ -10,5 +10,5 @@ pub enum Error { NotAllowed, } -/// Type alias to use this library's [`Error`] type in a [`Result`](core::result::Result). +/// Type alias to use this library's [`Error`](enum@crate::error::Error) type in a [`Result`](core::result::Result). pub type Result = core::result::Result; diff --git a/atrium-api/src/types.rs b/atrium-api/src/types.rs index ffafcfc0..04741235 100644 --- a/atrium-api/src/types.rs +++ b/atrium-api/src/types.rs @@ -144,6 +144,27 @@ pub struct UnknownData { /// Corresponds to [the `unknown` field type]. /// /// [the `unknown` field type]: https://atproto.com/specs/lexicon#unknown +/// +/// By using the [`TryFromUnknown`] trait, it is possible to convert to any type +/// that implements [`DeserializeOwned`](serde::de::DeserializeOwned). +/// +/// ``` +/// use atrium_api::types::{TryFromUnknown, Unknown}; +/// +/// #[derive(Debug, serde::Deserialize)] +/// struct Foo { +/// bar: i32, +/// } +/// +/// # fn main() -> Result<(), Box> { +/// let value: Unknown = serde_json::from_str(r#"{"bar": 42}"#)?; +/// println!("{value:?}"); // Object({"bar": DataModel(42)}) +/// +/// let foo = Foo::try_from_unknown(value)?; +/// println!("{foo:?}"); // Foo { bar: 42 } +/// # Ok(()) +/// # } +/// ``` #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(untagged)] pub enum Unknown { From 119b2e161cce69de3bbab546950088828ee53570 Mon Sep 17 00:00:00 2001 From: Yoshihiro Sugi Date: Mon, 25 Nov 2024 22:45:46 +0900 Subject: [PATCH 04/10] feat: Add examples/video (#260) * Add examples/video * Add README --- Cargo.toml | 1 + examples/video/Cargo.toml | 12 ++ examples/video/README.md | 14 ++ examples/video/src/main.rs | 265 +++++++++++++++++++++++++++++++++++++ 4 files changed, 292 insertions(+) create mode 100644 examples/video/Cargo.toml create mode 100644 examples/video/README.md create mode 100644 examples/video/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 7623fe3c..795a6a8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = [ exclude = [ "examples/concurrent", "examples/firehose", + "examples/video", ] resolver = "2" diff --git a/examples/video/Cargo.toml b/examples/video/Cargo.toml new file mode 100644 index 00000000..3a6c6f89 --- /dev/null +++ b/examples/video/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "video" +version = "0.1.0" +edition = "2021" + +[dependencies] +atrium-api = { version = "0.24.8", features = ["agent"] } +atrium-xrpc-client.version = "0.5.10" +clap = { version = "4.5.21", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } +serde_html_form = { version = "0.2.6", default-features = false } +tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread"] } diff --git a/examples/video/README.md b/examples/video/README.md new file mode 100644 index 00000000..d18d4fd0 --- /dev/null +++ b/examples/video/README.md @@ -0,0 +1,14 @@ +## Example code for uploading a video + +1. First, get a token by `com.atproto.server.getServiceAuth`. + +2. Call uploadVideo against the video service (`video.bsky.app`) with the token. + +3. Call `app.bsky.video.getJobStatus` against the video service as well. + +(The same goes for `app.bsky.video.getUploadLimits`, which gets a token and calls the video service with it to get the data, but the process of checking this may be omitted.) + +In Atrium: + +- Since `AtpAgent` cannot process XRPC requests with the token obtained by `getServiceAuth`, we need to prepare a dedicated Client and create an `AtpServiceClient` that uses it. +- The `app.bsky.video.uploadVideo` endpoint is special (weird?) and requires special hacks such as adding query parameters to the request URL and modifying the response to match the schema. \ No newline at end of file diff --git a/examples/video/src/main.rs b/examples/video/src/main.rs new file mode 100644 index 00000000..36670876 --- /dev/null +++ b/examples/video/src/main.rs @@ -0,0 +1,265 @@ +use atrium_api::{ + agent::{store::MemorySessionStore, AtpAgent}, + client::AtpServiceClient, + types::{ + string::{Datetime, Did}, + Collection, TryIntoUnknown, Union, + }, + xrpc::{ + http::{uri::Builder, Request, Response}, + types::AuthorizationToken, + HttpClient, XrpcClient, + }, +}; +use atrium_xrpc_client::reqwest::ReqwestClient; +use clap::Parser; +use serde::Serialize; +use std::{fs::File, io::Read, path::PathBuf, time::Duration}; +use tokio::time; + +const VIDEO_SERVICE: &str = "https://video.bsky.app"; +const VIDEO_SERVICE_DID: &str = "did:web:video.bsky.app"; +const UPLOAD_VIDEO_PATH: &str = "/xrpc/app.bsky.video.uploadVideo"; + +/// Simple program to upload videos by ATrium API agent. +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Args { + /// Identifier of the login user. + #[arg(short, long)] + identifier: String, + /// App password of the login user. + #[arg(short, long)] + password: String, + /// Video file to upload. + #[arg(long, value_name = "VIDEO FILE")] + video: PathBuf, +} + +#[derive(Serialize)] +struct UploadParams { + did: Did, + name: String, +} + +struct VideoClient { + token: String, + params: Option, + inner: ReqwestClient, +} + +impl VideoClient { + fn new(token: String, params: Option) -> Self { + Self { + token, + params, + inner: ReqwestClient::new( + // Actually, `base_uri` returns `VIDEO_SERVICE`, so there is no need to specify this. + "https://dummy.example.com", + ), + } + } +} + +impl HttpClient for VideoClient { + async fn send_http( + &self, + mut request: Request>, + ) -> Result>, Box> { + let is_upload_video = request.uri().path() == UPLOAD_VIDEO_PATH; + // Hack: Append query parameters + if is_upload_video { + if let Some(params) = &self.params { + *request.uri_mut() = Builder::from(request.uri().clone()) + .path_and_query(format!( + "{UPLOAD_VIDEO_PATH}?{}", + serde_html_form::to_string(params)? + )) + .build()?; + } + } + let mut response = self.inner.send_http(request).await; + // Hack: Formatting an incorrect response body + if is_upload_video { + if let Ok(res) = response.as_mut() { + *res.body_mut() = + [b"{\"jobStatus\":".to_vec(), res.body().to_vec(), b"}".to_vec()].concat(); + } + } + response + } +} + +impl XrpcClient for VideoClient { + fn base_uri(&self) -> String { + VIDEO_SERVICE.to_string() + } + async fn authorization_token(&self, _: bool) -> Option { + Some(AuthorizationToken::Bearer(self.token.clone())) + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + let args = Args::parse(); + // Read video file + let data = { + let mut file = File::open(&args.video)?; + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + buf + }; + + // Login + println!("Logging in..."); + let agent = + AtpAgent::new(ReqwestClient::new("https://bsky.social"), MemorySessionStore::default()); + let session = agent.login(&args.identifier, &args.password).await?; + + // Check upload limits + println!("Checking upload limits..."); + let limits = { + let service_auth = agent + .api + .com + .atproto + .server + .get_service_auth( + atrium_api::com::atproto::server::get_service_auth::ParametersData { + aud: VIDEO_SERVICE_DID.parse().expect("invalid DID"), + exp: None, + lxm: atrium_api::app::bsky::video::get_upload_limits::NSID.parse().ok(), + } + .into(), + ) + .await?; + let client = AtpServiceClient::new(VideoClient::new(service_auth.data.token, None)); + client.service.app.bsky.video.get_upload_limits().await? + }; + println!("{:?}", limits.data); + if !limits.can_upload + || limits.remaining_daily_bytes.map_or(false, |remain| remain < data.len() as i64) + || limits.remaining_daily_videos.map_or(false, |remain| remain <= 0) + { + eprintln!("You cannot upload a video: {:?}", limits.data); + return Ok(()); + } + + // Upload video + println!("Uploading video..."); + let output = { + let service_auth = agent + .api + .com + .atproto + .server + .get_service_auth( + atrium_api::com::atproto::server::get_service_auth::ParametersData { + aud: format!( + "did:web:{}", + agent.get_endpoint().await.strip_prefix("https://").unwrap() + ) + .parse() + .expect("invalid DID"), + exp: None, + lxm: atrium_api::com::atproto::repo::upload_blob::NSID.parse().ok(), + } + .into(), + ) + .await?; + + let filename = args + .video + .file_name() + .and_then(|s| s.to_os_string().into_string().ok()) + .expect("failed to get filename"); + let client = AtpServiceClient::new(VideoClient::new( + service_auth.data.token, + Some(UploadParams { did: session.did.clone(), name: filename }), + )); + client.service.app.bsky.video.upload_video(data).await? + }; + println!("{:?}", output.job_status.data); + + // Wait for the video to be uploaded + let client = AtpServiceClient::new(ReqwestClient::new(VIDEO_SERVICE)); + let mut status = output.data.job_status.data; + loop { + status = client + .service + .app + .bsky + .video + .get_job_status( + atrium_api::app::bsky::video::get_job_status::ParametersData { + job_id: status.job_id.clone(), + } + .into(), + ) + .await? + .data + .job_status + .data; + println!("{status:?}"); + if status.blob.is_some() + || status.state == "JOB_STATE_CREATED" + || status.state == "JOB_STATE_FAILED" + { + break; + } + time::sleep(Duration::from_millis(100)).await; + } + let Some(video) = status.blob else { + eprintln!("Failed to get blob: {status:?}"); + return Ok(()); + }; + if let Some(message) = status.message { + println!("{message}"); + } + + // Post to feed with the video + println!("Video uploaded: {video:?}"); + let record = atrium_api::app::bsky::feed::post::RecordData { + created_at: Datetime::now(), + embed: Some(Union::Refs( + atrium_api::app::bsky::feed::post::RecordEmbedRefs::AppBskyEmbedVideoMain(Box::new( + atrium_api::app::bsky::embed::video::MainData { + alt: Some(String::from("alt text")), + aspect_ratio: None, + captions: None, + video, + } + .into(), + )), + )), + entities: None, + facets: None, + labels: None, + langs: None, + reply: None, + tags: None, + text: String::new(), + } + .try_into_unknown() + .expect("failed to convert record"); + let output = agent + .api + .com + .atproto + .repo + .create_record( + atrium_api::com::atproto::repo::create_record::InputData { + collection: atrium_api::app::bsky::feed::Post::nsid(), + record, + repo: session.data.did.into(), + rkey: None, + swap_commit: None, + validate: Some(true), + } + .into(), + ) + .await?; + println!("{:?}", output.data); + + Ok(()) +} From 276fceadac354fd2332411443d67cfff3b79f299 Mon Sep 17 00:00:00 2001 From: sugyan Date: Mon, 2 Dec 2024 23:12:24 +0900 Subject: [PATCH 05/10] chore: Fix example/video https://github.com/sugyan/atrium/pull/260#pullrequestreview-2471483825 --- examples/video/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/video/src/main.rs b/examples/video/src/main.rs index 36670876..edc782bb 100644 --- a/examples/video/src/main.rs +++ b/examples/video/src/main.rs @@ -202,7 +202,7 @@ async fn main() -> Result<(), Box> { .data; println!("{status:?}"); if status.blob.is_some() - || status.state == "JOB_STATE_CREATED" + || status.state == "JOB_STATE_COMPLETED" || status.state == "JOB_STATE_FAILED" { break; From 7a1c92d648f3df23c7a944605868afdc6e6bca4d Mon Sep 17 00:00:00 2001 From: sugyan Date: Mon, 2 Dec 2024 23:26:30 +0900 Subject: [PATCH 06/10] chore: Fix workflows --- .github/workflows/rust.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index cb388147..43ee76d1 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -41,7 +41,7 @@ jobs: - name: Compile (rust-analyzer) run: cargo build --verbose - + - name: Lint (clippy) uses: giraffate/clippy-action@v1 with: @@ -49,4 +49,5 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} - name: Format (rustfmt) + if: matrix.rust != 'stable' run: cargo fmt-no-gen --check From 4c7ebe74cf914c10b69b1de535883c068decbe03 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Tue, 10 Dec 2024 05:19:01 +0200 Subject: [PATCH 07/10] feat: Extend DidDocument with useful methods (#265) New methods: * get_feed_gen_endpoint * get_notif_endpoint * get_signing_key --- atrium-api/src/did_doc.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/atrium-api/src/did_doc.rs b/atrium-api/src/did_doc.rs index 23408add..4d7b72e3 100644 --- a/atrium-api/src/did_doc.rs +++ b/atrium-api/src/did_doc.rs @@ -39,6 +39,12 @@ impl DidDocument { pub fn get_pds_endpoint(&self) -> Option { self.get_service_endpoint("#atproto_pds", "AtprotoPersonalDataServer") } + pub fn get_feed_gen_endpoint(&self) -> Option { + self.get_service_endpoint("#bsky_fg", "BskyFeedGenerator") + } + pub fn get_notif_endpoint(&self) -> Option { + self.get_service_endpoint("#bsky_notif", "BskyNotificationService") + } fn get_service_endpoint(&self, id: &str, r#type: &str) -> Option { let full_id = self.id.to_string() + id; if let Some(services) = &self.service { @@ -62,4 +68,11 @@ impl DidDocument { }) .unwrap_or_default() } + pub fn get_signing_key(&self) -> Option<&VerificationMethod> { + self.verification_method.as_ref().and_then(|methods| { + methods.iter().find(|method| { + method.id == "#atproto" || method.id == format!("{}#atproto", self.id) + }) + }) + } } From 456feee4027290f4c8a33c6f28c2f0b6227b64b6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 03:19:37 +0000 Subject: [PATCH 08/10] chore: release --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- atrium-api/CHANGELOG.md | 10 ++++++++++ atrium-api/Cargo.toml | 2 +- bsky-sdk/CHANGELOG.md | 6 ++++++ bsky-sdk/Cargo.toml | 2 +- 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e901706..53bbe0e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,7 +178,7 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atrium-api" -version = "0.24.8" +version = "0.24.9" dependencies = [ "atrium-xrpc", "atrium-xrpc-client", @@ -384,7 +384,7 @@ dependencies = [ [[package]] name = "bsky-sdk" -version = "0.1.13" +version = "0.1.14" dependencies = [ "anyhow", "atrium-api", diff --git a/Cargo.toml b/Cargo.toml index 795a6a8d..01d8f5ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,12 +27,12 @@ keywords = ["atproto", "bluesky"] [workspace.dependencies] # Intra-workspace dependencies -atrium-api = { version = "0.24.8", path = "atrium-api", default-features = false } +atrium-api = { version = "0.24.9", path = "atrium-api", default-features = false } atrium-common = { version = "0.1.0", path = "atrium-common" } atrium-identity = { version = "0.1.0", path = "atrium-oauth/identity" } atrium-xrpc = { version = "0.12.0", path = "atrium-xrpc" } atrium-xrpc-client = { version = "0.5.10", path = "atrium-xrpc-client" } -bsky-sdk = { version = "0.1.13", path = "bsky-sdk" } +bsky-sdk = { version = "0.1.14", path = "bsky-sdk" } # DAG-CBOR codec ipld-core = { version = "0.4.1", default-features = false, features = ["std"] } diff --git a/atrium-api/CHANGELOG.md b/atrium-api/CHANGELOG.md index bd351d3d..c17c0175 100644 --- a/atrium-api/CHANGELOG.md +++ b/atrium-api/CHANGELOG.md @@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.24.9](https://github.com/sugyan/atrium/compare/atrium-api-v0.24.8...atrium-api-v0.24.9) - 2024-12-10 + +### Added + +- Extend DidDocument with useful methods (#265) + +### Other + +- Add docs to API + ## [0.24.8](https://github.com/sugyan/atrium/compare/atrium-api-v0.24.7...atrium-api-v0.24.8) - 2024-11-19 ### Added diff --git a/atrium-api/Cargo.toml b/atrium-api/Cargo.toml index 246e1690..3843907a 100644 --- a/atrium-api/Cargo.toml +++ b/atrium-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "atrium-api" -version = "0.24.8" +version = "0.24.9" authors = ["sugyan "] edition.workspace = true rust-version.workspace = true diff --git a/bsky-sdk/CHANGELOG.md b/bsky-sdk/CHANGELOG.md index 3fee463a..ac22a875 100644 --- a/bsky-sdk/CHANGELOG.md +++ b/bsky-sdk/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.1.14](https://github.com/sugyan/atrium/compare/bsky-sdk-v0.1.13...bsky-sdk-v0.1.14) - 2024-12-10 + +### Other + +- updated the following local packages: atrium-api + ## [0.1.13](https://github.com/sugyan/atrium/compare/bsky-sdk-v0.1.12...bsky-sdk-v0.1.13) - 2024-11-19 ### Other diff --git a/bsky-sdk/Cargo.toml b/bsky-sdk/Cargo.toml index 7f6fb63a..06226179 100644 --- a/bsky-sdk/Cargo.toml +++ b/bsky-sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bsky-sdk" -version = "0.1.13" +version = "0.1.14" authors = ["sugyan "] edition.workspace = true rust-version.workspace = true From a28705dba850400fab19bc6569aacdc43879cfd7 Mon Sep 17 00:00:00 2001 From: Mikoto <60188643+avdb13@users.noreply.github.com> Date: Wed, 18 Dec 2024 14:58:22 +0000 Subject: [PATCH 09/10] make `AtprotoClientMetadata`'s `client_uri` optional (#270) --- atrium-oauth/oauth-client/src/atproto.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/atrium-oauth/oauth-client/src/atproto.rs b/atrium-oauth/oauth-client/src/atproto.rs index ae23170f..c4f96661 100644 --- a/atrium-oauth/oauth-client/src/atproto.rs +++ b/atrium-oauth/oauth-client/src/atproto.rs @@ -108,7 +108,7 @@ pub struct AtprotoLocalhostClientMetadata { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct AtprotoClientMetadata { pub client_id: String, - pub client_uri: String, + pub client_uri: Option, pub redirect_uris: Vec, pub token_endpoint_auth_method: AuthMethod, pub grant_types: Vec, @@ -209,7 +209,7 @@ impl TryIntoOAuthClientMetadata for AtprotoClientMetadata { } Ok(OAuthClientMetadata { client_id: self.client_id, - client_uri: Some(self.client_uri), + client_uri: self.client_uri, redirect_uris: self.redirect_uris, token_endpoint_auth_method: Some(self.token_endpoint_auth_method.into()), grant_types: Some(self.grant_types.into_iter().map(|v| v.into()).collect()), @@ -331,7 +331,7 @@ gbGGr0pN+oSing7cZ0169JaRHTNh+0LNQXrFobInX6cj95FzEdRyT4T3 fn test_client_metadata() { let metadata = AtprotoClientMetadata { client_id: String::from("https://example.com/client_metadata.json"), - client_uri: String::from("https://example.com"), + client_uri: Some(String::from("https://example.com")), redirect_uris: vec![String::from("https://example.com/callback")], token_endpoint_auth_method: AuthMethod::PrivateKeyJwt, grant_types: vec![GrantType::AuthorizationCode], From 25a80829b8d1da50a8c943f92a701a722f837fc8 Mon Sep 17 00:00:00 2001 From: Erlend Sogge Heggen Date: Sat, 28 Dec 2024 15:16:44 +0100 Subject: [PATCH 10/10] Update README.md (#274) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0822a1f0..2591bbce 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,8 @@ Below are some related projects that might be of interest: - `atproto` https://github.com/bluesky-social/atproto - The leading protocol implementation +- `rsky` https://github.com/blacksky-algorithms/rsky + - An AT Protocol Implementation built in Rust, using atrium. - `adenosine` https://gitlab.com/bnewbold/adenosine - `atproto-rs` https://github.com/ngerakines/atproto-rs - `atproto-rs` https://github.com/Maaarcocr/atproto-rs