@@ -103,19 +103,28 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
103103 . send ( )
104104 . await ?
105105 . error_for_status ( ) ?
106- . json :: < Vec < Keys > > ( )
106+ . json :: < Vec < Key > > ( )
107107 . await ?;
108108 let _ = term. clear_screen ( ) ;
109109 term. flush ( ) ?;
110110 let mut clipboard = Clipboard :: new ( ) ?;
111111 if api_keys. is_empty ( ) {
112- let new_key = client
113- . post ( "https://api.cloud.developerdao.com/api/keys" )
114- . send ( )
115- . await ?
116- . error_for_status ( ) ?
117- . text ( )
118- . await ?;
112+ let new_key = Key {
113+ apikey : client
114+ . post ( "https://api.cloud.developerdao.com/api/keys" )
115+ . send ( )
116+ . await ?
117+ . error_for_status ( ) ?
118+ . text ( )
119+ . await ?,
120+ } ;
121+
122+ let redacted_key = new_key. as_redacted ( ) ;
123+ let redacted_ep = format ! (
124+ "https://api.cloud.developerdao.com/rpc/{}/{}" ,
125+ CHAINS [ chain] . id( ) ,
126+ redacted_key
127+ ) ;
119128
120129 let endpoint = format ! (
121130 "https://api.cloud.developerdao.com/rpc/{}/{}" ,
@@ -125,23 +134,35 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
125134
126135 clipboard. set_text ( & endpoint) ?;
127136 println ! ( "\n Your RPC Endpoint for {}:\n " , CHAINS [ chain] ) ;
128- println ! ( "\n {endpoint }\n " ) ;
137+ println ! ( "\n {redacted_ep }\n " ) ;
129138 println ! ( "\n Your API key is now copied to your clipboard" ) ;
130139 } else {
131- let index = dialoguer:: Select :: new ( )
132- . items ( & api_keys)
140+ let redacted_keys = api_keys
141+ . iter ( )
142+ . map ( |e| e. as_redacted ( ) )
143+ . collect :: < Vec < RedactedKey > > ( ) ;
144+
145+ let index = dialoguer:: Select :: with_theme ( & ColorfulTheme :: default ( ) )
146+ . items ( & redacted_keys)
133147 . with_prompt ( "Select an API key to copy" )
134148 . interact ( ) ?;
135149
150+ let redacted_ep = format ! (
151+ "https://api.cloud.developerdao.com/rpc/{}/{}" ,
152+ CHAINS [ chain] . id( ) ,
153+ redacted_keys[ index] . redacted,
154+ ) ;
155+
136156 let endpoint = format ! (
137157 "https://api.cloud.developerdao.com/rpc/{}/{}" ,
138158 CHAINS [ chain] . id( ) ,
139159 api_keys[ index] . apikey
140160 ) ;
161+
141162 clipboard. set_text ( & endpoint) ?;
142163
143164 println ! ( "\n Your RPC Endpoint for {}:\n " , CHAINS [ chain] ) ;
144- println ! ( "\n {endpoint }\n " , ) ;
165+ println ! ( "\n {redacted_ep }\n " , ) ;
145166 println ! ( "\n Your endpoint is now copied to your clipboard" ) ;
146167 }
147168
@@ -155,11 +176,30 @@ pub struct LoginRequest {
155176}
156177
157178#[ derive( Serialize , Deserialize , Debug , Clone ) ]
158- pub struct Keys {
179+ pub struct Key {
159180 apikey : String ,
160181}
161182
162- impl Display for Keys {
183+ impl Key {
184+ pub fn as_redacted ( & self ) -> RedactedKey {
185+ let last_five = & self . apikey [ self . apikey . len ( ) - 5 ..] ;
186+ let first_five = & self . apikey [ ..5 ] ;
187+ let redacted = format ! ( "{first_five}*****************{last_five}" ) ;
188+ RedactedKey { redacted }
189+ }
190+ }
191+
192+ pub struct RedactedKey {
193+ redacted : String ,
194+ }
195+
196+ impl Display for RedactedKey {
197+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
198+ write ! ( f, "{}" , self . redacted)
199+ }
200+ }
201+
202+ impl Display for Key {
163203 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
164204 write ! ( f, "{}" , self . apikey)
165205 }
0 commit comments