Skip to content

Commit

Permalink
Merge pull request #3031 from HenrikJannsen/add-market-price-api
Browse files Browse the repository at this point in the history
Add MarketPriceRestApi
  • Loading branch information
HenrikJannsen authored Nov 24, 2024
2 parents db65fab + 2dbdfa2 commit 13b00ef
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 6 deletions.
2 changes: 1 addition & 1 deletion bonded-roles/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ dependencies {

implementation(libs.google.gson)
implementation(libs.typesafe.config)
implementation(libs.bundles.jackson)
implementation(libs.bundles.rest.api.libs)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.bonded_roles.market_price;

import bisq.common.currency.Market;
import bisq.common.rest_api.RestApiBase;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Path("/market-price")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Market Price API")
public class MarketPriceRestApi extends RestApiBase {

private final MarketPriceService marketPriceService;

public MarketPriceRestApi(MarketPriceService marketPriceService) {
this.marketPriceService = marketPriceService;
}

@GET
@Path("/quotes")
@Operation(
summary = "Get all market price quotes",
description = "Retrieve all market price quotes",
responses = {
@ApiResponse(
responseCode = "200",
description = "Market price quotes retrieved successfully",
content = @Content(schema = @Schema(implementation = MarketPriceResponse.class))
),
@ApiResponse(responseCode = "404", description = "Market price quotes not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
}
)
public Response getQuotes() {
try {
Map<Market, MarketPrice> marketPriceByCurrencyMap = marketPriceService.getMarketPriceByCurrencyMap();
Map<String, Long> result = marketPriceService.getMarketPriceByCurrencyMap()
.entrySet().stream()
.filter(entry->entry.getKey().getBaseCurrencyCode().equals("BTC")) // We get altcoin quotes as well
.collect(Collectors.toMap(
entry -> entry.getKey().getQuoteCurrencyCode(),
entry -> entry.getValue().getPriceQuote().getValue()
));

if (result.isEmpty()) {
return buildResponse(Response.Status.NOT_FOUND, "No market price quotes found.");
}

return buildResponse(Response.Status.OK, new MarketPriceResponse(result));
} catch (Exception ex) {
log.error("Failed to retrieve market price quotes", ex);
return buildResponse(Response.Status.INTERNAL_SERVER_ERROR, "An error occurred while retrieving market prices.");
}
}

/**
* Response DTO for market price quotes.
*/
@Getter
public static class MarketPriceResponse {
@Schema(description = "Map of currency codes to market price quotes")
private final Map<String, Long> quotes;

public MarketPriceResponse(Map<String, Long> quotes) {
this.quotes = quotes;
}
}
}
26 changes: 26 additions & 0 deletions common/src/main/java/bisq/common/rest_api/RestApiBase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.common.rest_api;

import jakarta.ws.rs.core.Response;

public abstract class RestApiBase {
protected Response buildResponse(Response.Status status, Object entity) {
return Response.status(status).entity(entity).build();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package bisq.rest_api;

import bisq.bonded_roles.BondedRolesService;
import bisq.bonded_roles.market_price.MarketPriceRestApi;
import bisq.chat.ChatService;
import bisq.chat.bisqeasy.offerbook.OfferbookRestApi;
import bisq.network.NetworkService;
Expand All @@ -25,11 +26,13 @@ public RestApiResourceConfig(RestApiService.Config config,
// with AbstractBinder to register resources as classes for Swagger
register(UserIdentityRestApi.class);
register(OfferbookRestApi.class);
register(MarketPriceRestApi.class);

register(new AbstractBinder() {
@Override
protected void configure() {
bind(new UserIdentityRestApi(userService.getUserIdentityService())).to(UserIdentityRestApi.class);
bind(new MarketPriceRestApi(bondedRolesService.getMarketPriceService())).to(MarketPriceRestApi.class);
bind(new OfferbookRestApi(chatService.getBisqEasyOfferbookChannelService())).to(OfferbookRestApi.class);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package bisq.user.identity;

import bisq.common.rest_api.RestApiBase;
import bisq.common.rest_api.error.RestApiException;
import bisq.security.DigestUtil;
import bisq.user.profile.UserProfile;
Expand Down Expand Up @@ -44,7 +45,7 @@
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "User Identity API")
public class UserIdentityRestApi {
public class UserIdentityRestApi extends RestApiBase {
private static final Set<String> MAIN_CURRENCIES = Set.of("usd", "eur", "gbp", "cad", "aud", "rub", "cny", "inr", "ngn");

private final UserIdentityService userIdentityService;
Expand Down Expand Up @@ -175,10 +176,6 @@ public Response createUserIdentityAndPublishUserProfile(CreateUserIdentityReques
}
}

private Response buildResponse(Response.Status status, Object entity) {
return Response.status(status).entity(entity).build();
}

@Data
@Schema(description = "Request payload for creating a new user identity.")
public static class CreateUserIdentityRequest {
Expand Down

0 comments on commit 13b00ef

Please sign in to comment.