@@ -6,6 +6,13 @@ import {
66import { ConfigService } from '@nestjs/config' ;
77import { Server } from 'stellar-sdk' ;
88import { Asset , AssetType , BalanceUpdate } from './domain/balance.model' ;
9+ import { WalletNetwork } from '../wallets/domain/wallet.model' ;
10+
11+ export interface HorizonAccountResponse {
12+ id : string ;
13+ sequence : string ;
14+ balances : HorizonBalance [ ] ;
15+ }
916import { RequestContextService } from '../common/request-context/request-context.service' ;
1017import {
1118 CircuitBreaker ,
@@ -22,6 +29,22 @@ export interface HorizonBalance {
2229@Injectable ( )
2330export class StellarHorizonService {
2431 private readonly logger = new Logger ( StellarHorizonService . name ) ;
32+ private readonly horizonUrls : Record < WalletNetwork , string > ;
33+
34+ constructor ( private readonly configService : ConfigService ) {
35+ this . horizonUrls = {
36+ [ WalletNetwork . TESTNET ] : this . configService . get < string > (
37+ 'STELLAR_HORIZON_TESTNET_URL' ,
38+ 'https://horizon-testnet.stellar.org' ,
39+ ) ,
40+ [ WalletNetwork . MAINNET ] : this . configService . get < string > (
41+ 'STELLAR_HORIZON_MAINNET_URL' ,
42+ 'https://horizon.stellar.org' ,
43+ ) ,
44+ } ;
45+
46+ this . logger . log (
47+ `Initialized Stellar Horizon clients: testnet=${ this . horizonUrls [ WalletNetwork . TESTNET ] } , mainnet=${ this . horizonUrls [ WalletNetwork . MAINNET ] } ` ,
2548 private readonly horizonUrl : string;
2649 private readonly maxRetries : number;
2750 private readonly retryBackoffMs : number;
@@ -37,7 +60,14 @@ export class StellarHorizonService {
3760 'STELLAR_HORIZON_URL' ,
3861 'https://horizon-testnet.stellar.org' ,
3962 ) ;
63+ }
4064
65+ /**
66+ * Resolves the Horizon base URL for a given network. Defaults to testnet
67+ * when no network is specified, matching prior (single-URL) behavior.
68+ */
69+ private resolveUrl ( network : WalletNetwork = WalletNetwork . TESTNET ) : string {
70+ return this . horizonUrls [ network ] ;
4171 this . maxRetries = this . configService . get < number > (
4272 'STELLAR_HORIZON_MAX_RETRIES' ,
4373 3 ,
@@ -120,6 +150,11 @@ export class StellarHorizonService {
120150 /**
121151 * Fetches account balances from Stellar Horizon
122152 */
153+ async getAccountBalances (
154+ publicKey : string ,
155+ network : WalletNetwork = WalletNetwork . TESTNET ,
156+ ) : Promise < BalanceUpdate [ ] > {
157+ const horizonUrl = this . resolveUrl ( network ) ;
123158 async getAccountBalances ( publicKey : string ) : Promise < BalanceUpdate [ ] > {
124159 const requestId = this . requestContext . getRequestId ( ) ;
125160 const logPrefix = requestId ? `[${ requestId } ] ` : '' ;
@@ -130,6 +165,7 @@ export class StellarHorizonService {
130165 ) ;
131166
132167 // Simplified mock implementation
168+ const response = await this . mockHorizonRequest ( publicKey , horizonUrl ) ;
133169 const response = await this . withRetry (
134170 ( ) => this . mockHorizonRequest ( publicKey ) ,
135171 `getAccountBalances(${ publicKey . substring ( 0 , 8 ) } ...)` ,
@@ -162,6 +198,12 @@ export class StellarHorizonService {
162198 /**
163199 * Checks if an account exists on-chain
164200 */
201+ async accountExists (
202+ publicKey : string ,
203+ network : WalletNetwork = WalletNetwork . TESTNET ,
204+ ) : Promise < boolean > {
205+ try {
206+ await this . mockHorizonRequest ( publicKey , this . resolveUrl ( network ) ) ;
165207 async accountExists ( publicKey : string ) : Promise < boolean > {
166208 const requestId = this . requestContext . getRequestId ( ) ;
167209 const logPrefix = requestId ? `[ $ { requestId} ] ` : '';
@@ -270,4 +312,36 @@ export class StellarHorizonService {
270312 throw new Error(` Unknown asset type : ${horizonBalance . asset_type } `);
271313 }
272314 }
315+
316+ /**
317+ * Mock Horizon request (replace with real stellar-sdk in production)
318+ */
319+ private async mockHorizonRequest(
320+ publicKey: string,
321+ horizonUrl: string,
322+ ): Promise<HorizonAccountResponse> {
323+ this.logger.debug(` Requesting account ${publicKey } from ${horizonUrl } `) ;
324+
325+ // Simulate API call delay
326+ await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
327+
328+ // Mock response with realistic data
329+ return {
330+ id : publicKey ,
331+ sequence : '123456789' ,
332+ balances : [
333+ {
334+ asset_type : 'native' ,
335+ balance : '1000.5000000' ,
336+ } ,
337+ {
338+ asset_type : 'credit_alphanum4' ,
339+ asset_code : 'USDC' ,
340+ asset_issuer :
341+ 'GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN' ,
342+ balance : '500.0000000' ,
343+ } ,
344+ ] ,
345+ } ;
346+ }
273347}
0 commit comments