Skip to main content

auths_cli/services/
gist.rs

1use anyhow::{Context, Result};
2use serde::Deserialize;
3
4#[derive(Debug, Deserialize)]
5struct GistResponse {
6    html_url: String,
7}
8
9/// Publishes a signed platform claim as a public GitHub Gist.
10///
11/// The Gist persists as a permanent, publicly-verifiable anchor even
12/// after the OAuth token expires. Anyone can verify the Ed25519 signature
13/// inside the claim using only the DID's public key.
14///
15/// Args:
16/// * `client`: Pre-configured HTTP client from the composition root.
17/// * `access_token`: GitHub OAuth access token (temporary, used only for creation).
18/// * `claim_json`: The JSON string of the signed platform claim.
19///
20/// Usage:
21/// ```ignore
22/// let url = publish_proof_gist(&client, &auth.access_token, &signed_claim).await?;
23/// println!("Proof published at: {url}");
24/// ```
25pub async fn publish_proof_gist(
26    client: &reqwest::Client,
27    access_token: &str,
28    claim_json: &str,
29) -> Result<String> {
30    let payload = serde_json::json!({
31        "description": "Auths Identity Proof — cryptographic link between DID and GitHub account",
32        "public": true,
33        "files": {
34            "auths-proof.json": {
35                "content": claim_json
36            }
37        }
38    });
39
40    let resp: GistResponse = client
41        .post("https://api.github.com/gists")
42        .header("Authorization", format!("Bearer {access_token}"))
43        .header("User-Agent", "auths-cli")
44        .header("Accept", "application/vnd.github+json")
45        .json(&payload)
46        .send()
47        .await
48        .context("Failed to create GitHub Gist")?
49        .error_for_status()
50        .context("GitHub Gist creation returned an error")?
51        .json()
52        .await
53        .context("Failed to parse Gist response")?;
54
55    Ok(resp.html_url)
56}