golgi/src/lib.rs

107 lines
3.2 KiB
Rust

mod error;
mod utils;
use async_std::net::TcpStream;
//use futures::io::{self, AsyncRead as Read, AsyncWrite as Write};
use kuska_handshake::async_std::{BoxStream, BoxStreamRead, BoxStreamWrite};
use kuska_handshake::HandshakeComplete;
use kuska_sodiumoxide::crypto::{auth, sign::ed25519};
use kuska_ssb::api::{dto::CreateHistoryStreamIn, ApiCaller};
use kuska_ssb::discovery;
use kuska_ssb::keystore;
use kuska_ssb::keystore::OwnedIdentity;
use kuska_ssb::rpc::{RpcReader, RpcWriter};
use crate::error::GolgiError;
struct Sbot {
id: String,
public_key: ed25519::PublicKey,
private_key: ed25519::SecretKey,
address: String,
// aka caps key (scuttleverse identifier)
network_id: auth::Key,
client: ApiCaller<TcpStream>,
rpc_reader: RpcReader<TcpStream>,
}
impl Sbot {
async fn init(ip_port: Option<String>, net_id: Option<String>) -> Result<Sbot, GolgiError> {
let address;
if ip_port.is_none() {
address = "127.0.0.1:8008".to_string();
} else {
address = ip_port.unwrap();
}
let network_id;
if net_id.is_none() {
network_id = discovery::ssb_net_id();
} else {
network_id = auth::Key::from_slice(&hex::decode(net_id.unwrap()).unwrap()).unwrap();
}
let OwnedIdentity { pk, sk, id } = keystore::from_gosbot_local()
.await
.expect("couldn't read local secret");
let socket = TcpStream::connect(&address)
.await
.map_err(|source| GolgiError::Io {
source,
context: "socket error; failed to initiate tcp stream connection".to_string(),
})?;
let handshake = kuska_handshake::async_std::handshake_client(
&mut &socket,
network_id.clone(),
pk,
sk.clone(),
pk,
)
.await
.map_err(GolgiError::Handshake)?;
let (box_stream_read, box_stream_write) =
BoxStream::from_handshake(socket.clone(), socket, handshake, 0x8000).split_read_write();
let rpc_reader = RpcReader::new(box_stream_read);
let client = ApiCaller::new(RpcWriter::new(box_stream_write));
Ok(Self {
id,
public_key: pk,
private_key: sk,
address,
network_id,
client: client,
rpc_reader: rpc_reader,
})
}
async fn whoami(&mut self) -> Result<String, GolgiError> {
let req_id = self.client.whoami_req_send().await?;
utils::get_async(&mut self.rpc_reader, req_id, utils::whoami_res_parse)
.await
.map(|whoami| whoami.id)
}
async fn create_history_stream(&mut self, id: String) -> Result<(), GolgiError> {
let args = CreateHistoryStreamIn::new(id);
let req_id = self.client.create_history_stream_req_send(&args).await?;
utils::print_source_until_eof(&mut self.rpc_reader, req_id, utils::feed_res_parse).await
}
}
pub async fn run() -> Result<(), GolgiError> {
let mut sbot_client = Sbot::init(None, None).await?;
let id = sbot_client.whoami().await?;
println!("{}", id);
sbot_client.create_history_stream(id).await?;
Ok(())
}