From 466eeee5928872727f1564d40f589b8797fdb220 Mon Sep 17 00:00:00 2001 From: Ebuka Moses Date: Tue, 2 Jun 2026 11:02:58 +0100 Subject: [PATCH 1/4] [Backend] sorobanService.simulateContractCall: extract STALE_THRESHOLD_MS / fee / placeholder source magic --- backend/src/services/sorobanService.ts | 35 +++++++++++++++++++------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/backend/src/services/sorobanService.ts b/backend/src/services/sorobanService.ts index 7248e0f..52147d1 100644 --- a/backend/src/services/sorobanService.ts +++ b/backend/src/services/sorobanService.ts @@ -4,9 +4,29 @@ import logger from '../logger.js'; const RPC_URL = process.env.SOROBAN_RPC_URL ?? 'https://soroban-testnet.stellar.org'; const CONTRACT_ID = process.env.STREAM_CONTRACT_ID ?? ''; const KEEPER_SECRET = process.env.KEEPER_SECRET_KEY ?? ''; -/** DB data older than this is considered stale and triggers an RPC fallback. */ +/** + * DB data older than this is considered stale and triggers an RPC fallback. + * 30 s ≈ avg Stellar ledger close time (~5 s) × 6 ledgers — a reasonable + * window to tolerate indexer lag without hammering the RPC on every request. + */ const STALE_THRESHOLD_MS = 30_000; +/** Stroops charged on read-only simulation transactions (no real resource cost). */ +const SIMULATION_FEE = '100'; + +/** Stroops charged on real contract-invocation transactions submitted to the network. */ +const SUBMIT_FEE = '1000'; + +/** Transaction validity window in seconds (applied via setTimeout). */ +const TX_TIMEOUT_SECONDS = 30; + +/** + * Throw-away source account used when building simulation-only transactions. + * Any valid Ed25519 public key works here; the account never needs to exist on-chain + * because simulation transactions are never submitted. + */ +const SIMULATION_PLACEHOLDER_ACCOUNT = 'GAAZI4TCR3TY5OJHCTJC2A4QSY6CJWJH5IAJTGKIN2ER7LBNVKOCCWN'; + const server = new rpc.Server(RPC_URL, { allowHttp: true }); export interface ChainStream { @@ -51,12 +71,9 @@ async function simulateContractCall(method: string, args: xdr.ScVal[]): Promise< const op = contract.call(method, ...args); const tx = new TransactionBuilder( - new Account( - 'GAAZI4TCR3TY5OJHCTJC2A4QSY6CJWJH5IAJTGKIN2ER7LBNVKOCCWN', - '0' - ), + new Account(SIMULATION_PLACEHOLDER_ACCOUNT, '0'), { - fee: '100', + fee: SIMULATION_FEE, networkPassphrase: process.env.STELLAR_NETWORK === 'mainnet' ? Networks.PUBLIC @@ -64,7 +81,7 @@ async function simulateContractCall(method: string, args: xdr.ScVal[]): Promise< } ) .addOperation(op) - .setTimeout(30) + .setTimeout(TX_TIMEOUT_SECONDS) .build(); const result = await server.simulateTransaction(tx); @@ -87,14 +104,14 @@ async function submitContractCall(method: string, args: xdr.ScVal[], senderSecre const op = contract.call(method, ...args); const tx = new TransactionBuilder(account, { - fee: '1000', + fee: SUBMIT_FEE, networkPassphrase: process.env.STELLAR_NETWORK === 'mainnet' ? Networks.PUBLIC : Networks.TESTNET, }) .addOperation(op) - .setTimeout(30) + .setTimeout(TX_TIMEOUT_SECONDS) .build(); // Simulate first to get foot print and resource info From b7fb5c8c702d9d1c88baae90ec24404efd632a9c Mon Sep 17 00:00:00 2001 From: Ebuka Moses Date: Tue, 9 Jun 2026 00:04:20 +0100 Subject: [PATCH 2/4] fixed bug --- backend/src/services/sorobanService.ts | 2 +- backend/src/workers/soroban-event-worker.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/services/sorobanService.ts b/backend/src/services/sorobanService.ts index 82ffd5e..44bce26 100644 --- a/backend/src/services/sorobanService.ts +++ b/backend/src/services/sorobanService.ts @@ -54,7 +54,7 @@ function decodeAddress(val: xdr.ScVal): string { return StrKey.encodeEd25519PublicKey(addr.accountId().ed25519()); } const hash = addr.contractId(); - return StrKey.encodeContract(Buffer.from(hash as Uint8Array)); + return StrKey.encodeContract(Buffer.from(hash)); } function decodeMap(val: xdr.ScVal): Record { diff --git a/backend/src/workers/soroban-event-worker.ts b/backend/src/workers/soroban-event-worker.ts index 1b1b6ab..f55598c 100644 --- a/backend/src/workers/soroban-event-worker.ts +++ b/backend/src/workers/soroban-event-worker.ts @@ -50,9 +50,9 @@ export function decodeAddress(val: xdr.ScVal): string { ) { return StrKey.encodeEd25519PublicKey(addr.accountId().ed25519()); } - // addr.contractId() returns a Hash (Opaque[]); cast to Uint8Array for encodeContract + // addr.contractId() returns a Hash (Opaque[]) const hash = addr.contractId(); - return StrKey.encodeContract(Buffer.from(hash as Uint8Array)); + return StrKey.encodeContract(Buffer.from(hash)); } /** From 83ca5cd6d62ca322d568a0780a73c63587fd08cb Mon Sep 17 00:00:00 2001 From: Ebuka Moses Date: Tue, 9 Jun 2026 00:11:53 +0100 Subject: [PATCH 3/4] fix: use as unknown as Uint8Array for Hash type conversion --- backend/src/services/sorobanService.ts | 3 ++- backend/src/workers/soroban-event-worker.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/src/services/sorobanService.ts b/backend/src/services/sorobanService.ts index 44bce26..5e942a1 100644 --- a/backend/src/services/sorobanService.ts +++ b/backend/src/services/sorobanService.ts @@ -54,7 +54,8 @@ function decodeAddress(val: xdr.ScVal): string { return StrKey.encodeEd25519PublicKey(addr.accountId().ed25519()); } const hash = addr.contractId(); - return StrKey.encodeContract(Buffer.from(hash)); + // Convert Hash (Opaque[]) to Buffer before passing to encodeContract + return StrKey.encodeContract(Buffer.from(hash as unknown as Uint8Array)); } function decodeMap(val: xdr.ScVal): Record { diff --git a/backend/src/workers/soroban-event-worker.ts b/backend/src/workers/soroban-event-worker.ts index f55598c..976f2eb 100644 --- a/backend/src/workers/soroban-event-worker.ts +++ b/backend/src/workers/soroban-event-worker.ts @@ -52,7 +52,7 @@ export function decodeAddress(val: xdr.ScVal): string { } // addr.contractId() returns a Hash (Opaque[]) const hash = addr.contractId(); - return StrKey.encodeContract(Buffer.from(hash)); + return StrKey.encodeContract(Buffer.from(hash as unknown as Uint8Array)); } /** From 6132b7aae591c781c7524b5e67a5a26111c718ac Mon Sep 17 00:00:00 2001 From: Ebuka Moses Date: Tue, 9 Jun 2026 00:14:04 +0100 Subject: [PATCH 4/4] fix: add Account to imports --- backend/src/services/sorobanService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/services/sorobanService.ts b/backend/src/services/sorobanService.ts index 5e942a1..2a1ed02 100644 --- a/backend/src/services/sorobanService.ts +++ b/backend/src/services/sorobanService.ts @@ -1,4 +1,4 @@ -import { rpc, xdr, StrKey, Contract, nativeToScVal, Keypair, TransactionBuilder, Networks } from '@stellar/stellar-sdk'; +import { rpc, xdr, StrKey, Contract, nativeToScVal, Keypair, TransactionBuilder, Networks, Account } from '@stellar/stellar-sdk'; import logger from '../logger.js'; const RPC_URL = process.env.SOROBAN_RPC_URL ?? 'https://soroban-testnet.stellar.org';