@@ -231,6 +231,9 @@ impl Session {
231231 cmd if cmd. starts_with ( "::set_epoch" ) => self . set_epoch ( cmd) ,
232232 cmd if cmd. starts_with ( "::encode" ) => self . encode ( cmd) ,
233233 cmd if cmd. starts_with ( "::decode" ) => self . decode ( cmd) ,
234+ cmd if cmd. starts_with ( "::get_constant" ) => self . get_constant ( cmd) ,
235+ cmd if cmd. starts_with ( "::get_data_var" ) => self . get_data_var ( cmd) ,
236+ cmd if cmd. starts_with ( "::get_map_val" ) => self . get_map_val ( cmd) ,
234237
235238 _ => "Invalid command. Try `::help`" . yellow ( ) . to_string ( ) ,
236239 }
@@ -857,6 +860,18 @@ impl Session {
857860 "{}" ,
858861 "::decode <bytes>\t \t \t Decode a Clarity Value bytes representation" . yellow( )
859862 ) ) ;
863+ output. push ( format ! (
864+ "{}" ,
865+ "::get_constant <contract> <constant>\t Get constant value from a contract" . yellow( )
866+ ) ) ;
867+ output. push ( format ! (
868+ "{}" ,
869+ "::get_data_var <contract> <var>\t \t Get data variable value from a contract" . yellow( )
870+ ) ) ;
871+ output. push ( format ! (
872+ "{}" ,
873+ "::get_map_val <contract> <map> <key>\t Get map value from a contract" . yellow( )
874+ ) ) ;
860875
861876 output. join ( "\n " )
862877 }
@@ -1090,6 +1105,168 @@ impl Session {
10901105 format ! ( "{}" , value_to_string( & value) . green( ) )
10911106 }
10921107
1108+ pub fn get_constant ( & mut self , cmd : & str ) -> String {
1109+ let args: Vec < _ > = cmd. split_whitespace ( ) . skip ( 1 ) . collect ( ) ;
1110+
1111+ if args. len ( ) != 2 {
1112+ return format ! ( "{}" , "Usage: ::get_constant <contract> <constant>" . red( ) ) ;
1113+ }
1114+
1115+ let contract_name = args[ 0 ] ;
1116+ let constant_name = args[ 1 ] ;
1117+
1118+ let default_deployer = self . settings . initial_deployer . as_ref ( )
1119+ . map ( |account| account. address . clone ( ) )
1120+ . unwrap_or_else ( || "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM" . to_string ( ) ) ;
1121+
1122+ let contract_id = match Self :: desugar_contract_id ( & default_deployer, contract_name) {
1123+ Ok ( id) => id,
1124+ Err ( e) => return format ! ( "{} {}" , "Invalid contract identifier:" . red( ) , e) ,
1125+ } ;
1126+
1127+ let contract = match self . contracts . get ( & contract_id) {
1128+ Some ( contract) => contract,
1129+ None => return format ! ( "{} {}" , "Contract not found:" . red( ) , contract_id) ,
1130+ } ;
1131+
1132+ // Search for constant in the contract's AST
1133+ for function_definition in & contract. ast . expressions {
1134+ if let Some ( expr) = function_definition. match_list ( ) {
1135+ if expr. len ( ) >= 3 {
1136+ if let Some ( name_expr) = expr. get ( 1 ) {
1137+ if let Some ( name) = name_expr. match_atom ( ) {
1138+ if name. as_str ( ) == constant_name && expr. len ( ) >= 3 {
1139+ let expr_str = format ! ( "{}" , expr[ 2 ] ) ;
1140+ return format ! ( "{} {}\n {} {}\n {} {}" ,
1141+ "Contract:" . yellow( ) ,
1142+ contract_id. to_string( ) . green( ) ,
1143+ "Constant:" . yellow( ) ,
1144+ name. green( ) ,
1145+ "Value:" . yellow( ) ,
1146+ expr_str. green( )
1147+ ) ;
1148+ }
1149+ }
1150+ }
1151+ }
1152+ }
1153+ }
1154+
1155+ format ! ( "{} {} {} {}" ,
1156+ "Constant:" . red( ) ,
1157+ constant_name. red( ) ,
1158+ "not found in contract:" . red( ) ,
1159+ contract_id. to_string( ) . red( )
1160+ )
1161+ }
1162+
1163+ pub fn get_data_var ( & mut self , cmd : & str ) -> String {
1164+ let args: Vec < _ > = cmd. split_whitespace ( ) . skip ( 1 ) . collect ( ) ;
1165+
1166+ if args. len ( ) != 2 {
1167+ return format ! ( "{}" , "Usage: ::get_data_var <contract> <var>" . red( ) ) ;
1168+ }
1169+
1170+ let contract_name = args[ 0 ] ;
1171+ let var_name = args[ 1 ] ;
1172+
1173+ let default_deployer = self . settings . initial_deployer . as_ref ( )
1174+ . map ( |account| account. address . clone ( ) )
1175+ . unwrap_or_else ( || "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM" . to_string ( ) ) ;
1176+
1177+ let contract_id = match Self :: desugar_contract_id ( & default_deployer, contract_name) {
1178+ Ok ( id) => id,
1179+ Err ( e) => return format ! ( "{} {}" , "Invalid contract identifier:" . red( ) , e) ,
1180+ } ;
1181+
1182+ let call_expr = format ! ( "(contract-call? '{}.{} var-get {})" ,
1183+ contract_id. name, contract_id. issuer, var_name) ;
1184+
1185+ match self . eval_with_hooks ( call_expr, None , false ) {
1186+ Ok ( result) => {
1187+ match & result. result {
1188+ EvaluationResult :: Snippet ( snippet_result) => {
1189+ format ! ( "{} {}\n {} {}\n {} {}" ,
1190+ "Contract:" . yellow( ) ,
1191+ contract_id. to_string( ) . green( ) ,
1192+ "Data var:" . yellow( ) ,
1193+ var_name. green( ) ,
1194+ "Value:" . yellow( ) ,
1195+ value_to_string( & snippet_result. result) . green( )
1196+ )
1197+ }
1198+ _ => format ! ( "{} {} {} {}" ,
1199+ "Unable to retrieve data var:" . red( ) ,
1200+ var_name. red( ) ,
1201+ "from contract:" . red( ) ,
1202+ contract_id. to_string( ) . red( )
1203+ )
1204+ }
1205+ }
1206+ Err ( diagnostics) => {
1207+ let error_msg = diagnostics. first ( )
1208+ . map ( |d| d. message . as_str ( ) )
1209+ . unwrap_or ( "Unknown error" ) ;
1210+ format ! ( "{} {}" , error_msg. red( ) , contract_id. to_string( ) . red( ) )
1211+ }
1212+ }
1213+ }
1214+
1215+ pub fn get_map_val ( & mut self , cmd : & str ) -> String {
1216+ let args: Vec < _ > = cmd. split_whitespace ( ) . skip ( 1 ) . collect ( ) ;
1217+
1218+ if args. len ( ) < 3 {
1219+ return format ! ( "{}" , "Usage: ::get_map_val <contract> <map> <key>" . red( ) ) ;
1220+ }
1221+
1222+ let contract_name = args[ 0 ] ;
1223+ let map_name = args[ 1 ] ;
1224+ let key_expr = args[ 2 ..] . join ( " " ) ;
1225+
1226+ let default_deployer = self . settings . initial_deployer . as_ref ( )
1227+ . map ( |account| account. address . clone ( ) )
1228+ . unwrap_or_else ( || "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM" . to_string ( ) ) ;
1229+
1230+ let contract_id = match Self :: desugar_contract_id ( & default_deployer, contract_name) {
1231+ Ok ( id) => id,
1232+ Err ( e) => return format ! ( "{} {}" , "Invalid contract identifier:" . red( ) , e) ,
1233+ } ;
1234+
1235+ let call_expr = format ! ( "(contract-call? '{}.{} map-get {} {})" ,
1236+ contract_id. name, contract_id. issuer, map_name, key_expr) ;
1237+
1238+ match self . eval_with_hooks ( call_expr, None , false ) {
1239+ Ok ( result) => {
1240+ match & result. result {
1241+ EvaluationResult :: Snippet ( snippet_result) => {
1242+ format ! ( "{} {}\n {} {}\n {} {}\n {} {}" ,
1243+ "Contract:" . yellow( ) ,
1244+ contract_id. to_string( ) . green( ) ,
1245+ "Map:" . yellow( ) ,
1246+ map_name. green( ) ,
1247+ "Key:" . yellow( ) ,
1248+ key_expr. green( ) ,
1249+ "Value:" . yellow( ) ,
1250+ value_to_string( & snippet_result. result) . green( )
1251+ )
1252+ }
1253+ _ => format ! ( "{} {} {} {}" ,
1254+ "Unable to retrieve map value:" . red( ) ,
1255+ map_name. red( ) ,
1256+ "from contract:" . red( ) ,
1257+ contract_id. to_string( ) . red( )
1258+ )
1259+ }
1260+ }
1261+ Err ( diagnostics) => {
1262+ let error_msg = diagnostics. first ( )
1263+ . map ( |d| d. message . as_str ( ) )
1264+ . unwrap_or ( "Unknown error" ) ;
1265+ format ! ( "{} {}" , error_msg. red( ) , contract_id. to_string( ) . red( ) )
1266+ }
1267+ }
1268+ }
1269+
10931270 #[ cfg( not( target_arch = "wasm32" ) ) ]
10941271 pub fn get_costs ( & mut self , output : & mut Vec < String > , cmd : & str ) {
10951272 let Some ( ( _, expr) ) = cmd. split_once ( ' ' ) else {
0 commit comments