diff --git a/backend/src/billing.rs b/backend/src/billing.rs index fa12bce..c263b7d 100644 --- a/backend/src/billing.rs +++ b/backend/src/billing.rs @@ -151,7 +151,11 @@ impl Billing { return Ok(()); } - tracing::info!(source, relay_count = relays.len(), "reconciling relay billing state"); + tracing::info!( + source, + relay_count = relays.len(), + "reconciling relay billing state" + ); for relay in relays { if let Err(error) = self.sync_relay_subscription_for_relay(&relay).await { @@ -765,8 +769,9 @@ impl Billing { } pub async fn stripe_create_customer(&self, tenant_pubkey: &str) -> Result { - let short_pubkey: String = tenant_pubkey.chars().take(12).collect(); - let display_name = format!("Caravel tenant {short_pubkey}"); + let short_pubkey: String = tenant_pubkey.chars().take(8).collect(); + let nostr_name = self.robot.fetch_nostr_name(tenant_pubkey).await; + let display_name = nostr_name.unwrap_or_else(|| short_pubkey.clone()); let idempotency_key = self.idempotency_key(&["create_customer", tenant_pubkey]); let resp = self @@ -998,8 +1003,7 @@ impl Billing { customer_id: &str, price_id: &str, ) -> Result<(String, String)> { - let idempotency_key = - self.idempotency_key(&["create_subscription", customer_id, price_id]); + let idempotency_key = self.idempotency_key(&["create_subscription", customer_id, price_id]); let resp = self .http .post(format!("{STRIPE_API}/subscriptions")) @@ -1726,5 +1730,4 @@ mod tests { assert_eq!(billing.stripe_secret_key, "sk_test_dummy"); assert_eq!(billing.stripe_webhook_secret, "whsec_test_dummy"); } - } diff --git a/backend/src/robot.rs b/backend/src/robot.rs index e8195db..7873c3e 100644 --- a/backend/src/robot.rs +++ b/backend/src/robot.rs @@ -160,6 +160,25 @@ impl Robot { Ok(relays) } + pub async fn fetch_nostr_name(&self, pubkey: &str) -> Option { + let pubkey = PublicKey::parse(pubkey).ok()?; + let filter = Filter::new().author(pubkey).kind(Kind::Metadata).limit(1); + let events = self + .indexer_client + .fetch_events(filter, Duration::from_secs(5)) + .await + .ok()?; + let event = events.into_iter().max_by_key(|e| e.created_at)?; + let content: serde_json::Value = serde_json::from_str(&event.content).ok()?; + let name = content + .get("display_name") + .or_else(|| content.get("name")) + .and_then(|v| v.as_str()) + .map(|s| s.trim().to_string()) + .filter(|s| !s.is_empty())?; + Some(name) + } + async fn fetch_messaging_relays_from_outbox( &self, recipient: &str,