Skip to content

Commit

Permalink
feat(cli): call contract from jstzd server
Browse files Browse the repository at this point in the history
  • Loading branch information
huancheng-trili committed Jan 24, 2025
1 parent c379c66 commit d8d8462
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 31 deletions.
48 changes: 33 additions & 15 deletions crates/jstz_cli/src/bridge/deposit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use log::{debug, info};
use crate::{
config::{Config, NetworkName},
error::{bail_user_error, Result},
sandbox::SANDBOX_BOOTSTRAP_ACCOUNTS,
sandbox::{JSTZD_SERVER_BASE_URL, SANDBOX_BOOTSTRAP_ACCOUNTS},
term::styles,
utils::{using_jstzd, AddressOrAlias},
};
Expand Down Expand Up @@ -43,20 +43,38 @@ pub async fn exec(
let pkh = to_pkh.to_base58();
debug!("resolved `to` -> {}", &pkh);

let contract = match using_jstzd() || cfg.sandbox().is_ok_and(|c| c.container) {
// Since jstz contracts are loaded as bootstrap contracts in jstzd,
// octez-client does not recognise them by alias, but addresses
// remain constant for bootstrap contracts, so we can use the KT1 address here
true => NATIVE_BRIDGE_ADDRESS,
_ => "jstz_native_bridge",
};
// Execute the octez-client command
if cfg
.octez_client(&network)?
.call_contract(&from, contract, "deposit", &format!("\"{}\"", &pkh), amount)
.is_err()
{
bail_user_error!("Failed to deposit XTZ. Please check whether the addresses and network are correct.");
if cfg.sandbox().is_ok_and(|c| c.container) {
let client = reqwest::Client::new();
let res = client
.post(format!("{JSTZD_SERVER_BASE_URL}/contract_call"))
.json(&serde_json::json!({
"from": from,
"contract": NATIVE_BRIDGE_ADDRESS,
"amount": amount,
"entrypoint": "deposit",
"arg": format!("\"{pkh}\"")
}))
.send()
.await?;
if !res.status().is_success() {
bail_user_error!("Failed to deposit XTZ. Please check whether the addresses and network are correct.");
}
} else {
let contract = match using_jstzd() {
// Since jstz contracts are loaded as bootstrap contracts in jstzd,
// octez-client does not recognise them by alias, but addresses
// remain constant for bootstrap contracts, so we can use the KT1 address here
true => NATIVE_BRIDGE_ADDRESS,
_ => "jstz_native_bridge",
};
// Execute the octez-client command
if cfg
.octez_client(&network)?
.call_contract(&from, contract, "deposit", &format!("\"{}\"", &pkh), amount)
.is_err()
{
bail_user_error!("Failed to deposit XTZ. Please check whether the addresses and network are correct.");
}
}

info!(
Expand Down
54 changes: 42 additions & 12 deletions crates/jstz_cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ use crate::{
error::{bail, user_error, Result},
jstz::JstzClient,
sandbox::{
SANDBOX_JSTZ_NODE_PORT, SANDBOX_LOCAL_HOST_ADDR, SANDBOX_OCTEZ_NODE_RPC_PORT,
JSTZD_SERVER_BASE_URL, SANDBOX_JSTZ_NODE_PORT, SANDBOX_LOCAL_HOST_ADDR,
SANDBOX_OCTEZ_NODE_RPC_PORT,
},
utils::{using_jstzd, AddressOrAlias},
};

// hardcoding it here instead of importing from jstzd simply to avoid adding jstzd
// as a new depedency of jstz_cli just for this so that build time remains the same
const JSTZD_SERVER_BASE_URL: &str = "http://127.0.0.1:54321";

pub fn jstz_home_dir() -> PathBuf {
if let Ok(value) = env::var("JSTZ_HOME") {
Expand Down Expand Up @@ -539,16 +539,27 @@ impl Config {
jstz_node_endpoint: jstzd_config.jstz_node.endpoint.clone(),
})
}
None => Ok(Network {
octez_node_rpc_endpoint: format!(
"http://{}:{}",
SANDBOX_LOCAL_HOST_ADDR, SANDBOX_OCTEZ_NODE_RPC_PORT
),
jstz_node_endpoint: format!(
"http://{}:{}",
SANDBOX_LOCAL_HOST_ADDR, SANDBOX_JSTZ_NODE_PORT,
),
}),
None => {
// Since for some reason docker does not forward 127.0.0.1 to containers
// (but [::1] works,) we need to use localhost here, assuming that users'
// localhost gets resolved to the working IP address. This only applies
// when the sandbox container is in use. Once the old sandbox is removed,
// we won't need this match.
let addr = match self.sandbox().is_ok_and(|c| c.container) {
true => "localhost",
_ => SANDBOX_LOCAL_HOST_ADDR,
};
Ok(Network {
octez_node_rpc_endpoint: format!(
"http://{}:{}",
addr, SANDBOX_OCTEZ_NODE_RPC_PORT
),
jstz_node_endpoint: format!(
"http://{}:{}",
addr, SANDBOX_JSTZ_NODE_PORT,
),
})
}
},
}
}
Expand Down Expand Up @@ -621,6 +632,25 @@ mod tests {
)
}

#[test]
fn lookup_network_dev_sandbox_container() {
let mut config = Config::default();
config.sandbox.replace(SandboxConfig {
octez_client_dir: PathBuf::new(),
octez_node_dir: PathBuf::new(),
octez_rollup_node_dir: PathBuf::new(),
pid: 0,
container: true,
});
assert_eq!(
config.lookup_network(&NetworkName::Dev).unwrap(),
Network {
octez_node_rpc_endpoint: "http://localhost:18730".to_owned(),
jstz_node_endpoint: "http://localhost:8933".to_owned()
}
)
}

#[test]
fn lookup_network_custom() {
let dummy_network = Network {
Expand Down
1 change: 1 addition & 0 deletions crates/jstz_cli/src/sandbox/consts.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::sandbox::daemon::SandboxBootstrapAccount;

pub const SANDBOX_LOCAL_HOST_ADDR: &str = "127.0.0.1";
pub const JSTZD_SERVER_BASE_URL: &str = "http://localhost:54321";
pub const SANDBOX_OCTEZ_NODE_PORT: u16 = 18731;
pub const SANDBOX_OCTEZ_NODE_RPC_PORT: u16 = 18730;
pub const SANDBOX_JSTZ_NODE_PORT: u16 = 8933;
Expand Down
6 changes: 5 additions & 1 deletion crates/jstz_cli/src/sandbox/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ pub(crate) async fn start_container(
container_name,
image,
mounts,
Some(vec![SANDBOX_OCTEZ_NODE_RPC_PORT, SANDBOX_JSTZ_NODE_PORT]),
Some(vec![
SANDBOX_OCTEZ_NODE_RPC_PORT,
SANDBOX_JSTZ_NODE_PORT,
54321,
]),
Some(vec!["run".to_owned(), JSTZD_CONFIG_PATH.to_owned()]),
)
.await
Expand Down
38 changes: 35 additions & 3 deletions crates/jstzd/src/task/jstzd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ use anyhow::{bail, Context, Result};
use async_dropper_simple::{AsyncDrop, AsyncDropper};
use async_trait::async_trait;
use axum::{
extract::{Path, State},
extract::{Json, Path, State},
response::IntoResponse,
routing::{get, put},
routing::{get, post, put},
Router,
};
use indicatif::{ProgressBar, ProgressStyle};
Expand All @@ -32,7 +32,7 @@ use octez::r#async::{
rollup::OctezRollupConfig,
};
use prettytable::{format::consts::FORMAT_DEFAULT, Cell, Row, Table};
use serde::Serialize;
use serde::{Deserialize, Serialize};
use std::io::{stdout, Write};
use std::sync::Arc;
use tokio::{
Expand Down Expand Up @@ -351,6 +351,7 @@ impl JstzdServer {
.route("/shutdown", put(shutdown_handler))
.route("/config/:config_type", get(config_handler))
.route("/config/", get(all_config_handler))
.route("/contract_call", post(call_contract_handler))
.with_state(self.inner.state.clone());
let listener = TcpListener::bind(("0.0.0.0", self.port)).await?;

Expand Down Expand Up @@ -563,6 +564,37 @@ async fn config_handler(
}
}

#[derive(Deserialize)]
struct TransferRequest {
from: String,
contract: String,
amount: f64,
entrypoint: String,
arg: String,
}

async fn call_contract_handler(
state: State<Shared<ServerState>>,
Json(payload): Json<TransferRequest>,
) -> http::StatusCode {
let lock = state.read().await;
let c = lock.jstzd_config.as_ref().unwrap().octez_client_config();
match OctezClient::new(c.clone())
.call_contract(
&payload.from,
&payload.contract,
payload.amount,
&payload.entrypoint,
&payload.arg,
Some(100f64),
)
.await
{
Ok(_) => http::StatusCode::OK,
_ => http::StatusCode::BAD_REQUEST,
}
}

#[cfg(test)]
mod tests {
use indicatif::ProgressBar;
Expand Down

0 comments on commit d8d8462

Please sign in to comment.