/*
 * 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/>.
 */

syntax = "proto3";
package io.bisq.protobuffer;

import "pb.proto";

option java_package = "bisq.proto.grpc";
option java_multiple_files = true;

///////////////////////////////////////////////////////////////////////////////////////////
// DisputeAgents
///////////////////////////////////////////////////////////////////////////////////////////

service DisputeAgents {
    rpc RegisterDisputeAgent (RegisterDisputeAgentRequest) returns (RegisterDisputeAgentReply) {
    }
}

message RegisterDisputeAgentRequest {
    string disputeAgentType = 1;
    string registrationKey = 2;
}

message RegisterDisputeAgentReply {
}

///////////////////////////////////////////////////////////////////////////////////////////
// Help
///////////////////////////////////////////////////////////////////////////////////////////

service Help {
    rpc GetMethodHelp (GetMethodHelpRequest) returns (GetMethodHelpReply) {
    }
}

message GetMethodHelpRequest {
    string methodName = 1;
}

message GetMethodHelpReply {
    string methodHelp = 1;
}

///////////////////////////////////////////////////////////////////////////////////////////
// Offers
///////////////////////////////////////////////////////////////////////////////////////////

service Offers {
    rpc GetOffer (GetOfferRequest) returns (GetOfferReply) {
    }
    rpc GetMyOffer (GetMyOfferRequest) returns (GetMyOfferReply) {
    }
    rpc GetOffers (GetOffersRequest) returns (GetOffersReply) {
    }
    rpc GetMyOffers (GetMyOffersRequest) returns (GetMyOffersReply) {
    }
    rpc CreateOffer (CreateOfferRequest) returns (CreateOfferReply) {
    }
    rpc CancelOffer (CancelOfferRequest) returns (CancelOfferReply) {
    }
}

message GetOfferRequest {
    string id = 1;
}

message GetOfferReply {
    OfferInfo offer = 1;
}

message GetMyOfferRequest {
    string id = 1;
}

message GetMyOfferReply {
    OfferInfo offer = 1;
}

message GetOffersRequest {
    string direction = 1;
    string currencyCode = 2;
}

message GetOffersReply {
    repeated OfferInfo offers = 1;
}

message GetMyOffersRequest {
    string direction = 1;
    string currencyCode = 2;
}

message GetMyOffersReply {
    repeated OfferInfo offers = 1;
}

message CreateOfferRequest {
    string currencyCode = 1;
    string direction = 2;
    string price = 3;
    bool useMarketBasedPrice = 4;
    double marketPriceMargin = 5;
    uint64 amount = 6 [jstype = JS_STRING];
    uint64 minAmount = 7 [jstype = JS_STRING];
    double buyerSecurityDeposit = 8;
    uint64 triggerPrice = 9 [jstype = JS_STRING];
    string paymentAccountId = 10;
    string makerFeeCurrencyCode = 11;
}

message CreateOfferReply {
    OfferInfo offer = 1;
}

message CancelOfferRequest {
    string id = 1;
}

message CancelOfferReply {
}

message OfferInfo {
    string id = 1;
    string direction = 2;
    uint64 price = 3;
    bool useMarketBasedPrice = 4;
    double marketPriceMargin = 5;
    uint64 amount = 6;
    uint64 minAmount = 7;
    uint64 volume = 8;
    uint64 minVolume = 9;
    uint64 buyerSecurityDeposit = 10;
    uint64 triggerPrice = 11;
    bool isCurrencyForMakerFeeBtc = 12;
    string paymentAccountId = 13;
    string paymentMethodId = 14;
    string paymentMethodShortName = 15;
    string baseCurrencyCode = 16;
    string counterCurrencyCode = 17;
    uint64 date = 18;
    string state = 19;
    uint64 sellerSecurityDeposit = 20;
    string offerFeePaymentTxId = 21;
    uint64 txFee = 22;
    uint64 makerFee = 23;
}

message AvailabilityResultWithDescription {
    AvailabilityResult availabilityResult = 1;
    string description = 2;
}

///////////////////////////////////////////////////////////////////////////////////////////
// PaymentAccounts
///////////////////////////////////////////////////////////////////////////////////////////

service PaymentAccounts {
    rpc CreatePaymentAccount (CreatePaymentAccountRequest) returns (CreatePaymentAccountReply) {
    }
    rpc GetPaymentAccounts (GetPaymentAccountsRequest) returns (GetPaymentAccountsReply) {
    }
    rpc GetPaymentMethods (GetPaymentMethodsRequest) returns (GetPaymentMethodsReply) {
    }
    rpc GetPaymentAccountForm (GetPaymentAccountFormRequest) returns (GetPaymentAccountFormReply) {
    }
    rpc CreateCryptoCurrencyPaymentAccount (CreateCryptoCurrencyPaymentAccountRequest) returns (CreateCryptoCurrencyPaymentAccountReply) {
    }
    rpc GetCryptoCurrencyPaymentMethods (GetCryptoCurrencyPaymentMethodsRequest) returns (GetCryptoCurrencyPaymentMethodsReply) {
    }
}

message CreatePaymentAccountRequest {
    string paymentAccountForm = 1;
}

message CreatePaymentAccountReply {
    PaymentAccount paymentAccount = 1;
}

message GetPaymentAccountsRequest {
}

message GetPaymentAccountsReply {
    repeated PaymentAccount paymentAccounts = 1;
}

message GetPaymentMethodsRequest {
}

message GetPaymentMethodsReply {
    repeated PaymentMethod paymentMethods = 1;
}

message GetPaymentAccountFormRequest {
    string paymentMethodId = 1;
}

message GetPaymentAccountFormReply {
    string paymentAccountFormJson = 1;
}

message CreateCryptoCurrencyPaymentAccountRequest {
    string accountName = 1;
    string currencyCode = 2;
    string address = 3;
    bool tradeInstant = 4;
}

message CreateCryptoCurrencyPaymentAccountReply {
    PaymentAccount paymentAccount = 1;
}

message GetCryptoCurrencyPaymentMethodsRequest {
}

message GetCryptoCurrencyPaymentMethodsReply {
    repeated PaymentMethod paymentMethods = 1;
}

///////////////////////////////////////////////////////////////////////////////////////////
// Price
///////////////////////////////////////////////////////////////////////////////////////////

service Price {
    rpc GetMarketPrice (MarketPriceRequest) returns (MarketPriceReply) {
    }
}

message MarketPriceRequest {
    string currencyCode = 1;
}

message MarketPriceReply {
    double price = 1;
}

///////////////////////////////////////////////////////////////////////////////////////////
// GetTradeStatistics
///////////////////////////////////////////////////////////////////////////////////////////

service GetTradeStatistics {
    rpc GetTradeStatistics (GetTradeStatisticsRequest) returns (GetTradeStatisticsReply) {
    }
}

message GetTradeStatisticsRequest {
}

message GetTradeStatisticsReply {
    repeated TradeStatistics3 TradeStatistics = 1;
}

///////////////////////////////////////////////////////////////////////////////////////////
// Shutdown
///////////////////////////////////////////////////////////////////////////////////////////

service ShutdownServer {
    rpc Stop (StopRequest) returns (StopReply) {
    }
}

message StopRequest {
}

message StopReply {
}

///////////////////////////////////////////////////////////////////////////////////////////
// Trades
///////////////////////////////////////////////////////////////////////////////////////////

service Trades {
    rpc GetTrade (GetTradeRequest) returns (GetTradeReply) {
    }
    rpc TakeOffer (TakeOfferRequest) returns (TakeOfferReply) {
    }
    rpc ConfirmPaymentStarted (ConfirmPaymentStartedRequest) returns (ConfirmPaymentStartedReply) {
    }
    rpc ConfirmPaymentReceived (ConfirmPaymentReceivedRequest) returns (ConfirmPaymentReceivedReply) {
    }
    rpc KeepFunds (KeepFundsRequest) returns (KeepFundsReply) {
    }
    rpc WithdrawFunds (WithdrawFundsRequest) returns (WithdrawFundsReply) {
    }
}

message TakeOfferRequest {
    string offerId = 1;
    string paymentAccountId = 2;
    string takerFeeCurrencyCode = 3;
}

message TakeOfferReply {
    TradeInfo trade = 1;
    AvailabilityResultWithDescription failureReason = 2;
}

message ConfirmPaymentStartedRequest {
    string tradeId = 1;
}

message ConfirmPaymentStartedReply {
}

message ConfirmPaymentReceivedRequest {
    string tradeId = 1;
}

message ConfirmPaymentReceivedReply {
}

message GetTradeRequest {
    string tradeId = 1;
}

message GetTradeReply {
    TradeInfo trade = 1;
}

message KeepFundsRequest {
    string tradeId = 1;
}

message KeepFundsReply {
}

message WithdrawFundsRequest {
    string tradeId = 1;
    string address = 2;
    string memo = 3;
}

message WithdrawFundsReply {
}

message TradeInfo {
    OfferInfo offer = 1;
    string tradeId = 2;
    string shortId = 3;
    uint64 date = 4;
    string role = 5;
    uint64 txFeeAsLong = 7;
    uint64 takerFeeAsLong = 8;
    string takerFeeTxId = 9;
    reserved 10; // was depositTxId
    string payoutTxId = 11;
    uint64 tradeAmountAsLong = 12;
    uint64 tradePrice = 13;
    string tradingPeerNodeAddress = 14;
    string state = 15;
    string phase = 16;
    string tradePeriodState = 17;
    bool isDepositPublished = 18;
    bool isDepositConfirmed = 19;
    bool isFiatSent = 20;
    bool isFiatReceived = 21;
    bool isPayoutPublished = 22;
    bool isWithdrawn = 23;
    string contractAsJson = 24;
    ContractInfo contract = 25;
    
    string makerDepositTxId = 100;
    string takerDepositTxId = 101;
}

message ContractInfo {
    string buyerNodeAddress = 1;
    string sellerNodeAddress = 2;
    reserved 3; // was mediatorNodeAddress
    reserved 4; // was refundAgendNodeAddress
    bool isBuyerMakerAndSellerTaker = 5;
    string makerAccountId = 6;
    string takerAccountId = 7;
    PaymentAccountPayloadInfo makerPaymentAccountPayload = 8;
    PaymentAccountPayloadInfo takerPaymentAccountPayload = 9;
    string makerPayoutAddressString = 10;
    string takerPayoutAddressString = 11;
    uint64 lockTime = 12;
    
    string arbitratorNodeAddress = 100;
}

message PaymentAccountPayloadInfo {
    string id = 1;
    string paymentMethodId = 2;
    string address = 3;
}

///////////////////////////////////////////////////////////////////////////////////////////
// Transactions
///////////////////////////////////////////////////////////////////////////////////////////

message TxFeeRateInfo {
    bool useCustomTxFeeRate = 1;
    uint64 customTxFeeRate = 2;
    uint64 feeServiceRate = 3;
    uint64 lastFeeServiceRequestTs = 4;
    uint64 minFeeServiceRate = 5;
}

message TxInfo {
    string txId = 1;
    uint64 inputSum = 2;
    uint64 outputSum = 3;
    uint64 fee = 4;
    int32 size = 5;
    bool isPending = 6;
    string memo = 7;
}

///////////////////////////////////////////////////////////////////////////////////////////
// Wallets
///////////////////////////////////////////////////////////////////////////////////////////

service Wallets {
    rpc GetBalances (GetBalancesRequest) returns (GetBalancesReply) {
    }
    rpc GetAddressBalance (GetAddressBalanceRequest) returns (GetAddressBalanceReply) {
    }
    rpc GetUnusedBsqAddress (GetUnusedBsqAddressRequest) returns (GetUnusedBsqAddressReply) {
    }
    rpc SendBsq (SendBsqRequest) returns (SendBsqReply) {
    }
    rpc SendBtc (SendBtcRequest) returns (SendBtcReply) {
    }
    rpc VerifyBsqSentToAddress (VerifyBsqSentToAddressRequest) returns (VerifyBsqSentToAddressReply) {
    }
    rpc GetTxFeeRate (GetTxFeeRateRequest) returns (GetTxFeeRateReply) {
    }
    rpc SetTxFeeRatePreference (SetTxFeeRatePreferenceRequest) returns (SetTxFeeRatePreferenceReply) {
    }
    rpc UnsetTxFeeRatePreference (UnsetTxFeeRatePreferenceRequest) returns (UnsetTxFeeRatePreferenceReply) {
    }
    rpc GetTransaction (GetTransactionRequest) returns (GetTransactionReply) {
    }
    rpc GetFundingAddresses (GetFundingAddressesRequest) returns (GetFundingAddressesReply) {
    }
    rpc SetWalletPassword (SetWalletPasswordRequest) returns (SetWalletPasswordReply) {
    }
    rpc RemoveWalletPassword (RemoveWalletPasswordRequest) returns (RemoveWalletPasswordReply) {
    }
    rpc LockWallet (LockWalletRequest) returns (LockWalletReply) {
    }
    rpc UnlockWallet (UnlockWalletRequest) returns (UnlockWalletReply) {
    }
}

message GetBalancesRequest {
    string currencyCode = 1;
}

message GetBalancesReply {
    BalancesInfo balances = 1;
}

message GetAddressBalanceRequest {
    string address = 1;
}

message GetAddressBalanceReply {
    AddressBalanceInfo addressBalanceInfo = 1;
}

message GetUnusedBsqAddressRequest {
}

message GetUnusedBsqAddressReply {
     string address = 1;
}

message SendBsqRequest {
    string address = 1;
    string amount = 2;
    string txFeeRate = 3;
}

message SendBsqReply {
    TxInfo txInfo = 1;
}

message SendBtcRequest {
    string address = 1;
    string amount = 2;
    string txFeeRate = 3;
    string memo = 4;
}

message SendBtcReply {
    TxInfo txInfo = 1;
}

message VerifyBsqSentToAddressRequest {
    string address = 1;
    string amount = 2;
}

message VerifyBsqSentToAddressReply {
    bool isAmountReceived = 1;
}

message GetTxFeeRateRequest {
}

message GetTxFeeRateReply {
    TxFeeRateInfo txFeeRateInfo = 1;
}

message SetTxFeeRatePreferenceRequest {
    uint64 txFeeRatePreference = 1;
}

message SetTxFeeRatePreferenceReply {
    TxFeeRateInfo txFeeRateInfo = 1;
}

message UnsetTxFeeRatePreferenceRequest {
}

message UnsetTxFeeRatePreferenceReply {
    TxFeeRateInfo txFeeRateInfo = 1;
}

message GetTransactionRequest {
    string txId = 1;
}

message GetTransactionReply {
    TxInfo txInfo = 1;
}

message GetFundingAddressesRequest {
}

message GetFundingAddressesReply {
    repeated AddressBalanceInfo addressBalanceInfo = 1;
}

message SetWalletPasswordRequest {
    string password = 1;
    string newPassword = 2;
}

message SetWalletPasswordReply {
}

message RemoveWalletPasswordRequest {
    string password = 1;
}

message RemoveWalletPasswordReply {
}

message LockWalletRequest {
}

message LockWalletReply {
}

message UnlockWalletRequest {
    string password = 1;
    uint64 timeout = 2;
}

message UnlockWalletReply {
}

message BalancesInfo {
    // Field names are shortened for readability's sake, i.e.,
    // balancesInfo.getBtc().getAvailableBalance() is cleaner than
    // balancesInfo.getBtcBalanceInfo().getAvailableBalance().
    BsqBalanceInfo bsq = 1;
    BtcBalanceInfo btc = 2;
    XmrBalanceInfo xmr = 3;
}

message BsqBalanceInfo {
    uint64 availableConfirmedBalance = 1;
    uint64 unverifiedBalance = 2;
    uint64 unconfirmedChangeBalance = 3;
    uint64 lockedForVotingBalance = 4;
    uint64 lockupBondsBalance = 5;
    uint64 unlockingBondsBalance = 6;
}

message BtcBalanceInfo {
    uint64 availableBalance = 1;
    uint64 reservedBalance = 2;
    uint64 totalAvailableBalance = 3;
    uint64 lockedBalance = 4;
}

message XmrBalanceInfo {
    uint64 unlockedBalance = 1 [jstype = JS_STRING];
    uint64 lockedBalance = 2 [jstype = JS_STRING];
    uint64 reservedOfferBalance = 3 [jstype = JS_STRING];
    uint64 reservedTradeBalance = 4 [jstype = JS_STRING];
}

message AddressBalanceInfo {
    string address = 1;
    int64 balance = 2;
    int64 numConfirmations = 3;
    bool isAddressUnused = 4;
}

///////////////////////////////////////////////////////////////////////////////////////////
// Version
///////////////////////////////////////////////////////////////////////////////////////////

service GetVersion {
    rpc GetVersion (GetVersionRequest) returns (GetVersionReply) {
    }
}

message GetVersionRequest {
}

message GetVersionReply {
    string version = 1;
}