@@ -15,7 +15,9 @@ use base58::FromBase58;
1515use clarity_repl:: clarity:: codec:: transaction:: TransactionPayload ;
1616use clarity_repl:: clarity:: codec:: { StacksMessageCodec , StacksTransaction } ;
1717use clarity_repl:: clarity:: representations:: ClarityName ;
18- use clarity_repl:: clarity:: types:: { BuffData , SequenceData , TupleData , Value as ClarityValue } ;
18+ use clarity_repl:: clarity:: types:: {
19+ AssetIdentifier , BuffData , SequenceData , TupleData , Value as ClarityValue ,
20+ } ;
1921use clarity_repl:: clarity:: util:: address:: AddressHashMode ;
2022use clarity_repl:: clarity:: util:: hash:: { hex_bytes, Hash160 } ;
2123use clarity_repl:: repl:: settings:: InitialContract ;
@@ -180,6 +182,12 @@ pub struct EventObserverConfig {
180182 pub deployer_nonce : u64 ,
181183}
182184
185+ #[ derive( Deserialize , Debug ) ]
186+ struct ContractReadonlyCall {
187+ okay : bool ,
188+ result : String ,
189+ }
190+
183191impl EventObserverConfig {
184192 pub fn new (
185193 devnet_config : DevnetConfig ,
@@ -433,9 +441,9 @@ pub fn handle_new_block(
433441 first_burnchain_block_height,
434442 prepare_phase_block_length,
435443 reward_phase_block_length,
436- node ,
444+ node_url ,
437445 ) = if let Ok ( config_reader) = config. read ( ) {
438- let node = format ! (
446+ let node_url = format ! (
439447 "http://localhost:{}" ,
440448 config_reader. devnet_config. stacks_node_rpc_port
441449 ) ;
@@ -460,7 +468,7 @@ pub fn handle_new_block(
460468 contracts_to_deploy. push ( contract) ;
461469 }
462470
463- let node_clone = node . clone ( ) ;
471+ let moved_node_url = node_url . clone ( ) ;
464472
465473 let mut deployers_lookup = BTreeMap :: new ( ) ;
466474 for account in updated_config. session . settings . initial_accounts . iter ( ) {
@@ -488,7 +496,7 @@ pub fn handle_new_block(
488496 & contract,
489497 & deployers_lookup,
490498 & mut deployers_nonces,
491- & node_clone ,
499+ & moved_node_url ,
492500 1 ,
493501 & Network :: Devnet ,
494502 ) {
@@ -510,15 +518,15 @@ pub fn handle_new_block(
510518 config_reader. pox_info . first_burnchain_block_height ,
511519 config_reader. pox_info . prepare_phase_block_length ,
512520 config_reader. pox_info . reward_phase_block_length ,
513- node ,
521+ node_url ,
514522 )
515523 } else {
516524 (
517525 None ,
518526 config_reader. pox_info . first_burnchain_block_height ,
519527 config_reader. pox_info . prepare_phase_block_length ,
520528 config_reader. pox_info . reward_phase_block_length ,
521- node ,
529+ node_url ,
522530 )
523531 }
524532 } else {
@@ -545,7 +553,11 @@ pub fn handle_new_block(
545553 transaction_identifier : TransactionIdentifier {
546554 hash : t. txid . clone ( ) ,
547555 } ,
548- operations : get_standardized_stacks_operations ( t, & mut asset_class_ids_map) ,
556+ operations : get_standardized_stacks_operations (
557+ t,
558+ & mut asset_class_ids_map,
559+ & node_url,
560+ ) ,
549561 metadata : StacksTransactionMetadata {
550562 success : t. status == "success" ,
551563 result : get_value_description ( & t. raw_result ) ,
@@ -597,7 +609,7 @@ pub fn handle_new_block(
597609
598610 let pox_stacking_orders = config_reader. devnet_config . pox_stacking_orders . clone ( ) ;
599611 std:: thread:: spawn ( move || {
600- let pox_url = format ! ( "{}/v2/pox" , node ) ;
612+ let pox_url = format ! ( "{}/v2/pox" , node_url ) ;
601613
602614 if let Ok ( reponse) = reqwest:: blocking:: get ( pox_url) {
603615 if let Ok ( update) = reponse. json ( ) {
@@ -611,7 +623,7 @@ pub fn handle_new_block(
611623 None => continue ,
612624 Some ( account) => account,
613625 } ;
614- let stacks_rpc = StacksRpc :: new ( node . clone ( ) ) ;
626+ let stacks_rpc = StacksRpc :: new ( node_url . clone ( ) ) ;
615627 let default_fee = 1000 ;
616628 let nonce = stacks_rpc
617629 . get_nonce ( account. address . to_string ( ) )
@@ -822,6 +834,7 @@ pub fn get_tx_description(raw_tx: &str) -> String {
822834fn get_standardized_stacks_operations (
823835 transaction : & NewTransaction ,
824836 asset_class_cache : & mut HashMap < String , AssetClassCache > ,
837+ node_url : & str ,
825838) -> Vec < Operation > {
826839 let mut operations = vec ! [ ] ;
827840 let mut operation_id = 0 ;
@@ -1042,6 +1055,7 @@ fn get_standardized_stacks_operations(
10421055 let currency = get_standardized_fungible_currency_from_asset_class_id (
10431056 & data. asset_class_identifier ,
10441057 asset_class_cache,
1058+ node_url,
10451059 ) ;
10461060 operations. push ( Operation {
10471061 operation_identifier : OperationIdentifier {
@@ -1068,6 +1082,7 @@ fn get_standardized_stacks_operations(
10681082 let currency = get_standardized_fungible_currency_from_asset_class_id (
10691083 & data. asset_class_identifier ,
10701084 asset_class_cache,
1085+ node_url,
10711086 ) ;
10721087 operations. push ( Operation {
10731088 operation_identifier : OperationIdentifier {
@@ -1094,6 +1109,7 @@ fn get_standardized_stacks_operations(
10941109 let currency = get_standardized_fungible_currency_from_asset_class_id (
10951110 & data. asset_class_identifier ,
10961111 asset_class_cache,
1112+ node_url,
10971113 ) ;
10981114 operations. push ( Operation {
10991115 operation_identifier : OperationIdentifier {
@@ -1155,13 +1171,81 @@ fn get_stacks_currency() -> Currency {
11551171fn get_standardized_fungible_currency_from_asset_class_id (
11561172 asset_class_id : & str ,
11571173 asset_class_cache : & mut HashMap < String , AssetClassCache > ,
1174+ node_url : & str ,
11581175) -> Currency {
11591176 match asset_class_cache. get ( asset_class_id) {
1160- None => Currency {
1161- symbol : asset_class_id. into ( ) ,
1162- decimals : 0 ,
1163- metadata : None ,
1164- } ,
1177+ None => {
1178+ let comps = asset_class_id. split ( "::" ) . collect :: < Vec < & str > > ( ) ;
1179+ let principal = comps[ 0 ] . split ( "." ) . collect :: < Vec < & str > > ( ) ;
1180+
1181+ let get_symbol_request_url = format ! (
1182+ "{}/v2/contracts/call-read/{}/{}/get-symbol" ,
1183+ node_url, principal[ 0 ] , principal[ 1 ] ,
1184+ ) ;
1185+
1186+ let symbol_res: ContractReadonlyCall = reqwest:: blocking:: get ( & get_symbol_request_url)
1187+ . expect ( "Unable to retrieve account" )
1188+ . json ( )
1189+ . expect ( "Unable to parse contract" ) ;
1190+
1191+ let raw_value = match symbol_res. result . strip_prefix ( "0x" ) {
1192+ Some ( raw_value) => raw_value,
1193+ _ => panic ! ( ) ,
1194+ } ;
1195+ let value_bytes = match hex_bytes ( & raw_value) {
1196+ Ok ( bytes) => bytes,
1197+ _ => panic ! ( ) ,
1198+ } ;
1199+
1200+ let symbol = match ClarityValue :: consensus_deserialize ( & mut Cursor :: new ( & value_bytes) ) {
1201+ Ok ( value) => value. expect_result_ok ( ) . expect_u128 ( ) ,
1202+ _ => panic ! ( ) ,
1203+ } ;
1204+
1205+ let get_decimals_request_url = format ! (
1206+ "{}/v2/contracts/call-read/{}/{}/get-decimals" ,
1207+ node_url, principal[ 0 ] , principal[ 1 ] ,
1208+ ) ;
1209+
1210+ let decimals_res: ContractReadonlyCall =
1211+ reqwest:: blocking:: get ( & get_decimals_request_url)
1212+ . expect ( "Unable to retrieve account" )
1213+ . json ( )
1214+ . expect ( "Unable to parse contract" ) ;
1215+
1216+ let raw_value = match decimals_res. result . strip_prefix ( "0x" ) {
1217+ Some ( raw_value) => raw_value,
1218+ _ => panic ! ( ) ,
1219+ } ;
1220+ let value_bytes = match hex_bytes ( & raw_value) {
1221+ Ok ( bytes) => bytes,
1222+ _ => panic ! ( ) ,
1223+ } ;
1224+
1225+ let value = match ClarityValue :: consensus_deserialize ( & mut Cursor :: new ( & value_bytes) ) {
1226+ Ok ( value) => value. expect_result_ok ( ) . expect_u128 ( ) ,
1227+ _ => panic ! ( ) ,
1228+ } ;
1229+
1230+ let entry = AssetClassCache {
1231+ symbol : format ! ( "{}" , symbol) ,
1232+ decimals : value as u8 ,
1233+ } ;
1234+
1235+ let currency = Currency {
1236+ symbol : entry. symbol . clone ( ) ,
1237+ decimals : entry. decimals . into ( ) ,
1238+ metadata : Some ( CurrencyMetadata {
1239+ asset_class_identifier : asset_class_id. into ( ) ,
1240+ asset_identifier : None ,
1241+ standard : CurrencyStandard :: Sip10 ,
1242+ } ) ,
1243+ } ;
1244+
1245+ asset_class_cache. insert ( asset_class_id. into ( ) , entry) ;
1246+
1247+ currency
1248+ }
11651249 Some ( entry) => Currency {
11661250 symbol : entry. symbol . clone ( ) ,
11671251 decimals : entry. decimals . into ( ) ,
@@ -1179,20 +1263,13 @@ fn get_standardized_non_fungible_currency_from_asset_class_id(
11791263 asset_id : & str ,
11801264 asset_class_cache : & mut HashMap < String , AssetClassCache > ,
11811265) -> Currency {
1182- match asset_class_cache. get ( asset_class_id) {
1183- None => Currency {
1184- symbol : asset_class_id. into ( ) ,
1185- decimals : 0 ,
1186- metadata : None ,
1187- } ,
1188- Some ( entry) => Currency {
1189- symbol : entry. symbol . clone ( ) ,
1190- decimals : 0 ,
1191- metadata : Some ( CurrencyMetadata {
1192- asset_class_identifier : asset_class_id. into ( ) ,
1193- asset_identifier : Some ( asset_id. into ( ) ) ,
1194- standard : CurrencyStandard :: Sip10 ,
1195- } ) ,
1196- } ,
1266+ Currency {
1267+ symbol : asset_class_id. into ( ) ,
1268+ decimals : 0 ,
1269+ metadata : Some ( CurrencyMetadata {
1270+ asset_class_identifier : asset_class_id. into ( ) ,
1271+ asset_identifier : Some ( asset_id. into ( ) ) ,
1272+ standard : CurrencyStandard :: Sip09 ,
1273+ } ) ,
11971274 }
11981275}
0 commit comments