@@ -16,8 +16,15 @@ use doublezero_cli::{
1616} ;
1717
1818use doublezero_sdk:: {
19- commands:: user:: { delete:: DeleteUserCommand , get:: GetUserCommand , list:: ListUserCommand } ,
20- UserType ,
19+ commands:: {
20+ accesspass:: get:: GetAccessPassCommand ,
21+ globalstate:: get:: GetGlobalStateCommand ,
22+ user:: {
23+ delete:: DeleteUserCommand , get:: GetUserCommand , list:: ListUserCommand ,
24+ transfer_ownership:: TransferUserOwnershipCommand ,
25+ } ,
26+ } ,
27+ User , UserType ,
2128} ;
2229
2330#[ allow( clippy:: upper_case_acronyms) ]
@@ -80,6 +87,10 @@ impl DecommissioningCliCommand {
8087 }
8188
8289 spinner. inc ( 1 ) ;
90+
91+ // Transfer ownership if needed before deleting
92+ self . maybe_transfer_user_ownership ( client, pubkey, user, & client_ip, & spinner) ?;
93+
8394 println ! ( "🔍 Deleting User Account for: {pubkey}" ) ;
8495 let res = client. delete_user ( DeleteUserCommand { pubkey : * pubkey } ) ;
8596 match res {
@@ -169,6 +180,54 @@ impl DecommissioningCliCommand {
169180 eyre:: bail!( "timed out waiting for daemon to remove tunnel" )
170181 }
171182
183+ /// If the user is currently owned by the feed authority and an access pass exists
184+ /// for the client's payer, transfer ownership so the delete instruction can succeed.
185+ fn maybe_transfer_user_ownership (
186+ & self ,
187+ client : & dyn CliCommand ,
188+ user_pubkey : & Pubkey ,
189+ user : & User ,
190+ client_ip : & std:: net:: Ipv4Addr ,
191+ spinner : & ProgressBar ,
192+ ) -> eyre:: Result < ( ) > {
193+ let payer = client. get_payer ( ) ;
194+
195+ if user. owner == payer {
196+ return Ok ( ( ) ) ;
197+ }
198+
199+ let ( _, globalstate) = client. get_globalstate ( GetGlobalStateCommand ) ?;
200+ if user. owner != globalstate. feed_authority_pk {
201+ return Ok ( ( ) ) ;
202+ }
203+
204+ let has_accesspass = client
205+ . get_accesspass ( GetAccessPassCommand {
206+ client_ip : * client_ip,
207+ user_payer : payer,
208+ } ) ?
209+ . is_some ( ) ;
210+
211+ if !has_accesspass {
212+ return Ok ( ( ) ) ;
213+ }
214+
215+ spinner. println ( format ! (
216+ " Transferring user ownership from feed authority to {}" ,
217+ payer
218+ ) ) ;
219+
220+ client. transfer_user_ownership ( TransferUserOwnershipCommand {
221+ user_pubkey : * user_pubkey,
222+ client_ip : * client_ip,
223+ old_user_payer : globalstate. feed_authority_pk ,
224+ new_user_payer : payer,
225+ } ) ?;
226+
227+ spinner. println ( " Ownership transferred successfully" ) ;
228+ Ok ( ( ) )
229+ }
230+
172231 fn poll_for_user_closed (
173232 & self ,
174233 client : & dyn CliCommand ,
0 commit comments