Skip to content

Commit 7b44ff2

Browse files
gsoares85AndresQuijano
authored andcommitted
feat: added the asset report endpoint
1 parent 76ab913 commit 7b44ff2

11 files changed

Lines changed: 473 additions & 2 deletions

File tree

OpenApi.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,6 @@ components:
521521
properties:
522522
fee:
523523
type: integer
524-
deprecated: true
525524
feePercentage:
526525
type: number
527526
fixedFee:
@@ -1034,6 +1033,13 @@ paths:
10341033
"204":
10351034
description: ""
10361035
summary: Withdraw PegIn Collateral
1036+
/reports/assets:
1037+
get:
1038+
description: ' Get the asset information for the LPS.'
1039+
responses:
1040+
"200":
1041+
description: ""
1042+
summary: Get asset Reports
10371043
/reports/pegin:
10381044
get:
10391045
description: ' Get the last pegins on the API. Included in the management API.'
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package handlers
2+
3+
import (
4+
"github.com/rsksmart/liquidity-provider-server/internal/adapters/entrypoints/rest"
5+
"github.com/rsksmart/liquidity-provider-server/internal/usecases/reports"
6+
"net/http"
7+
)
8+
9+
// NewGetReportsAssetsHandler
10+
// @Title Get asset Reports
11+
// @Description Get the asset information for the LPS.
12+
// @Success 200 pkg.GetAssetsReportResponse
13+
// @Route /reports/assets [get]
14+
func NewGetReportsAssetsHandler(useCase *reports.GetAssetsReportUseCase) http.HandlerFunc {
15+
return func(w http.ResponseWriter, req *http.Request) {
16+
response, err := useCase.Run(req.Context())
17+
if err != nil {
18+
jsonErr := rest.NewErrorResponseWithDetails("Request error", rest.DetailsFromError(err), false)
19+
rest.JsonErrorResponse(w, http.StatusBadRequest, jsonErr)
20+
return
21+
}
22+
23+
rest.JsonResponseWithBody(w, http.StatusOK, &response)
24+
}
25+
}

internal/adapters/entrypoints/rest/registry/registry.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ type UseCaseRegistry interface {
3939
GetPeginReportUseCase() *reports.GetPeginReportUseCase
4040
GetPegoutReportUseCase() *reports.GetPegoutReportUseCase
4141
GetRevenueReportUseCase() *reports.GetRevenueReportUseCase
42+
GetAssetsReportUseCase() *reports.GetAssetsReportUseCase
4243
}

internal/adapters/entrypoints/rest/routes/management.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ func GetManagementEndpoints(env environment.Environment, useCaseRegistry registr
9191
Method: http.MethodGet,
9292
Handler: handlers.NewGetReportsRevenueHandler(useCaseRegistry.GetRevenueReportUseCase()),
9393
},
94+
{
95+
Path: "/reports/assets",
96+
Method: http.MethodGet,
97+
Handler: handlers.NewGetReportsAssetsHandler(useCaseRegistry.GetAssetsReportUseCase()),
98+
},
9499
{
95100
Path: LoginPath,
96101
Method: http.MethodPost,

internal/adapters/entrypoints/rest/routes/management_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func TestGetManagementEndpoints(t *testing.T) {
3535
registryMock.EXPECT().GetPeginReportUseCase().Return(&reports.GetPeginReportUseCase{})
3636
registryMock.EXPECT().GetPegoutReportUseCase().Return(&reports.GetPegoutReportUseCase{})
3737
registryMock.EXPECT().GetRevenueReportUseCase().Return(&reports.GetRevenueReportUseCase{})
38+
registryMock.EXPECT().GetAssetsReportUseCase().Return(&reports.GetAssetsReportUseCase{})
3839

3940
endpoints := routes.GetManagementEndpoints(environment.Environment{}, registryMock, &mocks.StoreMock{})
4041
specBytes := test.ReadFile(t, "OpenApi.yml")
@@ -43,7 +44,7 @@ func TestGetManagementEndpoints(t *testing.T) {
4344
err := yaml.Unmarshal(specBytes, spec)
4445
require.NoError(t, err)
4546

46-
assert.Len(t, endpoints, 20)
47+
assert.Len(t, endpoints, 21)
4748
for _, endpoint := range endpoints {
4849
if endpoint.Path != routes.IconPath && endpoint.Path != routes.StaticPath {
4950
lowerCaseMethod := strings.ToLower(endpoint.Method)

internal/adapters/entrypoints/rest/routes/routes_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ func setupRegistryMock(registryMock *mocks.UseCaseRegistryMock) {
242242
registryMock.EXPECT().GetPeginReportUseCase().Return(&reports.GetPeginReportUseCase{})
243243
registryMock.EXPECT().GetPegoutReportUseCase().Return(&reports.GetPegoutReportUseCase{})
244244
registryMock.EXPECT().GetRevenueReportUseCase().Return(&reports.GetRevenueReportUseCase{})
245+
registryMock.EXPECT().GetAssetsReportUseCase().Return(&reports.GetAssetsReportUseCase{})
245246
}
246247

247248
func assertHasCorsHeaders(t *testing.T, recorder *httptest.ResponseRecorder) {

internal/configuration/registry/usecase.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ type UseCaseRegistry struct {
6262
getPeginReportUseCase *reports.GetPeginReportUseCase
6363
getPegoutReportUseCase *reports.GetPegoutReportUseCase
6464
getRevenueReportUseCase *reports.GetRevenueReportUseCase
65+
getAssetsReportUseCase *reports.GetAssetsReportUseCase
6566
}
6667

6768
// NewUseCaseRegistry
@@ -245,6 +246,15 @@ func NewUseCaseRegistry(
245246
databaseRegistry.PegoutRepository,
246247
databaseRegistry.PenalizedEventRepository,
247248
),
249+
getAssetsReportUseCase: reports.NewGetAssetsReportUseCase(
250+
btcRegistry.PaymentWallet,
251+
messaging.Rpc,
252+
liquidityProvider,
253+
liquidityProvider,
254+
liquidityProvider,
255+
databaseRegistry.PeginRepository,
256+
databaseRegistry.PegoutRepository,
257+
),
248258
}
249259
}
250260

@@ -371,3 +381,7 @@ func (registry *UseCaseRegistry) GetPegoutReportUseCase() *reports.GetPegoutRepo
371381
func (registry *UseCaseRegistry) GetRevenueReportUseCase() *reports.GetRevenueReportUseCase {
372382
return registry.getRevenueReportUseCase
373383
}
384+
385+
func (registry *UseCaseRegistry) GetAssetsReportUseCase() *reports.GetAssetsReportUseCase {
386+
return registry.getAssetsReportUseCase
387+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package reports
2+
3+
import (
4+
"context"
5+
"github.com/rsksmart/liquidity-provider-server/internal/entities"
6+
"github.com/rsksmart/liquidity-provider-server/internal/entities/blockchain"
7+
"github.com/rsksmart/liquidity-provider-server/internal/entities/liquidity_provider"
8+
"github.com/rsksmart/liquidity-provider-server/internal/entities/quote"
9+
"github.com/rsksmart/liquidity-provider-server/pkg"
10+
)
11+
12+
type GetAssetsReportUseCase struct {
13+
btcWallet blockchain.BitcoinWallet
14+
rsk blockchain.Rpc
15+
lp liquidity_provider.LiquidityProvider
16+
peginProvider liquidity_provider.PeginLiquidityProvider
17+
pegoutProvider liquidity_provider.PegoutLiquidityProvider
18+
peginRepository quote.PeginQuoteRepository
19+
pegoutRepository quote.PegoutQuoteRepository
20+
}
21+
22+
func NewGetAssetsReportUseCase(
23+
wallet blockchain.BitcoinWallet,
24+
rsk blockchain.Rpc,
25+
lp liquidity_provider.LiquidityProvider,
26+
peginProvider liquidity_provider.PeginLiquidityProvider,
27+
pegoutProvider liquidity_provider.PegoutLiquidityProvider,
28+
peginRepository quote.PeginQuoteRepository,
29+
pegoutRepository quote.PegoutQuoteRepository,
30+
) *GetAssetsReportUseCase {
31+
return &GetAssetsReportUseCase{
32+
btcWallet: wallet,
33+
rsk: rsk,
34+
lp: lp,
35+
peginProvider: peginProvider,
36+
pegoutProvider: pegoutProvider,
37+
peginRepository: peginRepository,
38+
pegoutRepository: pegoutRepository,
39+
}
40+
}
41+
42+
func (useCase *GetAssetsReportUseCase) Run(ctx context.Context) (pkg.GetAssetsReportResponse, error) {
43+
response := pkg.GetAssetsReportResponse{
44+
BtcBalance: entities.NewWei(0).AsBigInt(),
45+
RbtcBalance: entities.NewWei(0).AsBigInt(),
46+
BtcLocked: entities.NewWei(0).AsBigInt(),
47+
RbtcLocked: entities.NewWei(0).AsBigInt(),
48+
BtcLiquidity: entities.NewWei(0).AsBigInt(),
49+
RbtcLiquidity: entities.NewWei(0).AsBigInt(),
50+
}
51+
btcBalance, err := useCase.GetBtcBalance()
52+
if err != nil {
53+
return response, err
54+
}
55+
response.BtcBalance = btcBalance.AsBigInt()
56+
rbtcBalance, err := useCase.GetRBTCBalance(ctx)
57+
if err != nil {
58+
return response, err
59+
}
60+
response.RbtcBalance = rbtcBalance.AsBigInt()
61+
62+
rbtcLocked, err := useCase.GetRBTCLocked(ctx)
63+
if err != nil {
64+
return response, err
65+
}
66+
response.RbtcLocked = rbtcLocked.AsBigInt()
67+
68+
lockedBtc, err := useCase.GetBTCLocked(ctx)
69+
if err != nil {
70+
return response, err
71+
}
72+
response.BtcLocked = lockedBtc.AsBigInt()
73+
74+
btcLiquidity, err := useCase.GetBTCLiquidity(ctx)
75+
if err != nil {
76+
return response, err
77+
}
78+
response.BtcLiquidity = btcLiquidity.AsBigInt()
79+
80+
rbtcLiquidity, err := useCase.GetRBTCLiquidity(ctx)
81+
if err != nil {
82+
return response, err
83+
}
84+
response.RbtcLiquidity = rbtcLiquidity.AsBigInt()
85+
return response, nil
86+
}
87+
88+
func (useCase *GetAssetsReportUseCase) GetRBTCLiquidity(ctx context.Context) (*entities.Wei, error) {
89+
rbtcLiquidity, err := useCase.peginProvider.AvailablePeginLiquidity(ctx)
90+
if err != nil {
91+
return nil, err
92+
}
93+
return rbtcLiquidity, nil
94+
}
95+
96+
func (useCase *GetAssetsReportUseCase) GetBTCLiquidity(ctx context.Context) (*entities.Wei, error) {
97+
btcLiquidity, err := useCase.pegoutProvider.AvailablePegoutLiquidity(ctx)
98+
if err != nil {
99+
return nil, err
100+
}
101+
return btcLiquidity, nil
102+
}
103+
104+
func (useCase *GetAssetsReportUseCase) GetBTCLocked(ctx context.Context) (*entities.Wei, error) {
105+
lockedPegout := entities.NewWei(0)
106+
quotes, err := useCase.pegoutRepository.GetRetainedQuoteByState(ctx,
107+
quote.PegoutStateWaitingForDeposit, quote.PegoutStateWaitingForDepositConfirmations,
108+
)
109+
if err != nil {
110+
return nil, err
111+
}
112+
for _, retainedQuote := range quotes {
113+
lockedPegout.Add(lockedPegout, retainedQuote.RequiredLiquidity)
114+
}
115+
116+
return lockedPegout, nil
117+
}
118+
119+
func (useCase *GetAssetsReportUseCase) GetRBTCLocked(ctx context.Context) (*entities.Wei, error) {
120+
lockedPegin := entities.NewWei(0)
121+
peginQuotes, err := useCase.peginRepository.GetRetainedQuoteByState(ctx, quote.PeginStateWaitingForDeposit)
122+
if err != nil {
123+
return nil, err
124+
}
125+
for _, retainedQuote := range peginQuotes {
126+
lockedPegin.Add(lockedPegin, retainedQuote.RequiredLiquidity)
127+
}
128+
pegoutQuotes, err := useCase.pegoutRepository.GetRetainedQuoteByState(ctx, quote.PegoutStateRefundPegOutSucceeded)
129+
if err != nil {
130+
return nil, err
131+
}
132+
for _, retainedQuote := range pegoutQuotes {
133+
lockedPegin.Add(lockedPegin, retainedQuote.RequiredLiquidity)
134+
}
135+
136+
return lockedPegin, nil
137+
}
138+
139+
func (useCase *GetAssetsReportUseCase) GetRBTCBalance(ctx context.Context) (*entities.Wei, error) {
140+
lpsBalance, err := useCase.rsk.Rsk.GetBalance(ctx, useCase.lp.RskAddress())
141+
if err != nil {
142+
return nil, err
143+
}
144+
return lpsBalance, nil
145+
}
146+
147+
func (useCase *GetAssetsReportUseCase) GetBtcBalance() (*entities.Wei, error) {
148+
btcBalance, err := useCase.btcWallet.GetBalance()
149+
if err != nil {
150+
return nil, err
151+
}
152+
return btcBalance, nil
153+
}

0 commit comments

Comments
 (0)