Skip to content

Commit 4c0ec79

Browse files
committed
Fix address display in positions
1 parent c2f3ca4 commit 4c0ec79

File tree

1 file changed

+73
-31
lines changed

1 file changed

+73
-31
lines changed

crates/cli-client/src/cli/positions.rs

Lines changed: 73 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ use crate::error::Error;
99
use crate::metadata::ContractMetadata;
1010

1111
use coin_store::{Store, UtxoEntry, UtxoFilter, UtxoQueryResult, UtxoStore};
12-
use contracts::options::{OPTION_SOURCE, OptionsArguments};
12+
use contracts::options::{OPTION_SOURCE, OptionsArguments, get_options_address};
13+
use contracts::sdk::taproot_pubkey_gen::TaprootPubkeyGen;
1314
use contracts::swap_with_change::{SWAP_WITH_CHANGE_SOURCE, SwapWithChangeArguments};
15+
use simplicityhl::elements::Address;
1416

1517
/// Result type for contract info queries: (metadata, arguments, `taproot_pubkey_gen`)
1618
type ContractInfoResult = Result<Option<(Vec<u8>, Vec<u8>, String)>, coin_store::StoreError>;
@@ -29,7 +31,7 @@ impl Cli {
2931
let options_results = <_ as UtxoStore>::query_utxos(wallet.store(), &[options_filter]).await?;
3032
let option_entries = extract_entries(options_results);
3133

32-
let collateral_displays = build_collateral_displays(&wallet, &option_entries).await;
34+
let collateral_displays = build_collateral_displays(&wallet, &option_entries, config.address_params()).await;
3335

3436
println!("Option Contract Locked Assets:");
3537
println!("------------------------------");
@@ -39,7 +41,7 @@ impl Cli {
3941
let option_tokens = get_option_tokens_from_wallet(&wallet, OPTION_SOURCE, &user_script_pubkey).await?;
4042
let grantor_tokens = get_grantor_tokens_from_wallet(&wallet, OPTION_SOURCE, &user_script_pubkey).await?;
4143

42-
let user_token_displays = build_user_token_displays(&option_tokens, &grantor_tokens);
44+
let user_token_displays = build_user_token_displays(&option_tokens, &grantor_tokens, config.address_params());
4345

4446
println!("Your Option/Grantor Tokens:");
4547
println!("---------------------------");
@@ -65,33 +67,64 @@ impl Cli {
6567
let swap_contracts =
6668
<_ as UtxoStore>::list_contracts_by_source_with_metadata(wallet.store(), SWAP_WITH_CHANGE_SOURCE).await?;
6769

68-
let mut contracts_with_history: Vec<(&str, &str, ContractMetadata, i64)> = Vec::new();
70+
let mut contracts_with_history: Vec<(&str, Address, ContractMetadata, i64)> = Vec::new();
6971

70-
for (_args_bytes, tpg_str, metadata_bytes) in &option_contracts {
72+
for (args_bytes, tpg_str, metadata_bytes) in &option_contracts {
7173
if let Some(bytes) = metadata_bytes
7274
&& let Ok(metadata) = ContractMetadata::from_bytes(bytes)
7375
&& !metadata.history.is_empty()
7476
{
77+
let Ok((args, _)) = bincode::serde::decode_from_slice::<simplicityhl::Arguments, _>(
78+
args_bytes,
79+
bincode::config::standard(),
80+
) else {
81+
continue;
82+
};
83+
let Ok(opt_args) = OptionsArguments::from_arguments(&args) else {
84+
continue;
85+
};
86+
let Ok(tpg) =
87+
TaprootPubkeyGen::build_from_str(tpg_str, &opt_args, config.address_params(), &get_options_address)
88+
else {
89+
continue;
90+
};
7591
let most_recent = metadata.history.iter().map(|h| h.timestamp).max().unwrap_or(0);
76-
contracts_with_history.push(("Option", tpg_str, metadata, most_recent));
92+
contracts_with_history.push(("Option", tpg.address, metadata, most_recent));
7793
}
7894
}
7995

80-
for (_args_bytes, tpg_str, metadata_bytes) in &swap_contracts {
96+
for (args_bytes, tpg_str, metadata_bytes) in &swap_contracts {
8197
if let Some(bytes) = metadata_bytes
8298
&& let Ok(metadata) = ContractMetadata::from_bytes(bytes)
8399
&& !metadata.history.is_empty()
84100
{
101+
let Ok((args, _)) = bincode::serde::decode_from_slice::<simplicityhl::Arguments, _>(
102+
args_bytes,
103+
bincode::config::standard(),
104+
) else {
105+
continue;
106+
};
107+
let Ok(swap_args) = SwapWithChangeArguments::from_arguments(&args) else {
108+
continue;
109+
};
110+
let Ok(tpg) = TaprootPubkeyGen::build_from_str(
111+
tpg_str,
112+
&swap_args,
113+
config.address_params(),
114+
&contracts::swap_with_change::get_swap_with_change_address,
115+
) else {
116+
continue;
117+
};
85118
let most_recent = metadata.history.iter().map(|h| h.timestamp).max().unwrap_or(0);
86-
contracts_with_history.push(("Swap", tpg_str, metadata, most_recent));
119+
contracts_with_history.push(("Swap", tpg.address, metadata, most_recent));
87120
}
88121
}
89122

90123
contracts_with_history.sort_by(|a, b| b.3.cmp(&a.3));
91124

92-
for (contract_type, tpg_str, metadata, _) in &contracts_with_history {
93-
let short_tpg = truncate_id(tpg_str);
94-
println!("\n {contract_type} Contract {short_tpg}:");
125+
for (contract_type, address, metadata, _) in &contracts_with_history {
126+
let short_addr = format_contract_address(address);
127+
println!("\n {contract_type} Contract {short_addr}:");
95128
for entry in &metadata.history {
96129
let time_str = format_time_ago(entry.timestamp);
97130
let txid_str = entry.txid.as_deref().map_or("N/A", |t| &t[..t.len().min(12)]);
@@ -175,7 +208,11 @@ fn display_user_token_table(displays: &[UserTokenDisplay]) {
175208
}
176209

177210
/// Build locked asset displays, filtering to only show collateral or settlement assets (not reissuance tokens)
178-
async fn build_collateral_displays(wallet: &crate::wallet::Wallet, entries: &[UtxoEntry]) -> Vec<CollateralDisplay> {
211+
async fn build_collateral_displays(
212+
wallet: &crate::wallet::Wallet,
213+
entries: &[UtxoEntry],
214+
address_params: &'static simplicityhl::elements::AddressParams,
215+
) -> Vec<CollateralDisplay> {
179216
let mut displays = Vec::new();
180217
let mut display_idx = 0;
181218

@@ -184,7 +221,7 @@ async fn build_collateral_displays(wallet: &crate::wallet::Wallet, entries: &[Ut
184221
let contract_info = <_ as UtxoStore>::get_contract_by_script_pubkey(wallet.store(), &script_pubkey).await;
185222

186223
// Try to get option arguments to check if this is collateral
187-
let Some(info) = extract_collateral_info(wallet.store(), contract_info, entry).await else {
224+
let Some(info) = extract_collateral_info(wallet.store(), contract_info, entry, address_params).await else {
188225
continue;
189226
};
190227

@@ -206,8 +243,9 @@ async fn extract_collateral_info(
206243
store: &Store,
207244
contract_info: ContractInfoResult,
208245
entry: &UtxoEntry,
246+
address_params: &'static simplicityhl::elements::AddressParams,
209247
) -> Option<(String, String, String, String)> {
210-
let (_metadata, args_bytes, tpg) = contract_info.ok().flatten()?;
248+
let (_metadata, args_bytes, tpg_str) = contract_info.ok().flatten()?;
211249

212250
let (args, _) =
213251
bincode::serde::decode_from_slice::<simplicityhl::Arguments, _>(&args_bytes, bincode::config::standard())
@@ -222,10 +260,12 @@ async fn extract_collateral_info(
222260
return None;
223261
}
224262

263+
let tpg = TaprootPubkeyGen::build_from_str(&tpg_str, &opt_args, address_params, &get_options_address).ok()?;
264+
225265
let locked_str = format_asset_value_with_tag(store, entry.value(), entry.asset()).await;
226266
let settlement_str = format_asset_with_tag(store, &opt_args.get_settlement_asset_id()).await;
227267
let expiry_str = format_relative_time(i64::from(opt_args.expiry_time()));
228-
let contract_str = truncate_id(&tpg);
268+
let contract_str = format_contract_address(&tpg.address);
229269

230270
Some((locked_str, settlement_str, expiry_str, contract_str))
231271
}
@@ -234,6 +274,7 @@ async fn extract_collateral_info(
234274
fn build_user_token_displays(
235275
option_tokens: &[EnrichedTokenEntry],
236276
grantor_tokens: &[EnrichedTokenEntry],
277+
address_params: &'static simplicityhl::elements::AddressParams,
237278
) -> Vec<UserTokenDisplay> {
238279
let mut displays = Vec::new();
239280
let mut idx = 0;
@@ -245,11 +286,13 @@ fn build_user_token_displays(
245286
let settlement_per_contract = entry.option_arguments.settlement_per_contract();
246287
let expiry_time = entry.option_arguments.expiry_time();
247288

248-
let contract_addr = entry
249-
.taproot_pubkey_gen_str
250-
.split(':')
251-
.next_back()
252-
.map_or_else(|| "???".to_string(), |s| truncate_with_ellipsis(s, 12));
289+
let contract_addr = TaprootPubkeyGen::build_from_str(
290+
&entry.taproot_pubkey_gen_str,
291+
&entry.option_arguments,
292+
address_params,
293+
&get_options_address,
294+
)
295+
.map_or_else(|_| "???".to_string(), |tpg| format_contract_address(&tpg.address));
253296

254297
displays.push(UserTokenDisplay {
255298
index: idx,
@@ -272,11 +315,13 @@ fn build_user_token_displays(
272315
let settlement_per_contract = entry.option_arguments.settlement_per_contract();
273316
let expiry_time = entry.option_arguments.expiry_time();
274317

275-
let contract_addr = entry
276-
.taproot_pubkey_gen_str
277-
.split(':')
278-
.next_back()
279-
.map_or_else(|| "???".to_string(), |s| truncate_with_ellipsis(s, 12));
318+
let contract_addr = TaprootPubkeyGen::build_from_str(
319+
&entry.taproot_pubkey_gen_str,
320+
&entry.option_arguments,
321+
address_params,
322+
&get_options_address,
323+
)
324+
.map_or_else(|_| "???".to_string(), |tpg| format_contract_address(&tpg.address));
280325

281326
displays.push(UserTokenDisplay {
282327
index: idx,
@@ -352,10 +397,7 @@ async fn extract_swap_display_info_with_tags(
352397
Some((settlement_str, expiry_str, is_collateral, price))
353398
}
354399

355-
fn truncate_id(s: &str) -> String {
356-
if s.len() > 12 {
357-
format!("{}...", &s[..12])
358-
} else {
359-
s.to_string()
360-
}
400+
/// Format a contract address for display by truncating the bech32 address.
401+
fn format_contract_address(address: &Address) -> String {
402+
truncate_with_ellipsis(&address.to_string(), 12)
361403
}

0 commit comments

Comments
 (0)