@@ -144,6 +144,25 @@ def _bytes_to_sc_val(self, data: bytes) -> SCVal:
144144 bytes = SCBytes (data ),
145145 )
146146
147+ def _get_admin_keypair (self ) -> Optional [Keypair ]:
148+ admin_secret = getattr (settings , "ADMIN_SECRET_KEY" , "" ) or self .secret_key
149+ if not admin_secret :
150+ return None
151+ return Keypair .from_secret (admin_secret )
152+
153+ def _submit_contract_transaction (
154+ self ,
155+ function_name : str ,
156+ parameters : list [SCVal ],
157+ signer : Keypair ,
158+ ) -> TransactionResult :
159+ """Simulate, prepare, and submit a Soroban contract write transaction."""
160+ try :
161+ account = self .server .load_account (signer .public_key )
162+ tx_builder = TransactionBuilder (
163+ source_account = account ,
164+ network_passphrase = self .network_passphrase ,
165+ base_fee = 100000 ,
147166 def _simulate_contract_read (
148167 self ,
149168 function_name : str ,
@@ -169,6 +188,60 @@ def _simulate_contract_read(
169188 simulate_response = self .server .simulate_transaction (tx )
170189
171190 if simulate_response .error :
191+ return TransactionResult (
192+ success = False ,
193+ tx_hash = "" ,
194+ status = "simulation_failed" ,
195+ error = simulate_response .error ,
196+ )
197+
198+ prepared_tx = self .server .prepare_transaction (tx , simulate_response )
199+ prepared_tx .sign (signer )
200+ send_response = self .server .send_transaction (prepared_tx )
201+
202+ logger .info (
203+ "Contract transaction submitted: %s (%s)" ,
204+ send_response .hash ,
205+ function_name ,
206+ )
207+
208+ return TransactionResult (
209+ success = send_response .status == "PENDING" ,
210+ tx_hash = send_response .hash ,
211+ status = send_response .status ,
212+ result_xdr = getattr (send_response , "result_xdr" , None ),
213+ )
214+ except Exception as exc :
215+ logger .exception ("Failed to submit contract transaction: %s" , function_name )
216+ return TransactionResult (
217+ success = False ,
218+ tx_hash = "" ,
219+ status = "error" ,
220+ error = str (exc ),
221+ )
222+
223+ def add_indexer (self , indexer_address : str ) -> TransactionResult :
224+ """
225+ Submit an add_indexer transaction to the SoroScan contract (SC-9).
226+
227+ The configured admin keypair must sign the transaction.
228+ """
229+ admin_keypair = self ._get_admin_keypair ()
230+ if not admin_keypair :
231+ return TransactionResult (
232+ success = False ,
233+ tx_hash = "" ,
234+ status = "error" ,
235+ error = "No admin keypair configured" ,
236+ )
237+
238+ return self ._submit_contract_transaction (
239+ function_name = "add_indexer" ,
240+ parameters = [
241+ self ._address_to_sc_val (admin_keypair .public_key ),
242+ self ._address_to_sc_val (indexer_address ),
243+ ],
244+ signer = admin_keypair ,
172245 return False , simulate_response .error
173246
174247 results = getattr (simulate_response , "results" , None ) or []
0 commit comments