mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Make rpc GetOfferCategory service work for my+avail offers
There are some use cases where the CLI needs to know what kind of offer is being acted on before the request is made, For example: There are differences between a BsqSwap 'takeoffer'request, and a v1 'takeoffer' request. A BsqSwap offer cannot be edited by an 'editoffer' request, and an attempt should be blocked by the CLI. - Append isMyOffer GetOfferCategoryRequest rpc msg def. - Adjust daemon.grpc services for new boolean GetOfferCategoryRequest param. - Adjust core.api for new boolean GetOfferCategoryRequest param. - Add validation check in core.api EditOfferValidator to block attempt to edit a BsqSwap offer. - Refactor CoreOffersService get*offer(id) methods to optionally throw excpetions.
This commit is contained in:
parent
05d1916ae9
commit
64f228d872
@ -120,16 +120,16 @@ public class CoreApi {
|
|||||||
// Offers
|
// Offers
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public boolean isAvailableFiatOffer(String id) {
|
public boolean isFiatOffer(String id, boolean isMyOffer) {
|
||||||
return coreOffersService.isAvailableFiatOffer(id);
|
return coreOffersService.isFiatOffer(id, isMyOffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAvailableAltcoinOffer(String id) {
|
public boolean isAltcoinOffer(String id, boolean isMyOffer) {
|
||||||
return coreOffersService.isAvailableAltcoinOffer(id);
|
return coreOffersService.isAltcoinOffer(id, isMyOffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAvailableBsqSwapOffer(String id) {
|
public boolean isBsqSwapOffer(String id, boolean isMyOffer) {
|
||||||
return coreOffersService.isAvailableBsqSwapOffer(id);
|
return coreOffersService.isBsqSwapOffer(id, isMyOffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Offer getBsqSwapOffer(String id) {
|
public Offer getBsqSwapOffer(String id) {
|
||||||
|
@ -48,6 +48,8 @@ import java.math.BigDecimal;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -61,8 +63,6 @@ import static bisq.core.locale.CurrencyUtil.isCryptoCurrency;
|
|||||||
import static bisq.core.offer.Offer.State;
|
import static bisq.core.offer.Offer.State;
|
||||||
import static bisq.core.offer.OfferDirection.BUY;
|
import static bisq.core.offer.OfferDirection.BUY;
|
||||||
import static bisq.core.offer.OfferUtil.getRandomOfferId;
|
import static bisq.core.offer.OfferUtil.getRandomOfferId;
|
||||||
import static bisq.core.offer.OfferUtil.isAltcoinOffer;
|
|
||||||
import static bisq.core.offer.OfferUtil.isFiatOffer;
|
|
||||||
import static bisq.core.offer.OpenOffer.State.AVAILABLE;
|
import static bisq.core.offer.OpenOffer.State.AVAILABLE;
|
||||||
import static bisq.core.offer.OpenOffer.State.DEACTIVATED;
|
import static bisq.core.offer.OpenOffer.State.DEACTIVATED;
|
||||||
import static bisq.core.payment.PaymentAccountUtil.isPaymentAccountValidForOffer;
|
import static bisq.core.payment.PaymentAccountUtil.isPaymentAccountValidForOffer;
|
||||||
@ -81,6 +81,9 @@ class CoreOffersService {
|
|||||||
private final Supplier<Comparator<OpenOffer>> openOfferPriceComparator = () ->
|
private final Supplier<Comparator<OpenOffer>> openOfferPriceComparator = () ->
|
||||||
comparing(openOffer -> openOffer.getOffer().getPrice());
|
comparing(openOffer -> openOffer.getOffer().getPrice());
|
||||||
|
|
||||||
|
private final BiFunction<String, Boolean, Offer> toOfferWithId = (id, isMyOffer) ->
|
||||||
|
isMyOffer ? getMyOffer(id).getOffer() : getOffer(id);
|
||||||
|
|
||||||
private final CoreContext coreContext;
|
private final CoreContext coreContext;
|
||||||
private final KeyRing keyRing;
|
private final KeyRing keyRing;
|
||||||
// Dependencies on core api services in this package must be kept to an absolute
|
// Dependencies on core api services in this package must be kept to an absolute
|
||||||
@ -121,63 +124,48 @@ class CoreOffersService {
|
|||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isAvailableFiatOffer(String id) {
|
boolean isFiatOffer(String id, boolean isMyOffer) {
|
||||||
return isFiatOffer(getOffer(id));
|
var offer = toOfferWithId.apply(id, isMyOffer);
|
||||||
|
return OfferUtil.isFiatOffer(offer);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isAvailableAltcoinOffer(String id) {
|
boolean isAltcoinOffer(String id, boolean isMyOffer) {
|
||||||
return isAltcoinOffer(getOffer(id));
|
var offer = toOfferWithId.apply(id, isMyOffer);
|
||||||
|
return OfferUtil.isAltcoinOffer(offer);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isAvailableBsqSwapOffer(String id) {
|
boolean isBsqSwapOffer(String id, boolean isMyOffer) {
|
||||||
var offer = getOffer(id);
|
var offer = toOfferWithId.apply(id, isMyOffer);
|
||||||
return offer.isBsqSwapOffer();
|
return offer.isBsqSwapOffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
Offer getBsqSwapOffer(String id) {
|
|
||||||
return offerBookService.getOffers().stream()
|
|
||||||
.filter(o -> o.getId().equals(id))
|
|
||||||
.filter(o -> !o.isMyOffer(keyRing))
|
|
||||||
.filter(o -> offerFilterService.canTakeOffer(o, coreContext.isApiUser()).isValid())
|
|
||||||
.filter(o -> o.isBsqSwapOffer())
|
|
||||||
.findAny().orElseThrow(() ->
|
|
||||||
new IllegalStateException(format("offer with id '%s' not found", id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Offer getOffer(String id) {
|
Offer getOffer(String id) {
|
||||||
return offerBookService.getOffers().stream()
|
return findAvailableOffer(id).orElseThrow(() ->
|
||||||
.filter(o -> o.getId().equals(id))
|
new IllegalStateException(format("offer with id '%s' not found", id)));
|
||||||
.filter(o -> !o.isMyOffer(keyRing))
|
|
||||||
.filter(o -> offerFilterService.canTakeOffer(o, coreContext.isApiUser()).isValid())
|
|
||||||
.findAny().orElseThrow(() ->
|
|
||||||
new IllegalStateException(format("offer with id '%s' not found", id)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenOffer getMyOffer(String id) {
|
OpenOffer getMyOffer(String id) {
|
||||||
return openOfferManager.getObservableList().stream()
|
return findMyOpenOffer(id).orElseThrow(() ->
|
||||||
.filter(o -> o.getId().equals(id))
|
new IllegalStateException(format("offer with id '%s' not found", id)));
|
||||||
.filter(o -> o.getOffer().isMyOffer(keyRing))
|
}
|
||||||
.findAny().orElseThrow(() ->
|
|
||||||
new IllegalStateException(format("offer with id '%s' not found", id)));
|
Offer getBsqSwapOffer(String id) {
|
||||||
|
return findAvailableBsqSwapOffer(id).orElseThrow(() ->
|
||||||
|
new IllegalStateException(format("offer with id '%s' not found", id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Offer getMyBsqSwapOffer(String id) {
|
Offer getMyBsqSwapOffer(String id) {
|
||||||
return offerBookService.getOffers().stream()
|
return findMyBsqSwapOffer(id).orElseThrow(() ->
|
||||||
.filter(o -> o.getId().equals(id))
|
new IllegalStateException(format("offer with id '%s' not found", id)));
|
||||||
.filter(o -> o.isMyOffer(keyRing))
|
|
||||||
.filter(o -> o.isBsqSwapOffer())
|
|
||||||
.findAny().orElseThrow(() ->
|
|
||||||
new IllegalStateException(format("offer with id '%s' not found", id)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Offer> getBsqSwapOffers(String direction) {
|
List<Offer> getBsqSwapOffers(String direction) {
|
||||||
var offers = offerBookService.getOffers().stream()
|
return offerBookService.getOffers().stream()
|
||||||
.filter(o -> !o.isMyOffer(keyRing))
|
.filter(o -> !o.isMyOffer(keyRing))
|
||||||
.filter(o -> o.getDirection().name().equalsIgnoreCase(direction))
|
.filter(o -> o.getDirection().name().equalsIgnoreCase(direction))
|
||||||
.filter(o -> o.isBsqSwapOffer())
|
.filter(Offer::isBsqSwapOffer)
|
||||||
.sorted(priceComparator(direction))
|
.sorted(priceComparator(direction))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return offers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Offer> getOffers(String direction, String currencyCode) {
|
List<Offer> getOffers(String direction, String currencyCode) {
|
||||||
@ -198,13 +186,12 @@ class CoreOffersService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Offer> getMyBsqSwapOffers(String direction) {
|
List<Offer> getMyBsqSwapOffers(String direction) {
|
||||||
var offers = offerBookService.getOffers().stream()
|
return offerBookService.getOffers().stream()
|
||||||
.filter(o -> o.isMyOffer(keyRing))
|
.filter(o -> o.isMyOffer(keyRing))
|
||||||
.filter(o -> o.getDirection().name().equalsIgnoreCase(direction))
|
.filter(o -> o.getDirection().name().equalsIgnoreCase(direction))
|
||||||
.filter(Offer::isBsqSwapOffer)
|
.filter(Offer::isBsqSwapOffer)
|
||||||
.sorted(priceComparator(direction))
|
.sorted(priceComparator(direction))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return offers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenOffer getMyOpenBsqSwapOffer(String id) {
|
OpenOffer getMyOpenBsqSwapOffer(String id) {
|
||||||
@ -393,6 +380,38 @@ class CoreOffersService {
|
|||||||
throw new IllegalStateException(offer.getErrorMessage());
|
throw new IllegalStateException(offer.getErrorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<Offer> findAvailableBsqSwapOffer(String id) {
|
||||||
|
return offerBookService.getOffers().stream()
|
||||||
|
.filter(o -> o.getId().equals(id))
|
||||||
|
.filter(o -> !o.isMyOffer(keyRing))
|
||||||
|
.filter(o -> offerFilterService.canTakeOffer(o, coreContext.isApiUser()).isValid())
|
||||||
|
.filter(Offer::isBsqSwapOffer)
|
||||||
|
.findAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Offer> findMyBsqSwapOffer(String id) {
|
||||||
|
return offerBookService.getOffers().stream()
|
||||||
|
.filter(o -> o.getId().equals(id))
|
||||||
|
.filter(o -> o.isMyOffer(keyRing))
|
||||||
|
.filter(Offer::isBsqSwapOffer)
|
||||||
|
.findAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Offer> findAvailableOffer(String id) {
|
||||||
|
return offerBookService.getOffers().stream()
|
||||||
|
.filter(o -> o.getId().equals(id))
|
||||||
|
.filter(o -> !o.isMyOffer(keyRing))
|
||||||
|
.filter(o -> offerFilterService.canTakeOffer(o, coreContext.isApiUser()).isValid())
|
||||||
|
.findAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<OpenOffer> findMyOpenOffer(String id) {
|
||||||
|
return openOfferManager.getObservableList().stream()
|
||||||
|
.filter(o -> o.getId().equals(id))
|
||||||
|
.filter(o -> o.getOffer().isMyOffer(keyRing))
|
||||||
|
.findAny();
|
||||||
|
}
|
||||||
|
|
||||||
private OfferPayload getMergedOfferPayload(OpenOffer openOffer,
|
private OfferPayload getMergedOfferPayload(OpenOffer openOffer,
|
||||||
String editedPriceAsString,
|
String editedPriceAsString,
|
||||||
double editedMarketPriceMargin,
|
double editedMarketPriceMargin,
|
||||||
|
@ -45,7 +45,8 @@ class EditOfferValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void validate() {
|
void validate() {
|
||||||
log.info("Verifying 'editoffer' params OK for editType {}", editType);
|
log.info("Verifying 'editoffer' params for editType {}", editType);
|
||||||
|
checkNotBsqSwapOffer();
|
||||||
switch (editType) {
|
switch (editType) {
|
||||||
case ACTIVATION_STATE_ONLY: {
|
case ACTIVATION_STATE_ONLY: {
|
||||||
validateEditedActivationState();
|
validateEditedActivationState();
|
||||||
@ -138,4 +139,11 @@ class EditOfferValidator {
|
|||||||
currentlyOpenOffer.getId()));
|
currentlyOpenOffer.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkNotBsqSwapOffer() {
|
||||||
|
if (currentlyOpenOffer.getOffer().isBsqSwapOffer()) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
format("cannot edit bsq swap offer with id '%s'", currentlyOpenOffer.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ class GrpcOffersService extends OffersImplBase {
|
|||||||
public void getOfferCategory(GetOfferCategoryRequest req,
|
public void getOfferCategory(GetOfferCategoryRequest req,
|
||||||
StreamObserver<GetOfferCategoryReply> responseObserver) {
|
StreamObserver<GetOfferCategoryReply> responseObserver) {
|
||||||
try {
|
try {
|
||||||
OfferCategory category = getAvailableOfferCategory(req.getId());
|
OfferCategory category = getOfferCategory(req.getId(), req.getIsMyOffer());
|
||||||
var reply = newBuilder()
|
var reply = newBuilder()
|
||||||
.setOfferCategory(category)
|
.setOfferCategory(category)
|
||||||
.build();
|
.build();
|
||||||
@ -335,6 +335,7 @@ class GrpcOffersService extends OffersImplBase {
|
|||||||
return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
|
return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
|
||||||
.or(() -> Optional.of(CallRateMeteringInterceptor.valueOf(
|
.or(() -> Optional.of(CallRateMeteringInterceptor.valueOf(
|
||||||
new HashMap<>() {{
|
new HashMap<>() {{
|
||||||
|
put(getGetOfferCategoryMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
||||||
put(getGetOfferMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
put(getGetOfferMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
||||||
put(getGetMyOfferMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
put(getGetMyOfferMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
||||||
put(getGetOffersMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
put(getGetOffersMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
||||||
@ -346,12 +347,12 @@ class GrpcOffersService extends OffersImplBase {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private OfferCategory getAvailableOfferCategory(String offerId) {
|
private OfferCategory getOfferCategory(String offerId, boolean isMyOffer) {
|
||||||
if (coreApi.isAvailableAltcoinOffer(offerId))
|
if (coreApi.isAltcoinOffer(offerId, isMyOffer))
|
||||||
return ALTCOIN;
|
return ALTCOIN;
|
||||||
else if (coreApi.isAvailableFiatOffer(offerId))
|
else if (coreApi.isFiatOffer(offerId, isMyOffer))
|
||||||
return FIAT;
|
return FIAT;
|
||||||
else if (coreApi.isAvailableBsqSwapOffer(offerId))
|
else if (coreApi.isBsqSwapOffer(offerId, isMyOffer))
|
||||||
return BSQ_SWAP;
|
return BSQ_SWAP;
|
||||||
else
|
else
|
||||||
return UNKNOWN;
|
return UNKNOWN;
|
||||||
|
@ -79,7 +79,7 @@ class GrpcTradesService extends TradesImplBase {
|
|||||||
exceptionHandler,
|
exceptionHandler,
|
||||||
log);
|
log);
|
||||||
|
|
||||||
if (coreApi.isAvailableBsqSwapOffer(req.getOfferId())) {
|
if (coreApi.isBsqSwapOffer(req.getOfferId(), false)) {
|
||||||
coreApi.takeBsqSwapOffer(req.getOfferId(),
|
coreApi.takeBsqSwapOffer(req.getOfferId(),
|
||||||
bsqSwapTrade -> {
|
bsqSwapTrade -> {
|
||||||
var reply = buildTakeOfferReply(bsqSwapTrade);
|
var reply = buildTakeOfferReply(bsqSwapTrade);
|
||||||
|
@ -92,6 +92,7 @@ service Offers {
|
|||||||
|
|
||||||
message GetOfferCategoryRequest {
|
message GetOfferCategoryRequest {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
|
bool isMyOffer = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetOfferCategoryReply {
|
message GetOfferCategoryReply {
|
||||||
|
Loading…
Reference in New Issue
Block a user