@@ -9,6 +9,15 @@ import {
99 UseGuards ,
1010 BadRequestException ,
1111} from '@nestjs/common' ;
12+ import {
13+ ApiTags ,
14+ ApiSecurity ,
15+ ApiOperation ,
16+ ApiParam ,
17+ ApiQuery ,
18+ ApiResponse ,
19+ ApiBody ,
20+ } from '@nestjs/swagger' ;
1221import { TransactionsService } from './transactions.service' ;
1322import { StellarTransactionBuildService } from './stellar-transaction-build.service' ;
1423import { CreateTransactionDto } from './dto/create-transaction.dto' ;
@@ -54,18 +63,96 @@ export class TransactionsController {
5463 * Build an unsigned Stellar payment transaction XDR.
5564 * The returned XDR must be signed before submission to the network.
5665 */
66+ @ApiOperation ( { summary : 'Build an unsigned Stellar payment transaction XDR' } )
67+ @ApiBody ( {
68+ description : 'Payment build parameters' ,
69+ examples : {
70+ native : {
71+ summary : 'Native XLM payment' ,
72+ value : {
73+ sourcePublicKey : 'GABC1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEF' ,
74+ destinationPublicKey : 'GDEF1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEF' ,
75+ amount : '10.5' ,
76+ asset : { type : 'NATIVE' } ,
77+ memo : 'Payment for services' ,
78+ } ,
79+ } ,
80+ } ,
81+ } )
82+ @ApiResponse ( { status : 200 , description : 'Returns unsigned transaction XDR string' } )
5783 @Post ( 'build' )
5884 @SensitiveEndpoint ( )
5985 buildTransaction ( @Body ( ) dto : BuildTransactionDto ) {
6086 return this . stellarBuildService . buildPayment ( dto ) ;
6187 }
6288
89+ @ApiOperation ( { summary : 'Create a new transaction' } )
90+ @ApiBody ( {
91+ description : 'Transaction creation payload' ,
92+ examples : {
93+ nativePayment : {
94+ summary : 'Native XLM payment' ,
95+ value : {
96+ amount : '10' ,
97+ asset : { type : 'NATIVE' } ,
98+ senderWalletId : '550e8400-e29b-41d4-a716-446655440000' ,
99+ receiverWalletId : '550e8400-e29b-41d4-a716-446655440001' ,
100+ memo : 'Payment for invoice #42' ,
101+ idempotencyKey : 'inv-42-pay-1' ,
102+ } ,
103+ } ,
104+ usdcPayment : {
105+ summary : 'USDC payment' ,
106+ value : {
107+ amount : '25.00' ,
108+ asset : {
109+ type : 'CREDIT_ALPHANUM4' ,
110+ code : 'USDC' ,
111+ issuer : 'GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN' ,
112+ } ,
113+ senderWalletId : '550e8400-e29b-41d4-a716-446655440000' ,
114+ receiverWalletId : '550e8400-e29b-41d4-a716-446655440001' ,
115+ } ,
116+ } ,
117+ } ,
118+ } )
119+ @ApiResponse ( { status : 201 , description : 'Transaction created in PENDING state' } )
63120 @Post ( )
64121 @SensitiveEndpoint ( )
65122 create ( @Body ( ) createTransactionDto : CreateTransactionDto ) {
66123 return this . transactionsService . create ( createTransactionDto ) ;
67124 }
68125
126+ @ApiOperation ( { summary : 'List transactions with optional filters and pagination' } )
127+ @ApiQuery ( { name : 'senderWalletId' , required : false , description : 'Filter by sender wallet ID' } )
128+ @ApiQuery ( { name : 'receiverWalletId' , required : false , description : 'Filter by receiver wallet ID' } )
129+ @ApiQuery ( { name : 'status' , required : false , enum : TransactionStatus , description : 'Filter by transaction status' } )
130+ @ApiQuery ( { name : 'limit' , required : false , description : 'Max records to return (1-100, default 20)' , example : 20 } )
131+ @ApiQuery ( { name : 'offset' , required : false , description : 'Number of records to skip (default 0)' , example : 0 } )
132+ @ApiResponse ( {
133+ status : 200 ,
134+ description : 'Paginated list of transactions' ,
135+ schema : {
136+ example : {
137+ data : [
138+ {
139+ id : '550e8400-e29b-41d4-a716-446655440002' ,
140+ amount : '10' ,
141+ assetType : 'NATIVE' ,
142+ status : 'PENDING' ,
143+ senderWalletId : '550e8400-e29b-41d4-a716-446655440000' ,
144+ receiverWalletId : '550e8400-e29b-41d4-a716-446655440001' ,
145+ createdAt : '2026-01-01T00:00:00.000Z' ,
146+ updatedAt : '2026-01-01T00:00:00.000Z' ,
147+ } ,
148+ ] ,
149+ total : 1 ,
150+ limit : 20 ,
151+ offset : 0 ,
152+ hasMore : false ,
153+ } ,
154+ } ,
155+ } )
69156 @Get ( )
70157 findAll (
71158 @Query ( 'senderWalletId' ) senderWalletId ?: string ,
@@ -83,6 +170,12 @@ export class TransactionsController {
83170 } ) ;
84171 }
85172
173+ @ApiOperation ( { summary : 'List transactions for a specific wallet' } )
174+ @ApiParam ( { name : 'walletId' , description : 'Wallet ID to query transactions for' , example : '550e8400-e29b-41d4-a716-446655440000' } )
175+ @ApiQuery ( { name : 'limit' , required : false , description : 'Max records to return (1-100, default 20)' , example : 20 } )
176+ @ApiQuery ( { name : 'offset' , required : false , description : 'Number of records to skip (default 0)' , example : 0 } )
177+ @ApiResponse ( { status : 200 , description : 'Paginated list of wallet transactions' } )
178+ @ApiResponse ( { status : 404 , description : 'Wallet not found' } )
86179 @Get ( 'wallet/:walletId' )
87180 findByWallet (
88181 @Param ( 'walletId' ) walletId : string ,
@@ -95,16 +188,57 @@ export class TransactionsController {
95188 } ) ;
96189 }
97190
191+ @ApiOperation ( { summary : 'Find a transaction by Stellar transaction hash' } )
192+ @ApiParam ( { name : 'hash' , description : 'Stellar transaction hash' , example : 'a1b2c3d4e5f6...' } )
193+ @ApiResponse ( { status : 200 , description : 'Transaction found' } )
194+ @ApiResponse ( { status : 200 , description : 'Returns null if not found' } )
98195 @Get ( 'stellar/:hash' )
99196 findByStellarHash ( @Param ( 'hash' ) hash : string ) {
100197 return this . transactionsService . findByStellarHash ( hash ) ;
101198 }
102199
200+ @ApiOperation ( { summary : 'Get a transaction by ID' } )
201+ @ApiParam ( { name : 'id' , description : 'Transaction UUID' , example : '550e8400-e29b-41d4-a716-446655440002' } )
202+ @ApiResponse ( { status : 200 , description : 'Transaction found' } )
203+ @ApiResponse ( { status : 404 , description : 'Transaction not found' } )
103204 @Get ( ':id' )
104205 findOne ( @Param ( 'id' ) id : string ) {
105206 return this . transactionsService . findOne ( id ) ;
106207 }
107208
209+ @ApiOperation ( { summary : 'Update transaction status' } )
210+ @ApiParam ( { name : 'id' , description : 'Transaction UUID' } )
211+ @ApiBody ( {
212+ description : 'Status update payload' ,
213+ examples : {
214+ submit : {
215+ summary : 'Mark as submitted to Stellar' ,
216+ value : {
217+ status : 'SUBMITTED' ,
218+ stellarHash : 'a1b2c3d4e5f6789abc...' ,
219+ } ,
220+ } ,
221+ confirm : {
222+ summary : 'Mark as confirmed on-chain' ,
223+ value : {
224+ status : 'CONFIRMED' ,
225+ stellarHash : 'a1b2c3d4e5f6789abc...' ,
226+ stellarLedger : 48750123 ,
227+ stellarFee : '100' ,
228+ } ,
229+ } ,
230+ fail : {
231+ summary : 'Mark as failed' ,
232+ value : {
233+ status : 'FAILED' ,
234+ statusReason : 'Insufficient fee' ,
235+ } ,
236+ } ,
237+ } ,
238+ } )
239+ @ApiResponse ( { status : 200 , description : 'Status updated' } )
240+ @ApiResponse ( { status : 400 , description : 'Invalid status transition' } )
241+ @ApiResponse ( { status : 404 , description : 'Transaction not found' } )
108242 @Patch ( ':id/status' )
109243 @SensitiveEndpoint ( )
110244 updateStatus (
0 commit comments