2023-02-05 /
@syui
nostr
, rust
, damus
, sns
damusをはじめてみた
damusはnostr protocolに対応したiosのclientです。
verify
https://gist.github.com/metasikander/609a538e6a03b2f67e5c8de625baed3e
public-keyはhexに変換します。
https://damus.io/key/
# domain root
$ cd public
$ vim ./.well-known/nostr.json
{
"names": {
"<name>": "<pubkey>"
}
}
web client
https://snort.social
cli client
とりあえずcli client作ってpostしてみた。
exampleとしてはこんな感じになるんじゃないかというのを色々なパターンで書いてみた。
pub mod data;
use std::env;
use url::Url;
use data::Data as Datas;
use seahorse::{App, Command, Context};
use nostr::{Event, EventBuilder, Metadata};
use nostr::key::{FromBech32, Keys};
use nostr::message::ClientMessage;
use tungstenite::{connect, Message as WsMessage};
const WS_ENDPOINT: &str = "wss://relay.damus.io";
use nostr_sdk::{Client};
use nostr::SubscriptionFilter;
use nostr::util::time::timestamp;
fn main() {
let args: Vec<String> = env::args().collect();
let app = App::new(env!("CARGO_PKG_NAME"))
.author(env!("CARGO_PKG_AUTHORS"))
.description(env!("CARGO_PKG_DESCRIPTION"))
.version(env!("CARGO_PKG_VERSION"))
.usage("nor [option] [x]")
.command(
Command::new("timeline")
.usage("nor t")
.description("timeline")
.alias("t")
.action(t),
)
.command(
Command::new("notify")
.usage("nor n")
.description("notify")
.alias("n")
.action(n),
)
.command(
Command::new("status")
.usage("nor s")
.description("status")
.alias("s")
.action(s),
)
.command(
Command::new("post")
.usage("nor p {}")
.description("post message, ex: $ nor p $text")
.alias("p")
.action(p),
)
;
app.run(args);
}
#[tokio::main]
async fn timeline() -> anyhow::Result<()> {
let data = Datas::new().unwrap();
let my_keys = Keys::from_bech32(&data.secret_key)?;
let mut client = Client::new(&my_keys);
client
.add_relay("wss://relay.damus.io", None)
.unwrap();
client.connect_relay("wss://relay.damus.io", true).await.unwrap();
client.connect().await?;
let subscription = SubscriptionFilter::new()
.pubkeys(vec![my_keys.public_key()])
.since(timestamp());
let t = client.get_events_of(vec![subscription]).await.unwrap();
println!("{:#?}", t);
Ok(())
}
fn t(_c: &Context) {
timeline().unwrap();
}
#[tokio::main]
async fn notify() -> anyhow::Result<()> {
let data = Datas::new().unwrap();
let my_keys = Keys::from_bech32(&data.secret_key)?;
let client = Client::new(&my_keys);
let notifications = client.notifications();
println!("{:?}", notifications);
Ok(())
//loop {
// let mut notifications = client.notifications();
// while let Ok(notification) = notifications.recv().await {
// println!("{:?}", notification);
// }
//}
}
fn n(_c: &Context) {
notify().unwrap();
}
fn status() -> anyhow::Result<()> {
let data = Datas::new().unwrap();
let metadata = Metadata::new()
.name(data.name)
.display_name(data.display_name)
.about(data.about)
.picture(Url::parse(&data.picture)?)
.nip05(data.nip);
let my_keys = Keys::from_bech32(&data.secret_key)?;
let event: Event = EventBuilder::set_metadata(&my_keys, metadata)?.to_event(&my_keys)?;
println!("{:#?}", event);
Ok(())
}
fn s(_c: &Context) {
status().unwrap();
}
fn post(c: &Context) -> anyhow::Result<()> {
let text = c.args[0].to_string();
let data = Datas::new().unwrap();
let my_keys = Keys::from_bech32(&data.secret_key)?;
let event: Event = EventBuilder::new_text_note(&text, &[]).to_event(&my_keys)?;
let (mut socket, _response) = connect(WS_ENDPOINT).expect("Can't connect to relay");
let msg = ClientMessage::new_event(event).to_json();
socket.write_message(WsMessage::Text(msg))?;
Ok(())
}
fn p(c: &Context) {
post(c).unwrap();
}