Skip to content

Commit 8694898

Browse files
committed
feat: add api to decode a swapstring
1 parent 02aa662 commit 8694898

7 files changed

Lines changed: 153 additions & 13 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ The node currently exposes the following APIs:
211211
- `/createutxos` (POST)
212212
- `/decodelninvoice` (POST)
213213
- `/decodergbinvoice` (POST)
214+
- `/decodeswapstring` (POST)
214215
- `/disconnectpeer` (POST)
215216
- `/estimatefee` (POST)
216217
- `/failtransfers` (POST)

openapi.yaml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,24 @@ paths:
259259
application/json:
260260
schema:
261261
$ref: '#/components/schemas/DecodeRGBInvoiceResponse'
262+
/decodeswapstring:
263+
post:
264+
tags:
265+
- Swaps
266+
summary: Decode a swapstring
267+
description: Decode the provided swapstring
268+
requestBody:
269+
content:
270+
application/json:
271+
schema:
272+
$ref: '#/components/schemas/DecodeSwapstringRequest'
273+
responses:
274+
'200':
275+
description: Successful operation
276+
content:
277+
application/json:
278+
schema:
279+
$ref: '#/components/schemas/DecodeSwapstringResponse'
262280
/disconnectpeer:
263281
post:
264282
tags:
@@ -1690,6 +1708,44 @@ components:
16901708
items:
16911709
type: string
16921710
example: rpcs://proxy.iriswallet.com/0.2/json-rpc
1711+
DecodeSwapstringRequest:
1712+
type: object
1713+
required:
1714+
- swapstring
1715+
properties:
1716+
swapstring:
1717+
type: string
1718+
example: 30/rgb:CJkb4YZw-jRiz2sk-~PARPio-wtVYI1c-XAEYCqO-wTfvRZ8/10/rgb:icfqnK9y-wObZKTu-XJcDL98-sKbE5Mh-OuDJhiI-brRJrzE/1715896416/9d342c6ba006e24abee84a2e034a22d5e30c1f2599fb9c3574d46d3cde3d65a2
1719+
DecodeSwapstringResponse:
1720+
type: object
1721+
required:
1722+
- qty_from
1723+
- qty_to
1724+
- expiry
1725+
- payment_hash
1726+
properties:
1727+
qty_from:
1728+
type: integer
1729+
example: 30
1730+
qty_to:
1731+
type: integer
1732+
example: 10
1733+
from_asset:
1734+
type:
1735+
- string
1736+
- 'null'
1737+
example: rgb:CJkb4YZw-jRiz2sk-~PARPio-wtVYI1c-XAEYCqO-wTfvRZ8
1738+
to_asset:
1739+
type:
1740+
- string
1741+
- 'null'
1742+
example: rgb:icfqnK9y-wObZKTu-XJcDL98-sKbE5Mh-OuDJhiI-brRJrzE
1743+
expiry:
1744+
type: integer
1745+
example: 1715896416
1746+
payment_hash:
1747+
type: string
1748+
example: 9d342c6ba006e24abee84a2e034a22d5e30c1f2599fb9c3574d46d3cde3d65a2
16931749
DisconnectPeerRequest:
16941750
type: object
16951751
required:

src/auth.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ use crate::{
1616

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

19-
const READ_ONLY_OPS: [&str; 23] = [
19+
const READ_ONLY_OPS: [&str; 24] = [
2020
"/assetbalance",
2121
"/assetmetadata",
2222
"/btcbalance",
2323
"/checkindexerurl",
2424
"/checkproxyendpoint",
2525
"/decodelninvoice",
2626
"/decodergbinvoice",
27+
"/decodeswapstring",
2728
"/estimatefee",
2829
"/getassetmedia",
2930
"/getchannelid",

src/main.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ use crate::ldk::stop_ldk;
4444
use crate::routes::{
4545
address, asset_balance, asset_metadata, backup, btc_balance, change_password,
4646
check_indexer_url, check_proxy_endpoint, close_channel, connect_peer, create_utxos,
47-
decode_ln_invoice, decode_rgb_invoice, disconnect_peer, estimate_fee, fail_transfers,
48-
get_asset_media, get_channel_id, get_payment, get_swap, inflate, init, invoice_status,
49-
issue_asset_cfa, issue_asset_ifa, issue_asset_nia, issue_asset_uda, keysend, list_assets,
50-
list_channels, list_payments, list_peers, list_swaps, list_transactions, list_transfers,
51-
list_unspents, ln_invoice, lock, maker_execute, maker_init, network_info, node_info,
52-
open_channel, post_asset_media, refresh_transfers, restore, revoke_token, rgb_invoice,
53-
send_btc, send_onion_message, send_payment, send_rgb, shutdown, sign_message, sync, taker,
54-
unlock,
47+
decode_ln_invoice, decode_rgb_invoice, decode_swapstring, disconnect_peer, estimate_fee,
48+
fail_transfers, get_asset_media, get_channel_id, get_payment, get_swap, inflate, init,
49+
invoice_status, issue_asset_cfa, issue_asset_ifa, issue_asset_nia, issue_asset_uda, keysend,
50+
list_assets, list_channels, list_payments, list_peers, list_swaps, list_transactions,
51+
list_transfers, list_unspents, ln_invoice, lock, maker_execute, maker_init, network_info,
52+
node_info, open_channel, post_asset_media, refresh_transfers, restore, revoke_token,
53+
rgb_invoice, send_btc, send_onion_message, send_payment, send_rgb, shutdown, sign_message,
54+
sync, taker, unlock,
5555
};
5656
use crate::utils::{start_daemon, AppState, LOGS_DIR};
5757

@@ -118,6 +118,7 @@ pub(crate) async fn app(args: UserArgs) -> Result<(Router, Arc<AppState>), AppEr
118118
.route("/createutxos", post(create_utxos))
119119
.route("/decodelninvoice", post(decode_ln_invoice))
120120
.route("/decodergbinvoice", post(decode_rgb_invoice))
121+
.route("/decodeswapstring", post(decode_swapstring))
121122
.route("/disconnectpeer", post(disconnect_peer))
122123
.route("/estimatefee", post(estimate_fee))
123124
.route("/failtransfers", post(fail_transfers))

src/routes.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,21 @@ pub(crate) struct DecodeRGBInvoiceResponse {
521521
pub(crate) transport_endpoints: Vec<String>,
522522
}
523523

524+
#[derive(Deserialize, Serialize)]
525+
pub(crate) struct DecodeSwapstringRequest {
526+
pub(crate) swapstring: String,
527+
}
528+
529+
#[derive(Deserialize, Serialize)]
530+
pub(crate) struct DecodeSwapstringResponse {
531+
pub(crate) qty_from: u64,
532+
pub(crate) qty_to: u64,
533+
pub(crate) from_asset: Option<String>,
534+
pub(crate) to_asset: Option<String>,
535+
pub(crate) expiry: u64,
536+
pub(crate) payment_hash: String,
537+
}
538+
524539
#[derive(Deserialize, Serialize)]
525540
pub(crate) struct DisconnectPeerRequest {
526541
pub(crate) peer_pubkey: String,
@@ -1736,6 +1751,23 @@ pub(crate) async fn decode_rgb_invoice(
17361751
}))
17371752
}
17381753

1754+
pub(crate) async fn decode_swapstring(
1755+
WithRejection(Json(payload), _): WithRejection<Json<DecodeSwapstringRequest>, APIError>,
1756+
) -> Result<Json<DecodeSwapstringResponse>, APIError> {
1757+
let swapstring = SwapString::from_str(&payload.swapstring)
1758+
.map_err(|e| APIError::InvalidSwapString(payload.swapstring, e.to_string()))?;
1759+
let swap_info = swapstring.swap_info;
1760+
1761+
Ok(Json(DecodeSwapstringResponse {
1762+
qty_from: swap_info.qty_from,
1763+
qty_to: swap_info.qty_to,
1764+
from_asset: swap_info.from_asset.map(|a| a.to_string()),
1765+
to_asset: swap_info.to_asset.map(|a| a.to_string()),
1766+
expiry: swap_info.expiry,
1767+
payment_hash: hex_str(&swapstring.payment_hash.0),
1768+
}))
1769+
}
1770+
17391771
pub(crate) async fn disconnect_peer(
17401772
State(state): State<Arc<AppState>>,
17411773
WithRejection(Json(payload), _): WithRejection<Json<DisconnectPeerRequest>, APIError>,

src/test/mod.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ use crate::routes::{
3434
AssetUDA, Assignment, BackupRequest, BtcBalanceRequest, BtcBalanceResponse,
3535
ChangePasswordRequest, Channel, CloseChannelRequest, ConnectPeerRequest, CreateUtxosRequest,
3636
DecodeLNInvoiceRequest, DecodeLNInvoiceResponse, DecodeRGBInvoiceRequest,
37-
DecodeRGBInvoiceResponse, DisconnectPeerRequest, EmptyResponse, FailTransfersRequest,
38-
FailTransfersResponse, GetAssetMediaRequest, GetAssetMediaResponse, GetChannelIdRequest,
39-
GetChannelIdResponse, GetPaymentRequest, GetPaymentResponse, GetSwapRequest, GetSwapResponse,
40-
HTLCStatus, InflateRequest, InflateResponse, InitRequest, InitResponse, InvoiceStatus,
37+
DecodeRGBInvoiceResponse, DecodeSwapstringRequest, DecodeSwapstringResponse,
38+
DisconnectPeerRequest, EmptyResponse, FailTransfersRequest, FailTransfersResponse,
39+
GetAssetMediaRequest, GetAssetMediaResponse, GetChannelIdRequest, GetChannelIdResponse,
40+
GetPaymentRequest, GetPaymentResponse, GetSwapRequest, GetSwapResponse, HTLCStatus,
41+
InflateRequest, InflateResponse, InitRequest, InitResponse, InvoiceStatus,
4142
InvoiceStatusRequest, InvoiceStatusResponse, IssueAssetCFARequest, IssueAssetCFAResponse,
4243
IssueAssetIFARequest, IssueAssetIFAResponse, IssueAssetNIARequest, IssueAssetNIAResponse,
4344
IssueAssetUDARequest, IssueAssetUDAResponse, KeysendRequest, KeysendResponse, LNInvoiceRequest,
@@ -530,6 +531,24 @@ async fn decode_rgb_invoice(node_address: SocketAddr, invoice: &str) -> DecodeRG
530531
.unwrap()
531532
}
532533

534+
async fn decode_swapstring(node_address: SocketAddr, swapstring: &str) -> DecodeSwapstringResponse {
535+
println!("decoding swapstring {swapstring} for node {node_address}");
536+
let payload = DecodeSwapstringRequest {
537+
swapstring: swapstring.to_string(),
538+
};
539+
let res = reqwest::Client::new()
540+
.post(format!("http://{node_address}/decodeswapstring"))
541+
.json(&payload)
542+
.send()
543+
.await
544+
.unwrap();
545+
check_response_is_ok(res)
546+
.await
547+
.json::<DecodeSwapstringResponse>()
548+
.await
549+
.unwrap()
550+
}
551+
533552
async fn disconnect_peer(node_address: SocketAddr, peer_pubkey: &str) {
534553
println!("disconnecting peer {peer_pubkey} from node {node_address}");
535554
let payload = DisconnectPeerRequest {

src/test/swap_roundtrip_assets.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,36 @@ async fn swap_roundtrip_assets() {
8181
3600,
8282
)
8383
.await;
84+
// check /decodeswapstring
85+
let decoded_swapstring = decode_swapstring(maker_addr, &maker_init_response.swapstring).await;
86+
assert_eq!(decoded_swapstring.qty_from, qty_from);
87+
assert_eq!(decoded_swapstring.qty_to, qty_to);
88+
assert_eq!(decoded_swapstring.from_asset, Some(asset_id_2.clone()));
89+
assert_eq!(decoded_swapstring.to_asset, Some(asset_id_1.clone()));
90+
assert!(decoded_swapstring.expiry > 0);
91+
assert_eq!(
92+
decoded_swapstring.payment_hash,
93+
maker_init_response.payment_hash
94+
);
95+
96+
// check /decodeswapstring invalid swapstring error
97+
let payload = DecodeSwapstringRequest {
98+
swapstring: s!("not_a_valid_swapstring"),
99+
};
100+
let res = reqwest::Client::new()
101+
.post(format!("http://{maker_addr}/decodeswapstring"))
102+
.json(&payload)
103+
.send()
104+
.await
105+
.unwrap();
106+
check_response_is_nok(
107+
res,
108+
reqwest::StatusCode::BAD_REQUEST,
109+
"Invalid swap string 'not_a_valid_swapstring'",
110+
"InvalidSwapString",
111+
)
112+
.await;
113+
84114
taker(taker_addr, maker_init_response.swapstring.clone()).await;
85115

86116
let swaps_maker = list_swaps(maker_addr).await;

0 commit comments

Comments
 (0)