Add API functions to support trade chat (#257)

This commit is contained in:
duriancrepe 2022-03-09 04:42:48 -08:00 committed by GitHub
parent e7b4627102
commit 2851319e3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 3 deletions

View file

@ -32,6 +32,7 @@ import bisq.core.payment.payload.PaymentMethod;
import bisq.core.support.dispute.Attachment;
import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.DisputeResult;
import bisq.core.support.messages.ChatMessage;
import bisq.core.trade.Trade;
import bisq.core.trade.statistics.TradeStatistics3;
import bisq.core.trade.statistics.TradeStatisticsManager;
@ -543,4 +544,12 @@ public class CoreApi {
public String getTradeRole(String tradeId) {
return coreTradesService.getTradeRole(tradeId);
}
public List<ChatMessage> getChatMessages(String tradeId) {
return coreTradesService.getChatMessages(tradeId);
}
public void sendChatMessage(String tradeId, String message) {
coreTradesService.sendChatMessage(tradeId, message);
}
}

View file

@ -22,6 +22,10 @@ import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferUtil;
import bisq.core.offer.takeoffer.TakeOfferModel;
import bisq.core.support.dispute.Dispute;
import bisq.core.support.messages.ChatMessage;
import bisq.core.support.traderchat.TradeChatSession;
import bisq.core.support.traderchat.TraderChatManager;
import bisq.core.trade.Tradable;
import bisq.core.trade.Trade;
import bisq.core.trade.TradeManager;
@ -58,10 +62,10 @@ class CoreTradesService {
// exception is made in this case.
private final CoreWalletsService coreWalletsService;
private final BtcWalletService btcWalletService;
private final OfferUtil offerUtil;
private final ClosedTradableManager closedTradableManager;
private final TakeOfferModel takeOfferModel;
private final TradeManager tradeManager;
private final TraderChatManager traderChatManager;
private final TradeUtil tradeUtil;
private final User user;
@ -69,19 +73,19 @@ class CoreTradesService {
public CoreTradesService(CoreContext coreContext,
CoreWalletsService coreWalletsService,
BtcWalletService btcWalletService,
OfferUtil offerUtil,
ClosedTradableManager closedTradableManager,
TakeOfferModel takeOfferModel,
TradeManager tradeManager,
TraderChatManager traderChatManager,
TradeUtil tradeUtil,
User user) {
this.coreContext = coreContext;
this.coreWalletsService = coreWalletsService;
this.btcWalletService = btcWalletService;
this.offerUtil = offerUtil;
this.closedTradableManager = closedTradableManager;
this.takeOfferModel = takeOfferModel;
this.tradeManager = tradeManager;
this.traderChatManager = traderChatManager;
this.tradeUtil = tradeUtil;
this.user = user;
}
@ -237,6 +241,34 @@ class CoreTradesService {
return trades;
}
List<ChatMessage> getChatMessages(String tradeId) {
Trade trade;
var tradeOptional = tradeManager.getTradeById(tradeId);
if (tradeOptional.isPresent()) trade = tradeOptional.get();
else throw new IllegalStateException(format("trade with id '%s' not found", tradeId));
boolean isMaker = tradeManager.isMyOffer(trade.getOffer());
TradeChatSession tradeChatSession = new TradeChatSession(trade, !isMaker);
return tradeChatSession.getObservableChatMessageList();
}
void sendChatMessage(String tradeId, String message) {
Trade trade;
var tradeOptional = tradeManager.getTradeById(tradeId);
if (tradeOptional.isPresent()) trade = tradeOptional.get();
else throw new IllegalStateException(format("trade with id '%s' not found", tradeId));
boolean isMaker = tradeManager.isMyOffer(trade.getOffer());
TradeChatSession tradeChatSession = new TradeChatSession(trade, !isMaker);
ChatMessage chatMessage = new ChatMessage(
traderChatManager.getSupportType(),
tradeChatSession.getTradeId(),
tradeChatSession.getClientId(),
tradeChatSession.isClient(),
message,
traderChatManager.getMyAddress());
traderChatManager.addAndPersistChatMessage(chatMessage);
traderChatManager.sendChatMessage(chatMessage);
}
private boolean isFollowingBuyerProtocol(Trade trade) {
return tradeManager.getTradeProtocol(trade) instanceof BuyerProtocol;
}

View file

@ -19,18 +19,23 @@ package bisq.daemon.grpc;
import bisq.core.api.CoreApi;
import bisq.core.api.model.TradeInfo;
import bisq.core.support.messages.ChatMessage;
import bisq.core.trade.Trade;
import bisq.proto.grpc.ConfirmPaymentReceivedReply;
import bisq.proto.grpc.ConfirmPaymentReceivedRequest;
import bisq.proto.grpc.ConfirmPaymentStartedReply;
import bisq.proto.grpc.ConfirmPaymentStartedRequest;
import bisq.proto.grpc.GetChatMessagesReply;
import bisq.proto.grpc.GetChatMessagesRequest;
import bisq.proto.grpc.GetTradeReply;
import bisq.proto.grpc.GetTradeRequest;
import bisq.proto.grpc.GetTradesReply;
import bisq.proto.grpc.GetTradesRequest;
import bisq.proto.grpc.KeepFundsReply;
import bisq.proto.grpc.KeepFundsRequest;
import bisq.proto.grpc.SendChatMessageReply;
import bisq.proto.grpc.SendChatMessageRequest;
import bisq.proto.grpc.TakeOfferReply;
import bisq.proto.grpc.TakeOfferRequest;
import bisq.proto.grpc.WithdrawFundsReply;
@ -185,6 +190,37 @@ class GrpcTradesService extends TradesImplBase {
}
}
@Override
public void getChatMessages(GetChatMessagesRequest req,
StreamObserver<GetChatMessagesReply> responseObserver) {
try {
var tradeChats = coreApi.getChatMessages(req.getTradeId())
.stream()
.map(msg -> msg.toProtoNetworkEnvelope().getChatMessage())
.collect(Collectors.toList());
var reply = GetChatMessagesReply.newBuilder()
.addAllMessage(tradeChats)
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} catch (Throwable cause) {
exceptionHandler.handleException(log, cause, responseObserver);
}
}
@Override
public void sendChatMessage(SendChatMessageRequest req,
StreamObserver<SendChatMessageReply> responseObserver) {
try {
coreApi.sendChatMessage(req.getTradeId(), req.getMessage());
var reply = SendChatMessageReply.newBuilder().build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} catch (Throwable cause) {
exceptionHandler.handleException(log, cause, responseObserver);
}
}
final ServerInterceptor[] interceptors() {
Optional<ServerInterceptor> rateMeteringInterceptor = rateMeteringInterceptor();
return rateMeteringInterceptor.map(serverInterceptor ->
@ -202,6 +238,8 @@ class GrpcTradesService extends TradesImplBase {
put(getConfirmPaymentReceivedMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
put(getKeepFundsMethod().getFullMethodName(), new GrpcCallRateMeter(1, MINUTES));
put(getWithdrawFundsMethod().getFullMethodName(), new GrpcCallRateMeter(1, MINUTES));
put(getGetChatMessagesMethod().getFullMethodName(), new GrpcCallRateMeter(10, SECONDS));
put(getSendChatMessageMethod().getFullMethodName(), new GrpcCallRateMeter(10, SECONDS));
}}
)));
}

View file

@ -655,6 +655,10 @@ service Trades {
}
rpc WithdrawFunds (WithdrawFundsRequest) returns (WithdrawFundsReply) {
}
rpc GetChatMessages (GetChatMessagesRequest) returns (GetChatMessagesReply) {
}
rpc SendChatMessage (SendChatMessageRequest) returns (SendChatMessageReply) {
}
}
message TakeOfferRequest {
@ -712,6 +716,22 @@ message WithdrawFundsRequest {
message WithdrawFundsReply {
}
message GetChatMessagesRequest {
string trade_id = 1;
}
message GetChatMessagesReply {
repeated ChatMessage message = 1;
}
message SendChatMessageRequest {
string trade_id = 1;
string message = 2;
}
message SendChatMessageReply {
}
message TradeInfo {
OfferInfo offer = 1;
string trade_id = 2;