11import { STELLAR_NETWORK , CONTRACT_ID } from "@/lib/env" ;
22
3- type SorobanRpcServer = {
4- getAccount : ( id : string ) => Promise < unknown > ;
5- simulateTransaction : ( tx : unknown ) => Promise < unknown > ;
6- } ;
3+ let rpcClient : unknown = null ;
74
8- let rpcClient : SorobanRpcServer | null = null ;
9-
10- export async function getSorobanClient ( ) : Promise < SorobanRpcServer > {
5+ export async function getSorobanClient ( ) : Promise < unknown > {
116 if ( ! rpcClient ) {
12- // Dynamic import to avoid TypeScript resolution issues
13- const { SorobanRpc } = await import ( "@stellar/stellar-sdk" ) ;
14- rpcClient = new SorobanRpc . Server ( STELLAR_NETWORK . rpcUrl , {
15- allowHttp : false ,
16- } ) ;
7+ const { rpc } = await import ( "@stellar/stellar-sdk" ) ;
8+ rpcClient = new rpc . Server ( STELLAR_NETWORK . rpcUrl ) ;
179 }
1810 return rpcClient ;
1911}
@@ -37,56 +29,58 @@ export async function simulateContractCall(
3729 method : string ,
3830 args : unknown [ ] = [ ]
3931) : Promise < unknown > {
40- const { Address , TransactionBuilder, contract , nativeToScVal , scValToNative , SorobanRpc } = await import (
32+ const { Contract , TransactionBuilder, Keypair , Networks , nativeToScVal , scValToNative } = await import (
4133 "@stellar/stellar-sdk"
4234 ) ;
4335 const client = await getSorobanClient ( ) ;
4436 const contractId = getContractAddress ( ) ;
4537
4638 try {
47- const contractAddress = new Address ( contractId ) ;
48- const source = await client . getAccount ( contractId ) ;
39+ // Create a temporary keypair for building the transaction
40+ // This is just for transaction construction; we won't actually sign it
41+ const tempKeypair = Keypair . random ( ) ;
42+
43+ // Get the account details from RPC
44+ const sourceAccount = await ( client as { getAccount : ( key : string ) => Promise < unknown > } ) . getAccount ( tempKeypair . publicKey ( ) ) ;
4945
50- // Create a contract invocation with simulated parameters
51- const params = args . map ( ( arg ) => {
52- if ( typeof arg === "string" ) {
53- return nativeToScVal ( arg , { type : "string" } ) ;
54- }
55- if ( typeof arg === "number" ) {
56- return nativeToScVal ( arg , { type : "u64" } ) ;
57- }
58- if ( Array . isArray ( arg ) ) {
59- return nativeToScVal ( arg , { type : "vec" } ) ;
60- }
61- return nativeToScVal ( arg ) ;
62- } ) ;
46+ // Create contract instance and add operation
47+ const contract = new Contract ( contractId ) ;
48+
49+ // Build the contract call operation with arguments
50+ const operation = contract . call (
51+ method ,
52+ ...args . map ( ( arg ) => {
53+ if ( typeof arg === "string" ) {
54+ return nativeToScVal ( arg , { type : "string" } ) ;
55+ }
56+ if ( typeof arg === "number" ) {
57+ return nativeToScVal ( arg , { type : "u64" } ) ;
58+ }
59+ if ( Array . isArray ( arg ) ) {
60+ return nativeToScVal ( arg , { type : "vec" } ) ;
61+ }
62+ return nativeToScVal ( arg ) ;
63+ } )
64+ ) ;
6365
64- const tx = new TransactionBuilder ( source , {
66+ // Build transaction
67+ const tx = new TransactionBuilder ( sourceAccount , {
6568 fee : "100" ,
6669 networkPassphrase : STELLAR_NETWORK . networkPassphrase ,
6770 } )
68- . addOperation (
69- contract ( method , contractAddress , ...params )
70- )
71+ . addOperation ( operation )
7172 . setTimeout ( 30 )
7273 . build ( ) ;
7374
74- const client_tx = await client . simulateTransaction ( tx ) ;
75+ // Prepare transaction (which includes simulation)
76+ const preparedTx = await ( client as { prepareTransaction : ( tx : unknown ) => Promise < unknown > } ) . prepareTransaction ( tx ) ;
7577
76- if ( SorobanRpc . Api . isSimulationSuccess ( client_tx ) ) {
77- const result = ( client_tx as { result ?: { retval : unknown } } ) . result ?. retval ;
78- if ( result ) {
79- return scValToNative ( result ) ;
80- }
81- return null ;
82- } else if ( SorobanRpc . Api . isSimulationRestore ( client_tx ) ) {
83- throw new Error ( "Contract needs restore" ) ;
84- } else if ( SorobanRpc . Api . isSimulationError ( client_tx ) ) {
85- const errorMsg = ( client_tx as { error ?: { message : string } } ) . error ?. message ;
86- throw new Error (
87- `Simulation error: ${ errorMsg || "Unknown error" } `
88- ) ;
78+ // Extract result from prepared transaction
79+ const result = ( preparedTx as { result ?: { retval : unknown } } ) . result ?. retval ;
80+ if ( result ) {
81+ return scValToNative ( result ) ;
8982 }
83+ return null ;
9084 } catch ( error ) {
9185 console . error ( "Simulation error:" , error ) ;
9286 throw error ;
0 commit comments