1- import { Request , Response } from 'express' ;
2- import { AnchorService } from '../services/anchorService' ;
3- import { Keypair } from '@stellar/stellar-sdk' ;
1+ import type { Request , Response } from 'express' ;
2+ import { AnchorService } from '../services/anchorService.js' ;
3+ import { Keypair , Asset } from '@stellar/stellar-sdk' ;
4+ import { StellarService } from '../services/stellarService.js' ;
45
56export class PaymentController {
67 /**
@@ -32,10 +33,10 @@ export class PaymentController {
3233 const clientKeypair = Keypair . fromSecret ( secretKey ) ;
3334
3435 // 1. Authenticate
35- const token = await AnchorService . authenticate ( domain , clientKeypair ) ;
36+ const token = await AnchorService . authenticate ( domain as string , clientKeypair ) ;
3637
3738 // 2. Initiate Payment
38- const result = await AnchorService . initiatePayment ( domain , token , paymentData ) ;
39+ const result = await AnchorService . initiatePayment ( domain as string , token , paymentData ) ;
3940
4041 res . json ( result ) ;
4142 } catch ( error : any ) {
@@ -59,12 +60,66 @@ export class PaymentController {
5960 const clientKeypair = Keypair . fromSecret ( secretKey as string ) ;
6061 // Re-auth to get a fresh token or use a session-based approach
6162 // For simplicity in this implementation, we re-auth
62- const token = await AnchorService . authenticate ( domain , clientKeypair ) ;
63+ const token = await AnchorService . authenticate ( domain as string , clientKeypair ) ;
6364
64- const status = await AnchorService . getTransaction ( domain , token , id ) ;
65+ const status = await AnchorService . getTransaction ( domain as string , token , id ) ;
6566 res . json ( status ) ;
6667 } catch ( error : any ) {
6768 res . status ( 500 ) . json ( { error : error . message } ) ;
6869 }
6970 }
71+
72+ /**
73+ * GET /api/payments/paths
74+ * Proxy to Stellar Horizon strictSendPaths
75+ */
76+ static async getCrossAssetPaths ( req : Request , res : Response ) {
77+ const { sourceAsset, sourceAmount, destAssets } = req . query ;
78+
79+ if (
80+ typeof sourceAsset !== 'string' ||
81+ typeof sourceAmount !== 'string' ||
82+ typeof destAssets !== 'string'
83+ ) {
84+ return res . status ( 400 ) . json ( {
85+ error : 'Missing or invalid query params: sourceAsset, sourceAmount, destAssets must be strings'
86+ } ) ;
87+ }
88+
89+ try {
90+ const server = StellarService . getServer ( ) ;
91+
92+ // Parse Source Asset
93+ let sourceAssetObj : Asset ;
94+ if ( sourceAsset === 'XLM' ) {
95+ sourceAssetObj = Asset . native ( ) ;
96+ } else {
97+ // Format parsing: CODE:ISSUER
98+ const parts = sourceAsset . split ( ':' ) ;
99+ if ( parts . length !== 2 ) throw new Error ( 'Invalid sourceAsset format. Use CODE:ISSUER or XLM' ) ;
100+ sourceAssetObj = new Asset ( parts [ 0 ] as string , parts [ 1 ] as string ) ;
101+ }
102+
103+ // Parse Destination Assets
104+ const destAssetList : Asset [ ] = destAssets . split ( ',' ) . map ( ( assetStr ) => {
105+ if ( assetStr === 'XLM' ) return Asset . native ( ) ;
106+ const parts = assetStr . split ( ':' ) ;
107+ if ( parts . length !== 2 ) throw new Error ( `Invalid destAsset format: ${ assetStr } ` ) ;
108+ return new Asset ( parts [ 0 ] as string , parts [ 1 ] as string ) ;
109+ } ) ;
110+
111+ // Call Horizon
112+ const pathsResponse = await server
113+ . strictSendPaths ( sourceAssetObj , sourceAmount , destAssetList )
114+ . call ( ) ;
115+
116+ res . json ( {
117+ paths : pathsResponse . records
118+ } ) ;
119+
120+ } catch ( error : any ) {
121+ console . error ( 'Pathfinding Error:' , error ) ;
122+ res . status ( 500 ) . json ( { error : error . message || 'Error fetching conversion paths' } ) ;
123+ }
124+ }
70125}
0 commit comments