sim: add simple simulation of the payout
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
This commit is contained in:
parent
3a95f266d7
commit
bb11169d8e
|
@ -177,9 +177,9 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.86"
|
version = "1.0.88"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730"
|
checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -190,7 +190,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clightning-testing"
|
name = "clightning-testing"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/laanwj/cln4rust.git#46ff0e4dc7426926041410cc7486dc80a764a939"
|
source = "git+https://github.com/laanwj/cln4rust.git#b79651dfc8606e8ad4cefe652a582abbbb97c0d0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bitcoincore-rpc",
|
"bitcoincore-rpc",
|
||||||
|
@ -204,7 +204,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clightningrpc"
|
name = "clightningrpc"
|
||||||
version = "0.3.0-beta.8"
|
version = "0.3.0-beta.8"
|
||||||
source = "git+https://github.com/laanwj/cln4rust.git#46ff0e4dc7426926041410cc7486dc80a764a939"
|
source = "git+https://github.com/laanwj/cln4rust.git#b79651dfc8606e8ad4cefe652a582abbbb97c0d0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clightningrpc-common",
|
"clightningrpc-common",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -229,6 +229,8 @@ dependencies = [
|
||||||
"clightning-testing",
|
"clightning-testing",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
|
"ntest",
|
||||||
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
@ -262,6 +264,12 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
|
@ -296,10 +304,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hashbrown"
|
||||||
version = "0.3.6"
|
version = "0.14.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
|
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hex_lit"
|
name = "hex_lit"
|
||||||
|
@ -313,6 +327,16 @@ version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.10"
|
version = "1.0.10"
|
||||||
|
@ -374,6 +398,39 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ntest"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da8ec6d2b73d45307e926f5af46809768581044384637af6b3f3fe7c3c88f512"
|
||||||
|
dependencies = [
|
||||||
|
"ntest_test_cases",
|
||||||
|
"ntest_timeout",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ntest_test_cases"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be7d33be719c6f4d09e64e27c1ef4e73485dc4cc1f4d22201f89860a7fe22e22"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ntest_timeout"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "066b468120587a402f0b47d8f80035c921f6a46f8209efd0632a89a16f5188a4"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-crate",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
|
@ -393,6 +450,12 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.13"
|
version = "0.2.13"
|
||||||
|
@ -414,6 +477,16 @@ version = "0.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-crate"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.78"
|
version = "1.0.78"
|
||||||
|
@ -554,7 +627,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.51",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -579,9 +652,20 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.50"
|
version = "1.0.109"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb"
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.51"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -590,9 +674,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.10.0"
|
version = "3.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67"
|
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
|
@ -625,7 +709,24 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.51",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.19.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -777,3 +878,12 @@ name = "windows_x86_64_msvc"
|
||||||
version = "0.52.3"
|
version = "0.52.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6"
|
checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.5.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
|
@ -9,4 +9,6 @@ env_logger = "0.11.1"
|
||||||
anyhow = "1.0.71"
|
anyhow = "1.0.71"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
tokio = { version = "1.36.0", features = ["rt-multi-thread", "macros"] }
|
tokio = { version = "1.36.0", features = ["rt-multi-thread", "macros"] }
|
||||||
|
serde = "1.0"
|
||||||
serde_json = "1.0.1"
|
serde_json = "1.0.1"
|
||||||
|
ntest = "0.9.0"
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
|
|
||||||
use clightning_testing::cln;
|
use clightning_testing::cln;
|
||||||
|
use serde::Deserialize;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
@ -23,19 +24,74 @@ fn init() {
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_init_plugin() -> anyhow::Result<()> {
|
async fn test_init_plugin() -> anyhow::Result<()> {
|
||||||
init();
|
init();
|
||||||
let pwd = std::env!("PWD");
|
let cln1 = node!();
|
||||||
let plugin_name = std::env!("PLUGIN_NAME");
|
|
||||||
log::debug!("plugin path: {pwd}/../{plugin_name}");
|
|
||||||
let cln1 = cln::Node::with_params(
|
|
||||||
&format!("--developer --experimental-offers --plugin={pwd}/../{plugin_name}"),
|
|
||||||
"regtest",
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let info = cln1.rpc().call::<Value, Value>("ocean-info", json!({}));
|
let info = cln1.rpc().call::<Value, Value>("ocean-info", json!({}));
|
||||||
log::info!("{:?}", info);
|
log::info!("{:?}", info);
|
||||||
if info.is_err() {
|
check!(cln1, info, "{:?}", info);
|
||||||
let _ = cln1.print_logs();
|
Ok(())
|
||||||
}
|
}
|
||||||
assert!(info.is_ok(), "{:?}", info);
|
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
#[ntest::timeout(560000)]
|
||||||
|
async fn test_ocean_simple_payout() -> anyhow::Result<()> {
|
||||||
|
init();
|
||||||
|
|
||||||
|
// initial setup of the lightning payout with ocean.
|
||||||
|
// Long part of the story:
|
||||||
|
//
|
||||||
|
// - Ocean pool has a lightning node to do lightning payout;
|
||||||
|
// - Every miners will open a channel with the pool ln node;
|
||||||
|
// - The pool lightning node receive in money from the coinbase rewards
|
||||||
|
// - Wait the maturity of the blocks
|
||||||
|
// - The pool lightning node identify the channel and splice the amount of money
|
||||||
|
// inside the channel.
|
||||||
|
// - The splice transaction get confirmed;
|
||||||
|
// - The pool pay the bolt12 miners
|
||||||
|
let ocean_ln = node!();
|
||||||
|
let btc = ocean_ln.btc();
|
||||||
|
let miner_1 = node!(btc.clone());
|
||||||
|
open_channel(&miner_1, &ocean_ln, false)?;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct Offer {
|
||||||
|
bolt12: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// the miner generate the payout reusable offer
|
||||||
|
let payout_miner: Offer = miner_1.rpc().call(
|
||||||
|
"offer",
|
||||||
|
json!({
|
||||||
|
"amount": "any",
|
||||||
|
"description": "Miner 1 lightning payout for ocean",
|
||||||
|
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
log::info!("offer invoice: {:?}", payout_miner);
|
||||||
|
// FIXME: we are not able at the moment to splice the channel to increase the balance,
|
||||||
|
// so at the moment, so atm we open a new channel but this is not inside our simulation
|
||||||
|
open_channel(&ocean_ln, &miner_1, false)?;
|
||||||
|
|
||||||
|
let listchannels = ocean_ln.rpc().listchannels(None, None, None)?.channels;
|
||||||
|
log::debug!(
|
||||||
|
"channels before paying: {}",
|
||||||
|
serde_json::to_string(&listchannels)?
|
||||||
|
);
|
||||||
|
let listchannels = ocean_ln.rpc().listfunds()?.channels;
|
||||||
|
log::debug!(
|
||||||
|
"channels in list funds before paying: {}",
|
||||||
|
serde_json::to_string(&listchannels)?
|
||||||
|
);
|
||||||
|
let payout: Result<Value, _> = ocean_ln.rpc().call(
|
||||||
|
"ocean-pay",
|
||||||
|
json!({
|
||||||
|
"invstr": payout_miner.bolt12,
|
||||||
|
"amount_msat": "10sat",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
if payout.is_err() {
|
||||||
|
let _ = ocean_ln.print_logs()?;
|
||||||
|
payout.unwrap();
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
//! Test Utils
|
//! Test Utils
|
||||||
|
use std::{str::FromStr, sync::Arc};
|
||||||
|
|
||||||
|
use clightning_testing::{btc, cln, prelude::clightningrpc::requests::AmountOrAll};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! wait {
|
macro_rules! wait {
|
||||||
($callback:expr, $timeout:expr) => {{
|
($callback:expr, $timeout:expr) => {{
|
||||||
|
@ -19,3 +23,149 @@ macro_rules! wait {
|
||||||
$crate::wait!($callback, 100);
|
$crate::wait!($callback, 100);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! node {
|
||||||
|
($btc:expr) => {{
|
||||||
|
let pwd = std::env!("PWD");
|
||||||
|
let plugin_name = std::env!("PLUGIN_NAME");
|
||||||
|
log::debug!("plugin path: {pwd}/../{plugin_name}");
|
||||||
|
cln::Node::with_btc_and_params(
|
||||||
|
$btc,
|
||||||
|
&format!("--developer --experimental-offers --plugin={pwd}/../{plugin_name}"),
|
||||||
|
"regtest",
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
}};
|
||||||
|
() => {{
|
||||||
|
let pwd = std::env!("PWD");
|
||||||
|
let plugin_name = std::env!("PLUGIN_NAME");
|
||||||
|
log::debug!("plugin path: {pwd}/../{plugin_name}");
|
||||||
|
cln::Node::with_params(
|
||||||
|
&format!("--developer --experimental-offers --plugin={pwd}/../{plugin_name}"),
|
||||||
|
"regtest",
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! check {
|
||||||
|
($cln:expr, $value:expr, $($arg:tt)+) => {{
|
||||||
|
if $value.is_err() {
|
||||||
|
let _ = $cln.print_logs();
|
||||||
|
}
|
||||||
|
assert!($value.is_ok());
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! wait_sync {
|
||||||
|
($cln:expr) => {{
|
||||||
|
wait!(
|
||||||
|
|| {
|
||||||
|
let Ok(cln_info) = $cln.rpc().getinfo() else {
|
||||||
|
return Err(());
|
||||||
|
};
|
||||||
|
log::trace!("cln info: {:?}", cln_info);
|
||||||
|
if cln_info.warning_bitcoind_sync.is_some() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if cln_info.warning_lightningd_sync.is_some() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
let mut out = $cln.rpc().listfunds().unwrap().outputs;
|
||||||
|
log::trace!("{:?}", out);
|
||||||
|
out.retain(|tx| tx.status == "confirmed");
|
||||||
|
if out.is_empty() {
|
||||||
|
let addr = $cln.rpc().newaddr(None).unwrap().bech32.unwrap();
|
||||||
|
let _ = fund_wallet($cln.btc(), &addr, 6);
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
10000
|
||||||
|
);
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open a channel from node_a -> node_b
|
||||||
|
pub fn open_channel(node_a: &cln::Node, node_b: &cln::Node, dual_open: bool) -> anyhow::Result<()> {
|
||||||
|
let addr = node_a.rpc().newaddr(None)?.bech32.unwrap();
|
||||||
|
fund_wallet(node_a.btc(), &addr, 8)?;
|
||||||
|
wait_for_funds(node_a)?;
|
||||||
|
|
||||||
|
wait_sync!(node_a);
|
||||||
|
|
||||||
|
if dual_open {
|
||||||
|
let addr = node_b.rpc().newaddr(None)?.address.unwrap();
|
||||||
|
fund_wallet(node_b.btc(), &addr, 6)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let getinfo2 = node_b.rpc().getinfo()?;
|
||||||
|
node_a
|
||||||
|
.rpc()
|
||||||
|
.connect(&getinfo2.id, Some(&format!("127.0.0.1:{}", node_b.port)))?;
|
||||||
|
let listfunds = node_a.rpc().listfunds()?;
|
||||||
|
log::debug!("list funds {:?}", listfunds);
|
||||||
|
node_a
|
||||||
|
.rpc()
|
||||||
|
.fundchannel(&getinfo2.id, AmountOrAll::All, None)?;
|
||||||
|
wait!(
|
||||||
|
|| {
|
||||||
|
let mut channels = node_a.rpc().listfunds().unwrap().channels;
|
||||||
|
log::info!("{:?}", channels);
|
||||||
|
let origin_size = channels.len();
|
||||||
|
channels.retain(|chan| chan.state == "CHANNELD_NORMAL");
|
||||||
|
if channels.len() == origin_size {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let addr = node_a.rpc().newaddr(None).unwrap().bech32.unwrap();
|
||||||
|
fund_wallet(node_a.btc(), &addr, 6).unwrap();
|
||||||
|
wait_sync!(node_a);
|
||||||
|
Err(())
|
||||||
|
},
|
||||||
|
10000
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fund_wallet(btc: Arc<btc::BtcNode>, addr: &str, blocks: u64) -> anyhow::Result<String> {
|
||||||
|
use clightning_testing::prelude::bitcoincore_rpc;
|
||||||
|
use clightning_testing::prelude::bitcoincore_rpc::RpcApi;
|
||||||
|
// mine some bitcoin inside the lampo address
|
||||||
|
let address = bitcoincore_rpc::bitcoin::Address::from_str(addr)
|
||||||
|
.unwrap()
|
||||||
|
.assume_checked();
|
||||||
|
let _ = btc.rpc().generate_to_address(blocks, &address).unwrap();
|
||||||
|
|
||||||
|
Ok(address.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wait_for_funds(cln: &cln::Node) -> anyhow::Result<()> {
|
||||||
|
use clightning_testing::prelude::bitcoincore_rpc;
|
||||||
|
use clightning_testing::prelude::bitcoincore_rpc::RpcApi;
|
||||||
|
|
||||||
|
wait!(
|
||||||
|
|| {
|
||||||
|
let addr = cln.rpc().newaddr(None).unwrap().bech32.unwrap();
|
||||||
|
let address = bitcoincore_rpc::bitcoin::Address::from_str(&addr)
|
||||||
|
.unwrap()
|
||||||
|
.assume_checked();
|
||||||
|
let _ = cln.btc().rpc().generate_to_address(1, &address).unwrap();
|
||||||
|
|
||||||
|
let Ok(funds) = cln.rpc().listfunds() else {
|
||||||
|
return Err(());
|
||||||
|
};
|
||||||
|
log::trace!("listfunds {:?}", funds);
|
||||||
|
if funds.outputs.is_empty() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
10000
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
json "github.com/mitchellh/mapstructure"
|
json "github.com/mitchellh/mapstructure"
|
||||||
|
|
||||||
"github.com/vincenzopalazzo/cln4go/plugin"
|
"github.com/vincenzopalazzo/cln4go/plugin"
|
||||||
|
@ -12,10 +14,14 @@ func FetchOffer(cln *plugin.Plugin[*State], fetchInfo map[string]any) (map[strin
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
cln.Log("debug", fmt.Sprintf("fetch offer result: %s", fetchInvoice))
|
||||||
clnFetchInvoice := struct{}{}
|
clnFetchInvoice := struct {
|
||||||
|
Invoice string `mapstructure:"invoice"`
|
||||||
|
}{}
|
||||||
if err := json.Decode(fetchInvoice, &clnFetchInvoice); err != nil {
|
if err := json.Decode(fetchInvoice, &clnFetchInvoice); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return nil, nil
|
return map[string]any{
|
||||||
|
"bolt11": clnFetchInvoice.Invoice,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package plugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
json "github.com/mitchellh/mapstructure"
|
||||||
|
|
||||||
|
"github.com/vincenzopalazzo/cln4go/plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func OceanPay(cln *plugin.Plugin[*State], request map[string]any) (map[string]any, error) {
|
||||||
|
cln.Log("debug", fmt.Sprintf("ocean-pay: %s", request))
|
||||||
|
clnRequest := struct {
|
||||||
|
Invstr string `mapstructure:"invstr"`
|
||||||
|
Amount_msat string `mapstructure:"amount_msat"`
|
||||||
|
}{}
|
||||||
|
if err := json.Decode(request, &clnRequest); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cln.Log("debug", fmt.Sprintf("decode the string %s", clnRequest.Invstr))
|
||||||
|
invstrDecode, err := cln.State.Rpc("decode", map[string]any{
|
||||||
|
"string": clnRequest.Invstr,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
clnDecode := struct {
|
||||||
|
InvType string `mapstructure:"type"`
|
||||||
|
Valid bool `mapstructure:"valid"`
|
||||||
|
}{}
|
||||||
|
|
||||||
|
if err := json.Decode(invstrDecode, &clnDecode); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cln.Log("debug", fmt.Sprintf("decode offer: %s", invstrDecode))
|
||||||
|
var payInvoice map[string]any
|
||||||
|
switch clnDecode.InvType {
|
||||||
|
case "bolt12 offer", "bolt12 invoice_request", "bolt12 invoice":
|
||||||
|
payInvoice, err = FetchOffer(cln, map[string]any{
|
||||||
|
"offer": clnRequest.Invstr,
|
||||||
|
"amount_msat": clnRequest.Amount_msat,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Invoice String %s not supported: %s", clnDecode.InvType, clnRequest.Invstr)
|
||||||
|
}
|
||||||
|
|
||||||
|
cln.Log("debug", fmt.Sprintf("paying the offer %s", payInvoice))
|
||||||
|
payResponse, err := cln.State.Rpc("pay", payInvoice)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return payResponse, nil
|
||||||
|
}
|
Loading…
Reference in New Issue