@@ -203,6 +203,64 @@ export class StellarService implements OnModuleInit {
203203 }
204204 }
205205
206+ /**
207+ * Estimate fees for a Soroban contract call using simulation
208+ */
209+ async estimateSorobanFees (
210+ contractId : string ,
211+ functionName : string ,
212+ args : any [ ] = [ ] ,
213+ ) : Promise < { resourceFee : string ; baseFee : string ; totalFee : string } > {
214+ try {
215+ return await this . rpcClient . executeWithRetry ( async ( client ) => {
216+ const rpcServer = client as rpc . Server ;
217+ const sourceAccount = new Account ( Keypair . random ( ) . publicKey ( ) , '0' ) ;
218+ const contract = new Contract ( contractId ) ;
219+
220+ const transaction = new TransactionBuilder ( sourceAccount , {
221+ fee : BASE_FEE ,
222+ networkPassphrase : this . getNetworkPassphrase ( ) ,
223+ } )
224+ . addOperation (
225+ contract . call (
226+ functionName ,
227+ ...args . map ( ( arg ) => nativeToScVal ( arg as never ) ) ,
228+ ) ,
229+ )
230+ . setTimeout ( 30 )
231+ . build ( ) ;
232+
233+ const simulation = await rpcServer . simulateTransaction ( transaction ) ;
234+ if ( rpc . Api . isSimulationError ( simulation ) ) {
235+ throw new Error ( `Soroban simulation failed: ${ simulation . error } ` ) ;
236+ }
237+
238+ return this . calculateFees ( transaction , simulation ) ;
239+ } , 'rpc' ) ;
240+ } catch ( error ) {
241+ this . logger . error (
242+ `Failed to estimate fees for ${ contractId } .${ functionName } : ${ ( error as Error ) . message } ` ,
243+ error ,
244+ ) ;
245+ throw error ;
246+ }
247+ }
248+
249+ private calculateFees (
250+ transaction : any ,
251+ simulation : any ,
252+ ) : { resourceFee : string ; baseFee : string ; totalFee : string } {
253+ const resourceFee = BigInt ( simulation . minResourceFee ?? 0 ) ;
254+ const baseFee = BigInt ( transaction . operations . length ) * BigInt ( BASE_FEE ) ;
255+ const totalFee = baseFee + resourceFee ;
256+
257+ return {
258+ resourceFee : resourceFee . toString ( ) ,
259+ baseFee : baseFee . toString ( ) ,
260+ totalFee : totalFee . toString ( ) ,
261+ } ;
262+ }
263+
206264 async invokeContractWrite (
207265 contractId : string ,
208266 functionName : string ,
@@ -236,6 +294,9 @@ export class StellarService implements OnModuleInit {
236294 throw new Error ( `Soroban simulation failed: ${ simulation . error } ` ) ;
237295 }
238296
297+ const fees = this . calculateFees ( transaction , simulation ) ;
298+ transaction . fee = fees . totalFee ;
299+
239300 transaction = rpc . assembleTransaction ( transaction , simulation ) . build ( ) ;
240301 transaction . sign ( sourceKeypair ) ;
241302
0 commit comments