Skip to content
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ The node currently exposes the following APIs:
- `/createutxos` (POST)
- `/decodelninvoice` (POST)
- `/decodergbinvoice` (POST)
- `/decodeswapstring` (POST)
- `/disconnectpeer` (POST)
- `/estimatefee` (POST)
- `/failtransfers` (POST)
Expand Down
56 changes: 56 additions & 0 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,24 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/DecodeRGBInvoiceResponse'
/decodeswapstring:
post:
tags:
- Swaps
summary: Decode a swapstring
description: Decode the provided swapstring
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/DecodeSwapstringRequest'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/DecodeSwapstringResponse'
/disconnectpeer:
post:
tags:
Expand Down Expand Up @@ -1690,6 +1708,44 @@ components:
items:
type: string
example: rpcs://proxy.iriswallet.com/0.2/json-rpc
DecodeSwapstringRequest:
type: object
required:
- swapstring
properties:
swapstring:
type: string
example: 30/rgb:CJkb4YZw-jRiz2sk-~PARPio-wtVYI1c-XAEYCqO-wTfvRZ8/10/rgb:icfqnK9y-wObZKTu-XJcDL98-sKbE5Mh-OuDJhiI-brRJrzE/1715896416/9d342c6ba006e24abee84a2e034a22d5e30c1f2599fb9c3574d46d3cde3d65a2
DecodeSwapstringResponse:
type: object
required:
- qty_from
- qty_to
- expiry
- payment_hash
properties:
qty_from:
type: integer
example: 30
qty_to:
type: integer
example: 10
from_asset:
type:
- string
- 'null'
example: rgb:CJkb4YZw-jRiz2sk-~PARPio-wtVYI1c-XAEYCqO-wTfvRZ8
to_asset:
type:
- string
- 'null'
example: rgb:icfqnK9y-wObZKTu-XJcDL98-sKbE5Mh-OuDJhiI-brRJrzE
expiry:
type: integer
example: 1715896416
payment_hash:
type: string
example: 9d342c6ba006e24abee84a2e034a22d5e30c1f2599fb9c3574d46d3cde3d65a2
DisconnectPeerRequest:
type: object
required:
Expand Down
3 changes: 2 additions & 1 deletion src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ use crate::{

const REVOKED_TOKENS_FILE: &str = "revoked_tokens.txt";

const READ_ONLY_OPS: [&str; 23] = [
const READ_ONLY_OPS: [&str; 24] = [
"/assetbalance",
"/assetmetadata",
"/btcbalance",
"/checkindexerurl",
"/checkproxyendpoint",
"/decodelninvoice",
"/decodergbinvoice",
"/decodeswapstring",
"/estimatefee",
"/getassetmedia",
"/getchannelid",
Expand Down
17 changes: 9 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ use crate::ldk::stop_ldk;
use crate::routes::{
address, asset_balance, asset_metadata, backup, btc_balance, change_password,
check_indexer_url, check_proxy_endpoint, close_channel, connect_peer, create_utxos,
decode_ln_invoice, decode_rgb_invoice, disconnect_peer, estimate_fee, fail_transfers,
get_asset_media, get_channel_id, get_payment, get_swap, inflate, init, invoice_status,
issue_asset_cfa, issue_asset_ifa, issue_asset_nia, issue_asset_uda, keysend, list_assets,
list_channels, list_payments, list_peers, list_swaps, list_transactions, list_transfers,
list_unspents, ln_invoice, lock, maker_execute, maker_init, network_info, node_info,
open_channel, post_asset_media, refresh_transfers, restore, revoke_token, rgb_invoice,
send_btc, send_onion_message, send_payment, send_rgb, shutdown, sign_message, sync, taker,
unlock,
decode_ln_invoice, decode_rgb_invoice, decode_swapstring, disconnect_peer, estimate_fee,
fail_transfers, get_asset_media, get_channel_id, get_payment, get_swap, inflate, init,
invoice_status, issue_asset_cfa, issue_asset_ifa, issue_asset_nia, issue_asset_uda, keysend,
list_assets, list_channels, list_payments, list_peers, list_swaps, list_transactions,
list_transfers, list_unspents, ln_invoice, lock, maker_execute, maker_init, network_info,
node_info, open_channel, post_asset_media, refresh_transfers, restore, revoke_token,
rgb_invoice, send_btc, send_onion_message, send_payment, send_rgb, shutdown, sign_message,
sync, taker, unlock,
};
use crate::utils::{start_daemon, AppState, LOGS_DIR};

Expand Down Expand Up @@ -118,6 +118,7 @@ pub(crate) async fn app(args: UserArgs) -> Result<(Router, Arc<AppState>), AppEr
.route("/createutxos", post(create_utxos))
.route("/decodelninvoice", post(decode_ln_invoice))
.route("/decodergbinvoice", post(decode_rgb_invoice))
.route("/decodeswapstring", post(decode_swapstring))
.route("/disconnectpeer", post(disconnect_peer))
.route("/estimatefee", post(estimate_fee))
.route("/failtransfers", post(fail_transfers))
Expand Down
32 changes: 32 additions & 0 deletions src/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,21 @@ pub(crate) struct DecodeRGBInvoiceResponse {
pub(crate) transport_endpoints: Vec<String>,
}

#[derive(Deserialize, Serialize)]
pub(crate) struct DecodeSwapstringRequest {
pub(crate) swapstring: String,
}

#[derive(Deserialize, Serialize)]
pub(crate) struct DecodeSwapstringResponse {
pub(crate) qty_from: u64,
pub(crate) qty_to: u64,
pub(crate) from_asset: Option<String>,
pub(crate) to_asset: Option<String>,
pub(crate) expiry: u64,
pub(crate) payment_hash: String,
}

#[derive(Deserialize, Serialize)]
pub(crate) struct DisconnectPeerRequest {
pub(crate) peer_pubkey: String,
Expand Down Expand Up @@ -1736,6 +1751,23 @@ pub(crate) async fn decode_rgb_invoice(
}))
}

pub(crate) async fn decode_swapstring(
WithRejection(Json(payload), _): WithRejection<Json<DecodeSwapstringRequest>, APIError>,
) -> Result<Json<DecodeSwapstringResponse>, APIError> {
let swapstring = SwapString::from_str(&payload.swapstring)
.map_err(|e| APIError::InvalidSwapString(payload.swapstring, e.to_string()))?;
let swap_info = swapstring.swap_info;

Ok(Json(DecodeSwapstringResponse {
qty_from: swap_info.qty_from,
qty_to: swap_info.qty_to,
from_asset: swap_info.from_asset.map(|a| a.to_string()),
to_asset: swap_info.to_asset.map(|a| a.to_string()),
expiry: swap_info.expiry,
payment_hash: hex_str(&swapstring.payment_hash.0),
}))
}

pub(crate) async fn disconnect_peer(
State(state): State<Arc<AppState>>,
WithRejection(Json(payload), _): WithRejection<Json<DisconnectPeerRequest>, APIError>,
Expand Down
27 changes: 23 additions & 4 deletions src/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ use crate::routes::{
AssetUDA, Assignment, BackupRequest, BtcBalanceRequest, BtcBalanceResponse,
ChangePasswordRequest, Channel, CloseChannelRequest, ConnectPeerRequest, CreateUtxosRequest,
DecodeLNInvoiceRequest, DecodeLNInvoiceResponse, DecodeRGBInvoiceRequest,
DecodeRGBInvoiceResponse, DisconnectPeerRequest, EmptyResponse, FailTransfersRequest,
FailTransfersResponse, GetAssetMediaRequest, GetAssetMediaResponse, GetChannelIdRequest,
GetChannelIdResponse, GetPaymentRequest, GetPaymentResponse, GetSwapRequest, GetSwapResponse,
HTLCStatus, InflateRequest, InflateResponse, InitRequest, InitResponse, InvoiceStatus,
DecodeRGBInvoiceResponse, DecodeSwapstringRequest, DecodeSwapstringResponse,
DisconnectPeerRequest, EmptyResponse, FailTransfersRequest, FailTransfersResponse,
GetAssetMediaRequest, GetAssetMediaResponse, GetChannelIdRequest, GetChannelIdResponse,
GetPaymentRequest, GetPaymentResponse, GetSwapRequest, GetSwapResponse, HTLCStatus,
InflateRequest, InflateResponse, InitRequest, InitResponse, InvoiceStatus,
InvoiceStatusRequest, InvoiceStatusResponse, IssueAssetCFARequest, IssueAssetCFAResponse,
IssueAssetIFARequest, IssueAssetIFAResponse, IssueAssetNIARequest, IssueAssetNIAResponse,
IssueAssetUDARequest, IssueAssetUDAResponse, KeysendRequest, KeysendResponse, LNInvoiceRequest,
Expand Down Expand Up @@ -530,6 +531,24 @@ async fn decode_rgb_invoice(node_address: SocketAddr, invoice: &str) -> DecodeRG
.unwrap()
}

async fn decode_swapstring(node_address: SocketAddr, swapstring: &str) -> DecodeSwapstringResponse {
println!("decoding swapstring {swapstring} for node {node_address}");
let payload = DecodeSwapstringRequest {
swapstring: swapstring.to_string(),
};
let res = reqwest::Client::new()
.post(format!("http://{node_address}/decodeswapstring"))
.json(&payload)
.send()
.await
.unwrap();
check_response_is_ok(res)
.await
.json::<DecodeSwapstringResponse>()
.await
.unwrap()
}

async fn disconnect_peer(node_address: SocketAddr, peer_pubkey: &str) {
println!("disconnecting peer {peer_pubkey} from node {node_address}");
let payload = DisconnectPeerRequest {
Expand Down
30 changes: 30 additions & 0 deletions src/test/swap_roundtrip_assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,36 @@ async fn swap_roundtrip_assets() {
3600,
)
.await;
// check /decodeswapstring
let decoded_swapstring = decode_swapstring(maker_addr, &maker_init_response.swapstring).await;
assert_eq!(decoded_swapstring.qty_from, qty_from);
assert_eq!(decoded_swapstring.qty_to, qty_to);
assert_eq!(decoded_swapstring.from_asset, Some(asset_id_2.clone()));
assert_eq!(decoded_swapstring.to_asset, Some(asset_id_1.clone()));
assert!(decoded_swapstring.expiry > 0);
assert_eq!(
decoded_swapstring.payment_hash,
maker_init_response.payment_hash
);

// check /decodeswapstring invalid swapstring error
let payload = DecodeSwapstringRequest {
swapstring: s!("not_a_valid_swapstring"),
};
let res = reqwest::Client::new()
.post(format!("http://{maker_addr}/decodeswapstring"))
.json(&payload)
.send()
.await
.unwrap();
check_response_is_nok(
res,
reqwest::StatusCode::BAD_REQUEST,
"Invalid swap string 'not_a_valid_swapstring'",
"InvalidSwapString",
)
.await;

taker(taker_addr, maker_init_response.swapstring.clone()).await;

let swaps_maker = list_swaps(maker_addr).await;
Expand Down
Loading