Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ pub mod invoke;
pub mod publish;
pub mod telemetry;
pub mod test;
pub mod wallet_connect;
71 changes: 71 additions & 0 deletions src/commands/wallet_connect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use crate::config::{ProfileConfig, RootConfig};
use clap::Args as ClapArgs;
use miette::IntoDiagnostic;
use std::net::SocketAddr;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpListener;

const HTML_TEMPLATE: &str = include_str!("../../templates/wallet_connect.html");

#[derive(ClapArgs)]
pub struct Args {
/// Port to serve wallet connect on.
#[arg(long, default_value_t = 3030)]
port: u16,

/// Optional CBOR hex to pre-fill
#[arg(long)]
cbor: Option<String>,
}

pub async fn run(args: Args, config: &RootConfig, profile: &ProfileConfig) -> miette::Result<()> {
#[cfg(feature = "unstable")]
{
_run(args, config, profile).await
}
#[cfg(not(feature = "unstable"))]
{
Err(miette::miette!(
"The wallet-connect command is currently unstable and requires the `unstable` feature to be enabled."
))
}
}

async fn _run(args: Args, config: &RootConfig, profile: &ProfileConfig) -> miette::Result<()> {
let network = config.resolve_profile_network(&profile.name)?;

let addr = SocketAddr::from(([127, 0, 0, 1], args.port));
let listener = TcpListener::bind(addr).await.into_diagnostic()?;

println!("Serving wallet connect on port {}", args.port);
println!("http://localhost:{}", args.port);

let cbor_value = args.cbor.unwrap_or_default();
let headers_json = serde_json::to_string(&network.trp.headers).into_diagnostic()?;

let body = HTML_TEMPLATE
.replace("__CBOR_PLACEHOLDER__", &cbor_value)
.replace("__TRP_URL_PLACEHOLDER__", &network.trp.url)
.replace("__TRP_HEADERS_PLACEHOLDER__", &headers_json);

let response = format!(
"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: {}\r\n\r\n{}",
body.len(),
body
);

loop {
let (mut socket, _) = listener.accept().await.into_diagnostic()?;
let response = response.clone();

tokio::spawn(async move {
let mut buf = [0; 1024];
// Leemos la solicitud (aunque la ignoramos para este ejemplo simple)
let _ = socket.read(&mut buf).await;

if let Err(e) = socket.write_all(response.as_bytes()).await {
eprintln!("failed to write to socket; err = {:?}", e);
}
});
}
}
5 changes: 5 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ enum Commands {
/// Manage crypographic identities
Identities(cmds::identities::Args),

/// Connect to wallets via Wallet Connect protocol (UNSTABLE - This feature is experimental and may change)
#[command(hide = true)]
WalletConnect(cmds::wallet_connect::Args),

/// Publish a Tx3 package into the registry (UNSTABLE - This feature is experimental and may change)
#[command(hide = true)]
Publish(cmds::publish::Args),
Expand Down Expand Up @@ -111,6 +115,7 @@ async fn run_scoped_command(cli: Cli, config: RootConfig) -> Result<()> {
Commands::Identities(args) => cmds::identities::run(args, &config, &profile),
Commands::Publish(args) => cmds::publish::run(args, &config),
Commands::Telemetry(args) => cmds::telemetry::run(args),
Commands::WalletConnect(args) => cmds::wallet_connect::run(args, &config, &profile).await,
};

if let Some(handle) = metric {
Expand Down
Loading
Loading