mirror of
https://github.com/RoboSats/taptrade-core.git
synced 2025-08-04 09:00:05 +00:00
Merge branch 'research' of github.com:RoboSats/taptrade-core into research
This commit is contained in:
17
docs/TapTrade_obs/.obsidian/workspace.json
vendored
17
docs/TapTrade_obs/.obsidian/workspace.json
vendored
@ -13,11 +13,11 @@
|
||||
"state": {
|
||||
"type": "canvas",
|
||||
"state": {
|
||||
"file": "Research/Trade Pipelines/new concepts/concept pipeline 1.canvas",
|
||||
"file": "Research/Trade Pipelines/new concepts/concept locking script 1.canvas",
|
||||
"viewState": {
|
||||
"x": 1097.9522804628996,
|
||||
"y": -459.7668865449728,
|
||||
"zoom": 0.19999999999999996
|
||||
"x": 31,
|
||||
"y": -256.4238119356301,
|
||||
"zoom": -0.4572735104698888
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,7 +88,7 @@
|
||||
"state": {
|
||||
"type": "backlink",
|
||||
"state": {
|
||||
"file": "Research/Trade Pipelines/new concepts/concept pipeline 1.canvas",
|
||||
"file": "Research/Trade Pipelines/new concepts/concept locking script 1.canvas",
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical",
|
||||
@ -105,7 +105,7 @@
|
||||
"state": {
|
||||
"type": "outgoing-link",
|
||||
"state": {
|
||||
"file": "Research/Trade Pipelines/new concepts/concept pipeline 1.canvas",
|
||||
"file": "Research/Trade Pipelines/new concepts/concept locking script 1.canvas",
|
||||
"linksCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
}
|
||||
@ -128,7 +128,7 @@
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"file": "Research/Trade Pipelines/new concepts/concept pipeline 1.canvas"
|
||||
"file": "Research/Trade Pipelines/new concepts/concept locking script 1.canvas"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -151,6 +151,7 @@
|
||||
},
|
||||
"active": "bdb9fd88a01a8909",
|
||||
"lastOpenFiles": [
|
||||
"Research/Trade Pipelines/new concepts/concept pipeline 1.canvas",
|
||||
"Research/Trade Pipelines/new concepts/concept locking script 1.canvas",
|
||||
"Research/Trade Pipelines/new concepts/concept pipeline 1.canvas",
|
||||
"Research/Bitcoin fundamentals/Knowledge sources.md",
|
||||
@ -167,6 +168,8 @@
|
||||
"Research/Bitcoin fundamentals/Spending Taproot UTXOs.md",
|
||||
"Research/Bitcoin fundamentals/Signature and Flags.canvas",
|
||||
"Research/Implementation/CLI demonstrator architecture/demonstrator architecture.canvas",
|
||||
"Research/Implementation/Libraries.md",
|
||||
"Research/Implementation/BDK.md",
|
||||
"Research/Implementation/UI ideas.canvas",
|
||||
"Research/Trade Pipelines/Existing research.md",
|
||||
"Research/Implementation/CLI demonstrator architecture",
|
||||
|
@ -50,6 +50,7 @@ pub struct OfferTakenResponse {
|
||||
|
||||
// Taker structures //
|
||||
|
||||
// request all fitting offers from the coordinator
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct OffersRequest {
|
||||
pub buy_offers: bool, // true if looking for buy offers, false if looking for sell offers
|
||||
@ -57,19 +58,38 @@ pub struct OffersRequest {
|
||||
pub amount_max_sat: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct PublicOffer {
|
||||
pub amount_sat: u64,
|
||||
pub offer_id_hex: String,
|
||||
}
|
||||
|
||||
// response of the coordinator, containing all fitting offers to the OffersRequest request
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct PublicOffers {
|
||||
pub offers: Option<Vec<PublicOffer>>, // don't include offers var in return json if no offers are available
|
||||
}
|
||||
|
||||
// Offer information of each offer returned by the previous response
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct PublicOffer {
|
||||
pub amount_sat: u64,
|
||||
pub offer_id_hex: String,
|
||||
}
|
||||
|
||||
// request to receive the escrow psbt to sign for the specified offer to take it
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct RequestOfferPsbt {
|
||||
pub struct OfferPsbtRequest {
|
||||
pub offer: PublicOffer,
|
||||
pub trade_data: BondSubmissionRequest,
|
||||
}
|
||||
|
||||
// submit signed escrow psbt back to coordinator in a Json like this
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct PsbtSubmissionRequest {
|
||||
pub signed_psbt_hex: String,
|
||||
pub offer_id_hex: String,
|
||||
pub robohash_hex: String,
|
||||
}
|
||||
|
||||
// request polled to check if the maker has submitted his escrow transaction
|
||||
// and the escrow transaction is confirmed once this returns 200 the chat can open
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct IsOfferReadyRequest {
|
||||
pub robohash_hex: String,
|
||||
pub offer_id_hex: String,
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
use anyhow::{anyhow, Result};
|
||||
use api::{
|
||||
BondRequirementResponse, BondSubmissionRequest, OfferTakenRequest, OfferTakenResponse,
|
||||
OrderActivatedResponse, OrderRequest,
|
||||
OrderActivatedResponse, OrderRequest, PsbtSubmissionRequest,
|
||||
};
|
||||
use bdk::bitcoin::consensus::encode::serialize_hex;
|
||||
use bdk::{
|
||||
@ -17,6 +17,7 @@ use bdk::{
|
||||
wallet::AddressInfo,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{thread::sleep, time::Duration};
|
||||
|
||||
impl BondRequirementResponse {
|
||||
fn _format_request(trader_setup: &TraderSettings) -> OrderRequest {
|
||||
@ -107,7 +108,7 @@ impl OfferTakenResponse {
|
||||
let request = OfferTakenRequest {
|
||||
// maybe can be made a bit more efficient (less clone)
|
||||
robohash_hex: trader_setup.robosats_robohash_hex.clone(),
|
||||
order_id_hex: offer.order_id_hex.clone(),
|
||||
order_id_hex: offer.offer_id_hex.clone(),
|
||||
};
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let res = client
|
||||
@ -126,4 +127,32 @@ impl OfferTakenResponse {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl PsbtSubmissionRequest {
|
||||
pub fn submit_escrow_psbt(
|
||||
psbt: &PartiallySignedTransaction,
|
||||
offer_id_hex: String,
|
||||
taker_config: &TraderSettings,
|
||||
) -> Result<()> {
|
||||
let request = PsbtSubmissionRequest {
|
||||
signed_psbt_hex: psbt.serialize_hex(),
|
||||
offer_id_hex,
|
||||
robohash_hex: taker_config.robosats_robohash_hex.clone(),
|
||||
};
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let res = client
|
||||
.post(format!(
|
||||
"{}{}",
|
||||
taker_config.coordinator_endpoint, "/submit-escrow-psbt"
|
||||
))
|
||||
.json(&request)
|
||||
.send()?;
|
||||
if res.status() != 200 {
|
||||
return Err(anyhow!(
|
||||
"Submitting escrow psbt failed. Status: {}",
|
||||
res.status()
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -42,40 +42,73 @@ impl PublicOffers {
|
||||
}
|
||||
}
|
||||
|
||||
impl PublicOffer { tbd
|
||||
// pub fn take(&self, taker_config: &TraderSettings) -> Result<BondRequirementResponse> {
|
||||
// let client = reqwest::blocking::Client::new();
|
||||
// let res = client
|
||||
// .post(format!(
|
||||
// "{}{}",
|
||||
// taker_config.coordinator_endpoint, "/take-offer"
|
||||
// ))
|
||||
// .json(self)
|
||||
// .send()?
|
||||
// .json::<BondRequirementResponse>()?;
|
||||
// Ok(res)
|
||||
// }
|
||||
impl PublicOffer {
|
||||
pub fn request_bond(&self, taker_config: &TraderSettings) -> Result<BondRequirementResponse> {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let res = client
|
||||
.post(format!(
|
||||
"{}{}",
|
||||
taker_config.coordinator_endpoint, "/request-taker-bond"
|
||||
))
|
||||
.json(self)
|
||||
.send()?
|
||||
.json::<BondRequirementResponse>()?;
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl OfferTakenRequest { // tbd
|
||||
// pub fn taker_request(
|
||||
// bond: &Bond,
|
||||
// mut musig_data: &MuSigData,
|
||||
// taker_config: &TraderSettings,
|
||||
// ) -> Result<PartiallySignedTransaction> {
|
||||
// let request = RequestOfferPsbt {
|
||||
// offer:
|
||||
// };
|
||||
impl OfferPsbtRequest {
|
||||
pub fn taker_request(
|
||||
offer: &PublicOffer,
|
||||
trade_data: BondSubmissionRequest,
|
||||
taker_config: &TraderSettings,
|
||||
) -> Result<PartiallySignedTransaction> {
|
||||
let request = OfferPsbtRequest {
|
||||
offer: offer.clone(),
|
||||
trade_data,
|
||||
};
|
||||
|
||||
// let client = reqwest::blocking::Client::new();
|
||||
// let res = client
|
||||
// .post(format!(
|
||||
// "{}{}",
|
||||
// taker_config.coordinator_endpoint, "/submit-taker-bond"
|
||||
// ))
|
||||
// .json(self)
|
||||
// .send()?
|
||||
// .json::<OfferTakenResponse>()?;
|
||||
// Ok(res)
|
||||
// }
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let res = client
|
||||
.post(format!(
|
||||
"{}{}",
|
||||
taker_config.coordinator_endpoint, "/submit-taker-bond"
|
||||
))
|
||||
.json(&request)
|
||||
.send()?
|
||||
.json::<OfferTakenResponse>()?;
|
||||
|
||||
let psbt_bytes = hex::decode(res.trade_psbt_hex_to_sign)?;
|
||||
let psbt = PartiallySignedTransaction::deserialize(&psbt_bytes)?;
|
||||
Ok(psbt)
|
||||
}
|
||||
}
|
||||
|
||||
impl IsOfferReadyRequest {
|
||||
pub fn poll(taker_config: &TraderSettings, offer: &ActiveOffer) -> Result<()> {
|
||||
let request = IsOfferReadyRequest {
|
||||
robohash_hex: taker_config.robosats_robohash_hex.clone(),
|
||||
offer_id_hex: offer.offer_id_hex.clone(),
|
||||
};
|
||||
let client = reqwest::blocking::Client::new();
|
||||
loop {
|
||||
let res = client
|
||||
.post(format!(
|
||||
"{}{}",
|
||||
taker_config.coordinator_endpoint, "/poll-offer-status-taker"
|
||||
))
|
||||
.json(&request)
|
||||
.send()?;
|
||||
if res.status() == 200 {
|
||||
return Ok(());
|
||||
} else if res.status() != 201 {
|
||||
return Err(anyhow!(
|
||||
"Submitting taker psbt failed. Status: {}",
|
||||
res.status()
|
||||
));
|
||||
}
|
||||
// Sleep for 10 sec and poll again
|
||||
sleep(Duration::from_secs(10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ impl ActiveOffer {
|
||||
|
||||
let (bond, mut musig_data, payout_address) =
|
||||
trading_wallet.trade_onchain_assembly(&offer_conditions, maker_config)?;
|
||||
let submission_result = BondSubmissionRequest::send(
|
||||
let submission_result = BondSubmissionRequest::send_maker(
|
||||
&maker_config.robosats_robohash_hex,
|
||||
&bond,
|
||||
&mut musig_data,
|
||||
@ -24,23 +24,23 @@ impl ActiveOffer {
|
||||
maker_config,
|
||||
)?;
|
||||
Ok(ActiveOffer {
|
||||
order_id_hex: submission_result.order_id_hex,
|
||||
bond_locked_until_timestamp: submission_result.bond_locked_until_timestamp,
|
||||
offer_id_hex: submission_result.order_id_hex,
|
||||
used_musig_config: musig_data,
|
||||
used_bond: bond,
|
||||
expected_payout_address: payout_address,
|
||||
escrow_psbt: None,
|
||||
})
|
||||
}
|
||||
|
||||
// polling until offer is taken, in production a more efficient way would make sense
|
||||
// returns the PSBT of the escrow trade transaction we have to validate, sign and return
|
||||
pub fn wait_until_taken(
|
||||
self,
|
||||
&self,
|
||||
trader_config: &TraderSettings,
|
||||
) -> Result<PartiallySignedTransaction> {
|
||||
loop {
|
||||
thread::sleep(Duration::from_secs(10));
|
||||
if let Some(offer_taken_response) = OfferTakenResponse::check(&self, trader_config)? {
|
||||
if let Some(offer_taken_response) = OfferTakenResponse::check(self, trader_config)? {
|
||||
let psbt_bytes = hex::decode(offer_taken_response.trade_psbt_hex_to_sign)?;
|
||||
let psbt = PartiallySignedTransaction::deserialize(&psbt_bytes)?;
|
||||
return Ok(psbt);
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
cli::TraderSettings,
|
||||
communication::api::{
|
||||
BondRequirementResponse, BondSubmissionRequest, OfferTakenRequest, OfferTakenResponse,
|
||||
PublicOffer, PublicOffers,
|
||||
PsbtSubmissionRequest, PublicOffer, PublicOffers,
|
||||
},
|
||||
wallet::{
|
||||
bond::Bond,
|
||||
@ -28,7 +28,19 @@ pub fn run_maker(maker_config: &TraderSettings) -> Result<()> {
|
||||
|
||||
let offer = ActiveOffer::create(&wallet, maker_config)?;
|
||||
dbg!(&offer);
|
||||
let trade_psbt = offer.wait_until_taken(maker_config)?;
|
||||
let mut escrow_contract_psbt = offer.wait_until_taken(maker_config)?;
|
||||
|
||||
wallet
|
||||
.validate_maker_psbt(&escrow_contract_psbt)?
|
||||
.sign_escrow_psbt(&mut escrow_contract_psbt)?;
|
||||
|
||||
// submit signed escrow psbt back to coordinator
|
||||
PsbtSubmissionRequest::submit_escrow_psbt(
|
||||
&escrow_contract_psbt,
|
||||
offer.offer_id_hex.clone(),
|
||||
maker_config,
|
||||
)?;
|
||||
// wait for confirmation
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -43,9 +55,12 @@ pub fn run_taker(taker_config: &TraderSettings) -> Result<()> {
|
||||
available_offers = PublicOffers::fetch(taker_config)?;
|
||||
}
|
||||
let selected_offer: &PublicOffer = available_offers.ask_user_to_select()?;
|
||||
let accepted_offer = ActiveOffer::take(&wallet, taker_config, selected_offer)?;
|
||||
|
||||
accepted_offer.wait_on_maker();
|
||||
// take selected offer and wait for maker to sign his input to the ecrow transaction
|
||||
let accepted_offer =
|
||||
ActiveOffer::take(&wallet, taker_config, selected_offer)?.wait_on_maker(taker_config)?;
|
||||
|
||||
accepted_offer.wait_on_fiat_confirmation()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,20 +1,70 @@
|
||||
use bdk::electrum_client::Request;
|
||||
|
||||
use crate::communication::api::{IsOfferReadyRequest, OfferPsbtRequest, PsbtSubmissionRequest};
|
||||
|
||||
use super::utils::*;
|
||||
use super::*;
|
||||
|
||||
impl ActiveOffer {
|
||||
// pub fn take( tbd
|
||||
// trading_wallet: &TradingWallet,
|
||||
// taker_config: &TraderSettings,
|
||||
// offer: &PublicOffer,
|
||||
// ) -> Result<ActiveOffer> {
|
||||
// let bond_conditions: BondRequirementResponse = offer.take(taker_config)?;
|
||||
// let (bond, mut musig_data, payout_address) =
|
||||
// trading_wallet.trade_onchain_assembly(&bond_conditions, taker_config)?;
|
||||
// let trading_psbt =
|
||||
pub fn take(
|
||||
trading_wallet: &TradingWallet,
|
||||
taker_config: &TraderSettings,
|
||||
offer: &PublicOffer,
|
||||
) -> Result<ActiveOffer> {
|
||||
// fetching the bond requirements for the requested Offer (amount, locking address)
|
||||
let bond_conditions: BondRequirementResponse = offer.request_bond(taker_config)?;
|
||||
|
||||
// assembly of the Bond transaction and generation of MuSig data and payout address
|
||||
let (bond, mut musig_data, payout_address) =
|
||||
trading_wallet.trade_onchain_assembly(&bond_conditions, taker_config)?;
|
||||
|
||||
// now we submit the signed bond transaction to the coordinator and receive the escrow PSBT we have to sign
|
||||
// in exchange
|
||||
let bond_submission_request = BondSubmissionRequest::prepare_bond_request(
|
||||
&bond,
|
||||
&payout_address,
|
||||
&mut musig_data,
|
||||
taker_config,
|
||||
)?;
|
||||
let mut escrow_contract_psbt =
|
||||
OfferPsbtRequest::taker_request(offer, bond_submission_request, taker_config)?;
|
||||
|
||||
// now we have to verify, sign and submit the escrow psbt again
|
||||
trading_wallet
|
||||
.validate_taker_psbt(&escrow_contract_psbt)?
|
||||
.sign_escrow_psbt(&mut escrow_contract_psbt)?;
|
||||
|
||||
// submit signed escrow psbt back to coordinator
|
||||
PsbtSubmissionRequest::submit_escrow_psbt(
|
||||
&escrow_contract_psbt,
|
||||
offer.offer_id_hex.clone(),
|
||||
taker_config,
|
||||
)?;
|
||||
|
||||
Ok(ActiveOffer {
|
||||
offer_id_hex: offer.offer_id_hex.clone(),
|
||||
used_musig_config: musig_data,
|
||||
used_bond: bond,
|
||||
expected_payout_address: payout_address,
|
||||
escrow_psbt: Some(escrow_contract_psbt),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn wait_on_maker(&self) -> Result<()> {
|
||||
// tbd
|
||||
Ok(())
|
||||
pub fn wait_on_maker(self, taker_config: &TraderSettings) -> Result<Self> {
|
||||
IsOfferReadyRequest::poll(taker_config, &self)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn wait_on_fiat_confirmation(&self) -> Result<&Self> {
|
||||
// let user confirm in CLI that the fiat payment has been sent/receivec
|
||||
loop {
|
||||
println!("Please confirm that the fiat payment has been sent/received. (y/N)");
|
||||
let mut input = String::new();
|
||||
std::io::stdin().read_line(&mut input)?;
|
||||
if input.trim().to_lowercase() == "y" {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,9 @@ use super::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ActiveOffer {
|
||||
pub order_id_hex: String,
|
||||
pub bond_locked_until_timestamp: u128,
|
||||
pub offer_id_hex: String,
|
||||
pub used_musig_config: MuSigData,
|
||||
pub used_bond: PartiallySignedTransaction,
|
||||
pub expected_payout_address: AddressInfo,
|
||||
pub escrow_psbt: Option<PartiallySignedTransaction>,
|
||||
}
|
||||
|
@ -57,7 +57,3 @@ impl Bond {
|
||||
Ok(psbt)
|
||||
}
|
||||
}
|
||||
|
||||
// impl BranchAndBoundCoinSelection
|
||||
// pub fn new(size_of_change: u64) -> Self
|
||||
// Create new instance with target size for change output
|
||||
|
@ -3,7 +3,7 @@ pub mod musig2;
|
||||
pub mod wallet_utils;
|
||||
|
||||
use crate::{cli::TraderSettings, communication::api::BondRequirementResponse};
|
||||
use anyhow::Result;
|
||||
use anyhow::{anyhow, Result};
|
||||
use bdk::{
|
||||
bitcoin::{self, bip32::ExtendedPrivKey, psbt::PartiallySignedTransaction, Network},
|
||||
blockchain::ElectrumBlockchain,
|
||||
@ -13,7 +13,7 @@ use bdk::{
|
||||
miniscript::Descriptor,
|
||||
template::{Bip86, DescriptorTemplate},
|
||||
wallet::AddressInfo,
|
||||
KeychainKind, SyncOptions, Wallet,
|
||||
KeychainKind, SignOptions, SyncOptions, Wallet,
|
||||
};
|
||||
use bond::Bond;
|
||||
use musig2::MuSigData;
|
||||
@ -63,13 +63,35 @@ impl TradingWallet {
|
||||
offer_conditions: &BondRequirementResponse,
|
||||
trader_config: &TraderSettings,
|
||||
) -> Result<(PartiallySignedTransaction, MuSigData, AddressInfo)> {
|
||||
let trading_wallet = self.wallet;
|
||||
let trading_wallet = &self.wallet;
|
||||
let bond = Bond::assemble(&self.wallet, &offer_conditions, trader_config)?;
|
||||
let payout_address: AddressInfo =
|
||||
trading_wallet.get_address(bdk::wallet::AddressIndex::LastUnused)?;
|
||||
let mut musig_data =
|
||||
MuSigData::create(&trader_config.wallet_xprv, trading_wallet.secp_ctx())?;
|
||||
let musig_data = MuSigData::create(&trader_config.wallet_xprv, trading_wallet.secp_ctx())?;
|
||||
|
||||
Ok((bond, musig_data, payout_address))
|
||||
}
|
||||
|
||||
// validate that the taker psbt references the correct inputs and amounts
|
||||
// taker input should be the same as in the previous bond transaction.
|
||||
// input amount should be the bond amount when buying,
|
||||
pub fn validate_taker_psbt(&self, psbt: &PartiallySignedTransaction) -> Result<&Self> {
|
||||
dbg!("IMPLEMENT TAKER PSBT VALIDATION!");
|
||||
// tbd once the trade psbt is implemented on coordinator side
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn sign_escrow_psbt(&self, escrow_psbt: &mut PartiallySignedTransaction) -> Result<&Self> {
|
||||
let finalized = self.wallet.sign(escrow_psbt, SignOptions::default())?;
|
||||
if !finalized {
|
||||
return Err(anyhow!("Signing of taker escrow psbt failed!"));
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn validate_maker_psbt(&self, psbt: &PartiallySignedTransaction) -> Result<&Self> {
|
||||
dbg!("IMPLEMENT MAKER PSBT VALIDATION!");
|
||||
// tbd once the trade psbt is implemented on coordinator side
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@
|
||||
"body": "{\n \"trade_psbt_hex_to_sign\": \"DEADBEEF\",\n}",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "Returned of the offer has been taken",
|
||||
"label": "Returned if the offer has been taken",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
@ -94,7 +94,7 @@
|
||||
},
|
||||
{
|
||||
"uuid": "9ada9097-97e3-40c3-b0cf-d0eec3587027",
|
||||
"body": "{}",
|
||||
"body": "",
|
||||
"latency": 0,
|
||||
"statusCode": 204,
|
||||
"label": "Returned if the requested offer is not yet taken",
|
||||
@ -126,7 +126,7 @@
|
||||
"body": " \"offers\": [\n {\n \"amount_sat\": 1000,\n \"offer_id_hex\": \"abc123\"\n },\n {\n \"amount_sat\": 2000,\n \"offer_id_hex\": \"def456\"\n }\n ]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"label": "Returns a list of available offers, requested with OffersRequest",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
@ -148,14 +148,14 @@
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "post",
|
||||
"endpoint": "take-offer",
|
||||
"endpoint": "request-taker-bond",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "e527cfa3-eaf6-4972-882b-b723084dfe49",
|
||||
"body": "{\n \"bond_address\": \"tb1pfdvgfzwp8vhmelpv8w9kezz7nsmxw68jz6yehgze6mzx0t6r9t2qv9ynmm\",\n \"locking_amount\": 123456\n}",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"label": "Gets requested with PublicOffer Json",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
@ -171,6 +171,83 @@
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "cb932396-c73e-4a4c-9f1a-b4de5250cb16",
|
||||
"type": "http",
|
||||
"documentation": "gets requested with OfferPsbtRequest",
|
||||
"method": "post",
|
||||
"endpoint": "submit-taker-bond",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "b852f55c-5c97-47d2-a149-cbf6a0fad3e1",
|
||||
"body": "{\n \"trade_psbt_hex_to_sign\": \"INVALID_EXAMPLE_37346634343237352D373930622D343631342D626139332D65636637323565303638376337346634343237352D373930622D343631342D626139332D65636637323565303638376337346634343237352D373930622D343631342D626139332D65636637323565303638376337346634343237352D373930622D343631342D626139332D65636637323565303638376337346634343237352D373930622D343631342D626139332D656366373235653036383763\",\n}",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "returns OfferTakenResponse if bond is valid",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": true,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "34bda159-89cf-453c-bf5c-fa532b35f202",
|
||||
"type": "http",
|
||||
"documentation": "Taker submits the psbt as json to the coordinator. ",
|
||||
"method": "post",
|
||||
"endpoint": "submit-escrow-psbt",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "e9f64b19-94d0-4356-8892-d05466abbc5d",
|
||||
"body": "",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "Returned if psbt/signature is valid.",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": true,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
},
|
||||
{
|
||||
"uuid": "fdfb8fc1-1d54-46fc-b5ad-174f761120c1",
|
||||
"body": "{}",
|
||||
"latency": 0,
|
||||
"statusCode": 406,
|
||||
"label": "Returned if the signature is invalid or the psbt has been changed ",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": false,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
}
|
||||
],
|
||||
"rootChildren": [
|
||||
@ -193,6 +270,14 @@
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "ee4bb798-c787-43ae-9a34-64568ba8c31b"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "cb932396-c73e-4a4c-9f1a-b4de5250cb16"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "34bda159-89cf-453c-bf5c-fa532b35f202"
|
||||
}
|
||||
],
|
||||
"proxyMode": false,
|
||||
|
Reference in New Issue
Block a user