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]]
|
||||
name = "cc"
|
||||
version = "1.0.86"
|
||||
version = "1.0.88"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730"
|
||||
checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -190,7 +190,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
[[package]]
|
||||
name = "clightning-testing"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/laanwj/cln4rust.git#46ff0e4dc7426926041410cc7486dc80a764a939"
|
||||
source = "git+https://github.com/laanwj/cln4rust.git#b79651dfc8606e8ad4cefe652a582abbbb97c0d0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitcoincore-rpc",
|
||||
|
@ -204,7 +204,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "clightningrpc"
|
||||
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 = [
|
||||
"clightningrpc-common",
|
||||
"serde",
|
||||
|
@ -229,6 +229,8 @@ dependencies = [
|
|||
"clightning-testing",
|
||||
"env_logger",
|
||||
"log",
|
||||
"ntest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
]
|
||||
|
@ -262,6 +264,12 @@ dependencies = [
|
|||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.8"
|
||||
|
@ -296,10 +304,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.6"
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
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]]
|
||||
name = "hex_lit"
|
||||
|
@ -313,6 +327,16 @@ version = "2.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "itoa"
|
||||
version = "1.0.10"
|
||||
|
@ -374,6 +398,39 @@ dependencies = [
|
|||
"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]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
|
@ -393,6 +450,12 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
|
@ -414,6 +477,16 @@ version = "0.2.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.78"
|
||||
|
@ -554,7 +627,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.51",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -579,9 +652,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.50"
|
||||
version = "1.0.109"
|
||||
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 = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -590,9 +674,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.10.0"
|
||||
version = "3.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67"
|
||||
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
|
@ -625,7 +709,24 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"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]]
|
||||
|
@ -777,3 +878,12 @@ name = "windows_x86_64_msvc"
|
|||
version = "0.52.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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"
|
||||
log = "0.4"
|
||||
tokio = { version = "1.36.0", features = ["rt-multi-thread", "macros"] }
|
||||
serde = "1.0"
|
||||
serde_json = "1.0.1"
|
||||
ntest = "0.9.0"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
use std::sync::Once;
|
||||
|
||||
use clightning_testing::cln;
|
||||
use serde::Deserialize;
|
||||
use serde_json::{json, Value};
|
||||
|
||||
mod utils;
|
||||
|
@ -23,19 +24,74 @@ fn init() {
|
|||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_init_plugin() -> anyhow::Result<()> {
|
||||
init();
|
||||
let pwd = std::env!("PWD");
|
||||
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 cln1 = node!();
|
||||
let info = cln1.rpc().call::<Value, Value>("ocean-info", json!({}));
|
||||
log::info!("{:?}", info);
|
||||
if info.is_err() {
|
||||
let _ = cln1.print_logs();
|
||||
}
|
||||
assert!(info.is_ok(), "{:?}", info);
|
||||
check!(cln1, info, "{:?}", info);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[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(())
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
//! Test Utils
|
||||
use std::{str::FromStr, sync::Arc};
|
||||
|
||||
use clightning_testing::{btc, cln, prelude::clightningrpc::requests::AmountOrAll};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! wait {
|
||||
($callback:expr, $timeout:expr) => {{
|
||||
|
@ -19,3 +23,149 @@ macro_rules! wait {
|
|||
$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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
json "github.com/mitchellh/mapstructure"
|
||||
|
||||
"github.com/vincenzopalazzo/cln4go/plugin"
|
||||
|
@ -12,10 +14,14 @@ func FetchOffer(cln *plugin.Plugin[*State], fetchInfo map[string]any) (map[strin
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clnFetchInvoice := struct{}{}
|
||||
cln.Log("debug", fmt.Sprintf("fetch offer result: %s", fetchInvoice))
|
||||
clnFetchInvoice := struct {
|
||||
Invoice string `mapstructure:"invoice"`
|
||||
}{}
|
||||
if err := json.Decode(fetchInvoice, &clnFetchInvoice); err != nil {
|
||||
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