Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): implement the tip logic to pay a bolt 12 #181

Merged
merged 7 commits into from
Feb 6, 2024
Merged
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
27 changes: 26 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,34 @@ ARGS=""

default: fmt
$(CC) build
@make example

doc-deps:
$(CC) install mdbook

fmt:
$(CC) fmt --all

check:
check: ## Runs unit testing
$(CC) test $(ARGS)

example:
@echo "No example for the moment"

clean:
clean: ## Clean up everythings
$(CC) clean

book:
book: ## Build the release version of documentation
cd docs/docs-book; mdbook build

dev-book:
dev-book: ## Build the docs in dev mode
cd docs/docs-book; mdbook serve --open

install:
install: ## Install coffee inside the local machine
$(CC) install --locked --path ./coffee_cmd

integration: default
integration: default ## Runs integration testing
$(CC) test -j 4 -p tests $(ARGS)

setup:
git config core.hooksPath .githooks

help: ## Show Help
@grep --no-filename -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-15s\033[0m %s\n", $$1, $$2}'
7 changes: 7 additions & 0 deletions coffee_cmd/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ pub enum CoffeeCommand {
#[arg(short, long, action = clap::ArgAction::SetTrue)]
verify: bool,
},
/// tipping a plugins developer.
#[clap(arg_required_else_help = false)]
Tip { plugin: String, amount_msat: u64 },
vincenzopalazzo marked this conversation as resolved.
Show resolved Hide resolved
}

#[derive(Debug, Subcommand)]
Expand Down Expand Up @@ -107,6 +110,10 @@ impl From<&CoffeeCommand> for coffee_core::CoffeeOperation {
CoffeeCommand::Show { plugin } => Self::Show(plugin.to_owned()),
CoffeeCommand::Search { plugin } => Self::Search(plugin.to_owned()),
CoffeeCommand::Nurse { verify } => Self::Nurse(*verify),
CoffeeCommand::Tip {
plugin,
amount_msat,
} => Self::Tip(plugin.to_owned(), amount_msat.clone()),
vincenzopalazzo marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand Down
30 changes: 27 additions & 3 deletions coffee_cmd/src/coffee_term/command_show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
//! the command result on the terminal!

use radicle_term as term;
use radicle_term::table::TableOptions;
use term::table::TableOptions;
use term::Element;

use coffee_lib::error;
use coffee_lib::errors::CoffeeError;
use coffee_lib::types::response::{CoffeeList, CoffeeNurse, CoffeeRemote, NurseStatus};
use term::Element;
use coffee_lib::types::response::{CoffeeList, CoffeeNurse, CoffeeRemote, CoffeeTip, NurseStatus};

pub fn show_list(coffee_list: Result<CoffeeList, CoffeeError>) -> Result<(), CoffeeError> {
let remotes = coffee_list?;
Expand Down Expand Up @@ -119,6 +119,30 @@ pub fn show_nurse_result(
}
Err(err) => eprintln!("{}", err),
}
Ok(())
}

pub fn show_tips(coffee_tip: &CoffeeTip) -> Result<(), CoffeeError> {
term::println(term::format::bold("●"), term::format::tertiary("Plugin"));
let mut table = radicle_term::Table::new(TableOptions::bordered());
table.push([
term::format::dim(String::from("●")),
term::format::bold(String::from("Plugin")),
term::format::bold(String::from("Receiver")),
term::format::bold(String::from("Amount Sent (msat)")),
]);
table.divider();

table.push([
if coffee_tip.status == "completed" {
term::format::positive("●").into()
} else {
term::format::negative("●").into()
},
term::format::highlight(coffee_tip.for_plugin.clone()),
term::format::bold(coffee_tip.destination.clone().unwrap_or_default()),
term::format::highlight(coffee_tip.amount_msat.to_string()),
]);
table.print();
Ok(())
}
7 changes: 7 additions & 0 deletions coffee_cmd/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,13 @@ async fn run(args: CoffeeArgs, mut coffee: CoffeeManager) -> Result<(), CoffeeEr
coffee_term::show_nurse_result(nurse_result)?;
}
}
CoffeeCommand::Tip {
plugin,
amount_msat,
} => {
let tip_result = coffee.tip(&plugin, amount_msat).await?;
coffee_term::show_tips(&tip_result)?;
}
};
Ok(())
}
Expand Down
42 changes: 41 additions & 1 deletion coffee_core/src/coffee.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Coffee mod implementation

use std::collections::HashMap;
use std::fmt::Debug;
use std::vec::Vec;
Expand All @@ -12,6 +11,7 @@ use clightningrpc_conf::{CLNConf, SyncCLNConf};
use log;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde_json::json;
use tokio::process::Command;

use coffee_github::repository::Github;
Expand Down Expand Up @@ -547,6 +547,46 @@ impl PluginManager for CoffeeManager {
}
Ok(nurse_actions)
}

async fn tip(&mut self, plugin: &str, amount_msat: u64) -> Result<CoffeeTip, CoffeeError> {
let plugins = self
.config
.plugins
.iter()
.filter(|repo_plugin| plugin == repo_plugin.name())
.collect::<Vec<_>>();
let plugin = plugins.first().ok_or(error!(
"No plugin with name `{plugin}` found in the plugins installed"
))?;

let Some(tipping) = plugin.tipping_info() else {
return Err(error!("Plugin `{plugin}` has no tipping information"));
};
// FIXME write a tip_plugin method as method
#[derive(Debug, Deserialize)]
struct FetchResult {
invoice: String,
}
let invoice: FetchResult = self
.cln(
"fetchinvoice",
json!({
"offer": tipping.bolt12,
"amount_msat": amount_msat,
}),
)
.await?;
let tip: CoffeeTip = self
.cln(
"pay",
json!({
"bolt11": invoice.invoice,
"amount_msat": amount_msat,
}),
)
.await?;
Ok(tip)
}
}

// FIXME: we need to move on but this is not safe and with the coffee
Expand Down
4 changes: 4 additions & 0 deletions coffee_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ pub enum CoffeeOperation {
/// Search(plugin name)
Search(String),
Nurse(bool),
/// Tip operation
vincenzopalazzo marked this conversation as resolved.
Show resolved Hide resolved
///
/// (plugin_name, amount_msat)
Tip(String, u64),
}

#[derive(Clone, Debug)]
Expand Down
6 changes: 5 additions & 1 deletion coffee_lib/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use tokio::process::Command;

use crate::errors::CoffeeError;
use crate::macros::error;
use crate::plugin_conf::Conf;
use crate::plugin_conf::{Conf, Tipping};
use crate::sh;

/// Plugin language definition
Expand Down Expand Up @@ -156,6 +156,10 @@ impl Plugin {
pub fn name(&self) -> String {
self.name.clone()
}

pub fn tipping_info(&self) -> Option<Tipping> {
self.conf.as_ref().and_then(|conf| conf.tipping.clone())
}
}

impl fmt::Display for Plugin {
Expand Down
10 changes: 4 additions & 6 deletions coffee_lib/src/plugin_conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]

pub struct Conf {
pub plugin: Plugin,
pub tipping: Option<Tipping>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]

pub struct Plugin {
pub name: String,
pub version: String,
Expand All @@ -24,8 +23,7 @@ pub struct Deprecaterd {
pub reason: String,
}

#[cfg(test)]
mod tests {
#[test]
fn test_remote() {}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Tipping {
pub bolt12: String,
}
8 changes: 8 additions & 0 deletions coffee_lib/src/plugin_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,12 @@ pub trait PluginManager {
&mut self,
repos: Vec<String>,
) -> Result<Vec<NurseStatus>, CoffeeError>;

/// tip a specific plugins of the following amount
///
/// The tip command required that the receiver of the
/// donation is runing the coffee core lightning plugin.
///
/// P.S: only Bitcoin ofc
async fn tip(&mut self, plugin: &str, amount_msat: u64) -> Result<CoffeeTip, CoffeeError>;
}
12 changes: 12 additions & 0 deletions coffee_lib/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,16 @@ pub mod response {
}
}
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CoffeeTip {
pub for_plugin: String,
pub invoice: String,
pub status: String,
pub destination: Option<String>,
pub amount_msat: u64,
// This includes the fee
pub amount_sent_msat: u64,
pub warning_partial_completion: Option<String>,
}
}
1 change: 1 addition & 0 deletions coffee_plugin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"
tokio = { version = "1.22.0", features = ["rt"] }
clightningrpc-common = "0.3.0-beta.3"
clightningrpc-plugin = { version = "0.3.0-beta.8", features = ["log"] }
clightningrpc-plugin-macros = "0.3.0-beta.4"
coffee_core = { path = "../coffee_core" }
coffee_lib = { path = "../coffee_lib" }
serde_json = "1"
Expand Down
Loading
Loading