Skip to content
Permalink
Browse files

feat: quickly-assembled ilp-cli command for hackathon

  • Loading branch information...
Ben Striegel authored and bstrie committed Oct 2, 2019
1 parent be8d401 commit 59a19cb02df5adfba52a879ea8d446764c8837c0
Showing with 89 additions and 2 deletions.
  1. +1 −0 Cargo.lock
  2. +2 −1 crates/ilp-cli/Cargo.toml
  3. +65 −0 crates/ilp-cli/src/interpreter.rs
  4. +20 −0 crates/ilp-cli/src/parser.rs
  5. +1 −1 examples/simple/README.md

Some generated files are not rendered by default. Learn more.

@@ -8,4 +8,5 @@ repository = "https://github.com/interledger-rs/interledger-rs"

[dependencies]
clap = { version = "2.33.0", default-features = false }
reqwest = { version = "0.9.20", default-features = false, features = ["default-tls"] }
reqwest = { version = "0.9.20", default-features = false, features = ["default-tls"] }
serde = "1.0.101"
@@ -2,6 +2,7 @@ use clap::ArgMatches;
use reqwest::{self, Client, Response};
use std::collections::HashMap;

#[derive(Debug)]
pub enum Error {
UsageErr(&'static str),
ClientErr(reqwest::Error),
@@ -67,6 +68,13 @@ pub fn run<'a, 'b>(matches: &ArgMatches) -> Result<Response, Error> {
_ => Err(Error::UsageErr("ilp-cli help settlement-engines")),
},
"status" => client.get_root(ilp_cli_matches),
"testnet" => match ilp_cli_matches.subcommand() {
(testnet_subcommand, Some(testnet_matches)) => match testnet_subcommand {
"setup" => client.xpring_account(testnet_matches),
command => panic!("Unhandled `ilp-cli testnet` subcommand: {}", command),
},
_ => Err(Error::UsageErr("ilp-cli help testnet")),
},
command => panic!("Unhandled `ilp-cli` subcommand: {}", command),
}
}
@@ -223,6 +231,51 @@ impl NodeClient<'_> {
.send()
.map_err(Error::ClientErr)
}
/*
{"http_endpoint": "https://rs3.xpring.dev/ilp", // ilp_over_http_url
"passkey": "b0i3q9tbvfgek", // ilp_over_http_outgoing_token = username:passkey
"btp_endpoint": "btp+wss://rs3.xpring.dev/ilp/btp", // ilp_over_btp_url
"asset_scale": 9, // asset_scale
"node": "rs3.xpring.dev",
"asset_code": "XRP", // asset_code
"username": "user_g31tuju4", // username
"payment_pointer": "$rs3.xpring.dev/accounts/user_g31tuju4/spsp"}
routing_relation Parent
*/

fn xpring_account(&self, matches: &ArgMatches) -> Result<Response, Error> {
let (auth, cli_args) = extract_args(matches);
let asset = cli_args["asset"];
let foreign_args: XpringResponse = self
.client
.get(&format!("https://stage.xpring.io/api/accounts/{}", asset))
.send()
.unwrap()
.json()
.unwrap();
let mut args = HashMap::new();
args.insert("ilp_over_http_url", foreign_args.http_endpoint.clone());
args.insert(
"ilp_over_http_outgoing_token",
format!(
"{}:{}",
foreign_args.username.clone(),
foreign_args.passkey.clone()
),
);
args.insert("ilp_over_btp_url", foreign_args.btp_endpoint.clone());
args.insert("asset_scale", foreign_args.asset_scale.to_string());
args.insert("asset_code", foreign_args.asset_code.clone());
args.insert("username", format!("xpring_{}", cli_args["asset"]));
args.insert("routing_relation", String::from("Parent")); // TODO: weird behavior when deleting and re-inserting accounts with this
dbg!(&args);
self.client
.post(&format!("{}/accounts/", self.url))
.bearer_auth(auth)
.json(&args)
.send()
.map_err(Error::ClientErr)
}
}

// This function takes the map of arguments parsed by Clap
@@ -249,3 +302,15 @@ fn unflatten_pairs<'a>(matches: &'a ArgMatches) -> (&'a str, HashMap<&'a str, &'
}
(matches.value_of("authorization_key").unwrap(), pairs)
}

#[derive(Debug, serde::Deserialize)]
struct XpringResponse {
http_endpoint: String,
passkey: String,
btp_endpoint: String,
asset_scale: u8,
node: String,
asset_code: String,
username: String,
payment_pointer: String,
}
@@ -17,6 +17,7 @@ pub fn build<'a, 'b>() -> App<'a, 'b> {
routes().subcommands(vec![routes_list(), routes_set(), routes_set_all()]),
settlement_engines().subcommands(vec![settlement_engines_set_all()]),
status(),
testnet().subcommands(vec![testnet_setup()]),
])
}

@@ -368,6 +369,7 @@ fn routes_set_all<'a, 'b>() -> App<'a, 'b> {

fn settlement_engines<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("settlement-engines")
.about("Interact with the settlement engine configurations")
}

fn settlement_engines_set_all<'a, 'b>() -> App<'a, 'b> {
@@ -385,3 +387,21 @@ fn settlement_engines_set_all<'a, 'b>() -> App<'a, 'b> {
fn status<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("status").about("Query the status of the server")
}

fn testnet<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("testnet").about("Easily access the testnet")
}

fn testnet_setup<'a, 'b>() -> App<'a, 'b> {
AuthorizedSubCommand::with_name("setup")
.about("Create a local account peered with a remote node on the testnet")
.arg(
Arg::with_name("asset")
.index(1)
.required(true)
.takes_value(true)
.possible_values(&["xrp", "eth"])
.case_insensitive(true)
.help("The asset that will be tied to the new testnet account"),
)
}
@@ -173,7 +173,7 @@ else

```bash
# Turn on debug logging for all of the interledger.rs components
export RUST_LOG=interledger=trace
export RUST_LOG=interledger=debug
# Start both nodes.
# Note that the configuration options can be passed as environment variables

0 comments on commit 59a19cb

Please sign in to comment.
You can’t perform that action at this time.