-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtransaction_service.go
More file actions
306 lines (258 loc) · 9.3 KB
/
Copy pathtransaction_service.go
File metadata and controls
306 lines (258 loc) · 9.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
package idrx
import (
"context"
"fmt"
"github.com/widnyana/idrx-go/models"
)
// TransactionService handles transaction operations including minting, redeeming,
// rate queries, and transaction history.
type TransactionService struct {
client *Client
}
// MintRequest creates a request to mint IDRX or other stablecoins.
// This operation requires user-level authentication.
func (s *TransactionService) MintRequest(ctx context.Context, req *models.MintRequest) (*models.MintResponse, error) {
if req == nil {
return nil, fmt.Errorf("mint request cannot be nil")
}
// Validate required fields
if err := s.validateMintRequest(req); err != nil {
return nil, fmt.Errorf("validation failed: %w", err)
}
var response models.APIResponse[models.MintResponse]
if err := s.client.doRequest(ctx, "POST", "/api/transaction/mint-request", req, &response); err != nil {
return nil, fmt.Errorf("failed to create mint request: %w", err)
}
return &response.Data, nil
}
// RedeemRequest creates a request to redeem IDRX to a bank account.
// This operation requires user-level authentication.
func (s *TransactionService) RedeemRequest(ctx context.Context, req *models.RedeemRequest) (*models.RedeemResponse, error) {
if req == nil {
return nil, fmt.Errorf("redeem request cannot be nil")
}
// Validate required fields
if err := s.validateRedeemRequest(req); err != nil {
return nil, fmt.Errorf("validation failed: %w", err)
}
var response models.APIResponse[models.RedeemResponse]
if err := s.client.doRequest(ctx, "POST", "/api/transaction/redeem-request", req, &response); err != nil {
return nil, fmt.Errorf("failed to create redeem request: %w", err)
}
return &response.Data, nil
}
// BridgeRequest creates a request for token bridging operations.
// This operation requires user-level authentication.
func (s *TransactionService) BridgeRequest(ctx context.Context, req *models.BridgeRequest) (*models.BridgeResponse, error) {
if req == nil {
return nil, fmt.Errorf("bridge request cannot be nil")
}
// Validate required fields
if err := s.validateBridgeRequest(req); err != nil {
return nil, fmt.Errorf("validation failed: %w", err)
}
var response models.APIResponse[models.BridgeResponse]
if err := s.client.doRequest(ctx, "POST", "/api/transaction/bridge-request", req, &response); err != nil {
return nil, fmt.Errorf("failed to create bridge request: %w", err)
}
return &response.Data, nil
}
// GetRates retrieves current swap rates between IDRX and other tokens.
// Either idrxAmount or usdtAmount must be provided, but not both.
func (s *TransactionService) GetRates(ctx context.Context, req *models.RatesRequest) (*models.RatesResponse, error) {
if req == nil {
return nil, fmt.Errorf("rates request cannot be nil")
}
// Validate that exactly one amount is provided
if err := s.validateRatesRequest(req); err != nil {
return nil, fmt.Errorf("validation failed: %w", err)
}
// Build query parameters
queryParams, err := s.client.buildQueryParams(req)
if err != nil {
return nil, fmt.Errorf("failed to build query parameters: %w", err)
}
path := "/api/transaction/rates"
if queryParams != "" {
path += "?" + queryParams
}
var response models.APIResponse[models.RatesResponse]
if err := s.client.doRequest(ctx, "GET", path, nil, &response); err != nil {
return nil, fmt.Errorf("failed to get rates: %w", err)
}
return &response.Data, nil
}
// GetMethods retrieves the list of supported banks with codes and transfer limits.
func (s *TransactionService) GetMethods(ctx context.Context) ([]models.Bank, error) {
var response models.BanksResponse
if err := s.client.doRequest(ctx, "GET", "/api/transaction/method", nil, &response); err != nil {
return nil, fmt.Errorf("failed to get methods: %w", err)
}
return response.Data, nil
}
// GetBanks is a wrapper for GetMethods to fix vague IDRX terms
func (s *TransactionService) GetBanks(ctx context.Context) ([]models.Bank, error) {
return s.GetMethods(ctx)
}
// GetAdditionalFees retrieves additional fees for different transaction types.
func (s *TransactionService) GetAdditionalFees(ctx context.Context, req *models.FeesRequest) ([]models.Fee, error) {
if req == nil {
return nil, fmt.Errorf("fees request cannot be nil")
}
// Validate required fields
if req.FeeType == "" {
return nil, fmt.Errorf("fee type is required")
}
// Build query parameters
queryParams, err := s.client.buildQueryParams(req)
if err != nil {
return nil, fmt.Errorf("failed to build query parameters: %w", err)
}
path := "/api/transaction/get-additional-fees"
if queryParams != "" {
path += "?" + queryParams
}
var response models.FeesResponse
if err := s.client.doRequest(ctx, "GET", path, nil, &response); err != nil {
return nil, fmt.Errorf("failed to get additional fees: %w", err)
}
return response.Data, nil
}
// GetTransactionHistory retrieves the user's transaction history with filtering and pagination.
// This operation requires user-level authentication.
func (s *TransactionService) GetTransactionHistory(
ctx context.Context,
req *models.TransactionHistoryRequest,
) (*models.TransactionHistoryResponse, error) {
if req == nil {
return nil, fmt.Errorf("transaction history request cannot be nil")
}
// Validate required fields
if err := s.validateTransactionHistoryRequest(req); err != nil {
return nil, fmt.Errorf("validation failed: %w", err)
}
// Build query parameters
queryParams, err := s.client.buildQueryParams(req)
if err != nil {
return nil, fmt.Errorf("failed to build query parameters: %w", err)
}
path := "/api/transaction/user-transaction-history"
if queryParams != "" {
path += "?" + queryParams
}
var response models.TransactionHistoryResponse
if err := s.client.doRequest(ctx, "GET", path, nil, &response); err != nil {
return nil, fmt.Errorf("failed to get transaction history: %w", err)
}
return &response, nil
}
// validateMintRequest validates the mint request fields.
func (s *TransactionService) validateMintRequest(req *models.MintRequest) error {
if req.ToBeMinted == "" {
return fmt.Errorf("toBeMinted is required")
}
if req.DestinationWalletAddress == "" {
return fmt.Errorf("destinationWalletAddress is required")
}
if req.NetworkChainID == "" {
return fmt.Errorf("networkChainId is required")
}
if req.ExpiryPeriod <= 0 {
return fmt.Errorf("expiryPeriod must be greater than 0")
}
// Validate optional productDetails length
if len(req.ProductDetails) > 255 {
return fmt.Errorf("productDetails must not exceed 255 characters")
}
// Validate optional customerDetail fields
if req.CustomerDetail != nil {
if len(req.CustomerDetail.FirstName) > 50 {
return fmt.Errorf("customerDetail.firstName must not exceed 50 characters")
}
if len(req.CustomerDetail.LastName) > 50 {
return fmt.Errorf("customerDetail.lastName must not exceed 50 characters")
}
if len(req.CustomerDetail.Email) > 50 {
return fmt.Errorf("customerDetail.email must not exceed 50 characters")
}
}
return nil
}
// validateRedeemRequest validates the redeem request fields.
func (s *TransactionService) validateRedeemRequest(req *models.RedeemRequest) error {
if req.TxHash == "" {
return fmt.Errorf("txHash is required")
}
if req.NetworkChainID == "" {
return fmt.Errorf("networkChainId is required")
}
if req.AmountTransfer == "" {
return fmt.Errorf("amountTransfer is required")
}
if req.BankAccount == "" {
return fmt.Errorf("bankAccount is required")
}
if req.BankCode == "" {
return fmt.Errorf("bankCode is required")
}
if req.BankName == "" {
return fmt.Errorf("bankName is required")
}
if req.BankAccountName == "" {
return fmt.Errorf("bankAccountName is required")
}
if req.WalletAddress == "" {
return fmt.Errorf("walletAddress is required")
}
if req.Notes == "" {
return fmt.Errorf("notes is required")
}
return nil
}
// validateBridgeRequest validates the bridge request fields.
func (s *TransactionService) validateBridgeRequest(req *models.BridgeRequest) error {
if req.FromChainID == "" {
return fmt.Errorf("fromChainId is required")
}
if req.ToChainID == "" {
return fmt.Errorf("toChainId is required")
}
if req.Amount == "" {
return fmt.Errorf("amount is required")
}
if req.WalletAddress == "" {
return fmt.Errorf("walletAddress is required")
}
if req.DestinationAddress == "" {
return fmt.Errorf("destinationAddress is required")
}
return nil
}
// validateRatesRequest validates that exactly one amount is provided.
func (s *TransactionService) validateRatesRequest(req *models.RatesRequest) error {
hasIDRXAmount := req.IDRXAmount != nil && *req.IDRXAmount != ""
hasUSDTAmount := req.USDTAmount != nil && *req.USDTAmount != ""
if !hasIDRXAmount && !hasUSDTAmount {
return fmt.Errorf("either idrxAmount or usdtAmount must be provided")
}
if hasIDRXAmount && hasUSDTAmount {
return fmt.Errorf("only one of idrxAmount or usdtAmount should be provided")
}
return nil
}
// validateTransactionHistoryRequest validates the transaction history request fields.
func (s *TransactionService) validateTransactionHistoryRequest(req *models.TransactionHistoryRequest) error {
if req.TransactionType == "" {
return fmt.Errorf("transactionType is required")
}
if req.Page <= 0 {
return fmt.Errorf("page must be greater than 0")
}
if req.Take <= 0 {
return fmt.Errorf("take must be greater than 0")
}
if req.Take > 100 {
return fmt.Errorf("take cannot be greater than 100")
}
return nil
}