Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'gettrade' to api method CLI #4704

Merged
merged 14 commits into from
Oct 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,4 @@ protected final void verifyExpectedTradeStateAndPhase(TradeInfo trade,
assertEquals(expectedState.name(), trade.getState());
assertEquals(expectedPhase.name(), trade.getPhase());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.apitest.config.BisqAppConfig.bobdaemon;
import static bisq.cli.TradeFormat.format;
import static bisq.core.trade.Trade.Phase.DEPOSIT_CONFIRMED;
import static bisq.core.trade.Trade.Phase.DEPOSIT_PUBLISHED;
import static bisq.core.trade.Trade.Phase.FIAT_SENT;
Expand All @@ -39,6 +40,7 @@
import static bisq.core.trade.Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN;
import static bisq.core.trade.Trade.State.SELLER_PUBLISHED_DEPOSIT_TX;
import static bisq.core.trade.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG;
import static java.lang.System.out;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
Expand Down Expand Up @@ -85,10 +87,12 @@ public void testTakeAlicesBuyOffer() {

trade = getTrade(bobdaemon, trade.getTradeId());
verifyExpectedTradeStateAndPhase(trade, SELLER_PUBLISHED_DEPOSIT_TX, DEPOSIT_PUBLISHED);
out.println(format(trade));

genBtcBlocksThenWait(1, 2250);
trade = getTrade(bobdaemon, trade.getTradeId());
verifyExpectedTradeStateAndPhase(trade, DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN, DEPOSIT_CONFIRMED);
out.println(format(trade));
} catch (StatusRuntimeException e) {
fail(e);
}
Expand All @@ -107,6 +111,7 @@ public void testAlicesConfirmPaymentStarted() {
trade = getTrade(alicedaemon, tradeId);
assertEquals(OFFER_FEE_PAID.name(), trade.getOffer().getState());
verifyExpectedTradeStateAndPhase(trade, BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG, FIAT_SENT);
out.println(format(trade));
} catch (StatusRuntimeException e) {
fail(e);
}
Expand All @@ -125,5 +130,6 @@ public void testBobsConfirmPaymentReceived() {
// TODO is this a bug? Why is offer.state == available?
assertEquals(AVAILABLE.name(), trade.getOffer().getState());
verifyExpectedTradeStateAndPhase(trade, SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG, PAYOUT_PUBLISHED);
out.println(format(trade));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.apitest.config.BisqAppConfig.bobdaemon;
import static bisq.cli.TradeFormat.format;
import static bisq.core.trade.Trade.Phase.DEPOSIT_CONFIRMED;
import static bisq.core.trade.Trade.Phase.DEPOSIT_PUBLISHED;
import static bisq.core.trade.Trade.Phase.FIAT_SENT;
Expand All @@ -39,6 +40,7 @@
import static bisq.core.trade.Trade.State.BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG;
import static bisq.core.trade.Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN;
import static bisq.core.trade.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG;
import static java.lang.System.out;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
Expand Down Expand Up @@ -86,10 +88,12 @@ public void testTakeAlicesSellOffer() {

trade = getTrade(bobdaemon, trade.getTradeId());
verifyExpectedTradeStateAndPhase(trade, BUYER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG, DEPOSIT_PUBLISHED);
out.println(format(trade));

genBtcBlocksThenWait(1, 2250);
trade = getTrade(bobdaemon, trade.getTradeId());
verifyExpectedTradeStateAndPhase(trade, DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN, DEPOSIT_CONFIRMED);
out.println(format(trade));

} catch (StatusRuntimeException e) {
fail(e);
Expand All @@ -110,6 +114,8 @@ public void testBobsConfirmPaymentStarted() {
// TODO is this a bug? Why is offer.state == available?
assertEquals(AVAILABLE.name(), trade.getOffer().getState());
verifyExpectedTradeStateAndPhase(trade, BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG, FIAT_SENT);

out.println(format(trade));
} catch (StatusRuntimeException e) {
fail(e);
}
Expand All @@ -127,5 +133,6 @@ public void testAlicesConfirmPaymentReceived() {
trade = getTrade(alicedaemon, tradeId);
assertEquals(OFFER_FEE_PAID.name(), trade.getOffer().getState());
verifyExpectedTradeStateAndPhase(trade, SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG, PAYOUT_PUBLISHED);
out.println(format(trade));
}
}
15 changes: 15 additions & 0 deletions cli/src/main/java/bisq/cli/CliMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import bisq.proto.grpc.GetOfferRequest;
import bisq.proto.grpc.GetOffersRequest;
import bisq.proto.grpc.GetPaymentAccountsRequest;
import bisq.proto.grpc.GetTradeRequest;
import bisq.proto.grpc.GetVersionRequest;
import bisq.proto.grpc.LockWalletRequest;
import bisq.proto.grpc.RegisterDisputeAgentRequest;
Expand Down Expand Up @@ -74,6 +75,7 @@ private enum Method {
getoffer,
getoffers,
takeoffer,
gettrade,
confirmpaymentstarted,
confirmpaymentreceived,
createpaymentacct,
Expand Down Expand Up @@ -275,6 +277,18 @@ public static void run(String[] args) {
out.printf("trade '%s' successfully taken", reply.getTrade().getShortId());
return;
}
case gettrade: {
if (nonOptionArgs.size() < 2)
throw new IllegalArgumentException("incorrect parameter count, expecting trade id");

var tradeId = nonOptionArgs.get(1);
var request = GetTradeRequest.newBuilder()
.setTradeId(tradeId)
.build();
var reply = tradesService.getTrade(request);
out.println(TradeFormat.format(reply.getTrade()));
return;
}
case confirmpaymentstarted: {
if (nonOptionArgs.size() < 2)
throw new IllegalArgumentException("incorrect parameter count, expecting trade id");
Expand Down Expand Up @@ -427,6 +441,7 @@ private static void printHelp(OptionParser parser, PrintStream stream) {
stream.format(rowFormat, "getoffer", "offer id", "Get current offer with id");
stream.format(rowFormat, "getoffers", "buy | sell, currency code", "Get current offers");
stream.format(rowFormat, "takeoffer", "offer id", "Take offer with id");
stream.format(rowFormat, "gettrade", "trade id", "Get trade details and protocol status");
stream.format(rowFormat, "confirmpaymentstarted", "trade id", "Confirm payment started");
stream.format(rowFormat, "confirmpaymentreceived", "trade id", "Confirm payment received");
stream.format(rowFormat, "createpaymentacct", "account name, account number, currency code", "Create PerfectMoney dummy account");
Expand Down
55 changes: 55 additions & 0 deletions cli/src/main/java/bisq/cli/ColumnHeaderConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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.cli;

import static com.google.common.base.Strings.padEnd;
import static com.google.common.base.Strings.padStart;

class ColumnHeaderConstants {

// For inserting 2 spaces between column headers.
static final String COL_HEADER_DELIMITER = " ";

// Table column header format specs, right padded with two spaces. In some cases
// such as COL_HEADER_CREATION_DATE, COL_HEADER_VOLUME and COL_HEADER_UUID, the
// expected max data string length is accounted for. In others, the column header length
// are expected to be greater than any column value length.
static final String COL_HEADER_ADDRESS = padEnd("Address", 34, ' ');
static final String COL_HEADER_AMOUNT = padEnd("BTC(min - max)", 24, ' ');
static final String COL_HEADER_BALANCE = padStart("Balance", 12, ' ');
static final String COL_HEADER_CONFIRMATIONS = "Confirmations";
static final String COL_HEADER_CREATION_DATE = padEnd("Creation Date (UTC)", 20, ' ');
static final String COL_HEADER_CURRENCY = "Currency";
static final String COL_HEADER_DIRECTION = "Buy/Sell";
static final String COL_HEADER_NAME = "Name";
static final String COL_HEADER_PAYMENT_METHOD = "Payment Method";
static final String COL_HEADER_PRICE = "Price in %-3s for 1 BTC";
static final String COL_HEADER_TRADE_AMOUNT = padStart("Amount(%-3s)", 12, ' ');
static final String COL_HEADER_TRADE_DEPOSIT_CONFIRMED = "Deposit Confirmed";
static final String COL_HEADER_TRADE_DEPOSIT_PUBLISHED = "Deposit Published";
static final String COL_HEADER_TRADE_FIAT_SENT = "Fiat Sent";
static final String COL_HEADER_TRADE_FIAT_RECEIVED = "Fiat Received";
static final String COL_HEADER_TRADE_PAYOUT_PUBLISHED = "Payout Published";
static final String COL_HEADER_TRADE_WITHDRAWN = "Withdrawn";
static final String COL_HEADER_TRADE_ROLE = "My Role";
static final String COL_HEADER_TRADE_SHORT_ID = "ID";
static final String COL_HEADER_TRADE_TX_FEE = "Tx Fee(%-3s)";
static final String COL_HEADER_TRADE_TAKER_FEE = "Taker Fee(%-3s)";
static final String COL_HEADER_VOLUME = padEnd("%-3s(min - max)", 15, ' ');
static final String COL_HEADER_UUID = padEnd("ID", 52, ' ');
}
26 changes: 3 additions & 23 deletions cli/src/main/java/bisq/cli/TableFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,41 +29,21 @@
import java.util.TimeZone;
import java.util.stream.Collectors;

import static bisq.cli.ColumnHeaderConstants.*;
import static bisq.cli.CurrencyFormat.formatAmountRange;
import static bisq.cli.CurrencyFormat.formatOfferPrice;
import static bisq.cli.CurrencyFormat.formatSatoshis;
import static bisq.cli.CurrencyFormat.formatVolumeRange;
import static com.google.common.base.Strings.padEnd;
import static com.google.common.base.Strings.padStart;
import static java.lang.String.format;
import static java.util.Collections.max;
import static java.util.Comparator.comparing;
import static java.util.TimeZone.getTimeZone;

class TableFormat {

private static final TimeZone TZ_UTC = getTimeZone("UTC");
private static final SimpleDateFormat DATE_FORMAT_ISO_8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

// For inserting 2 spaces between column headers.
private static final String COL_HEADER_DELIMITER = " ";

// Table column header format specs, right padded with two spaces. In some cases
// such as COL_HEADER_CREATION_DATE, COL_HEADER_VOLUME and COL_HEADER_UUID, the
// expected max data string length is accounted for. In others, the column header length
// are expected to be greater than any column value length.
private static final String COL_HEADER_ADDRESS = padEnd("Address", 34, ' ');
private static final String COL_HEADER_AMOUNT = padEnd("BTC(min - max)", 24, ' ');
private static final String COL_HEADER_BALANCE = padStart("Balance", 12, ' ');
private static final String COL_HEADER_CONFIRMATIONS = "Confirmations";
private static final String COL_HEADER_CREATION_DATE = padEnd("Creation Date (UTC)", 20, ' ');
private static final String COL_HEADER_CURRENCY = "Currency";
private static final String COL_HEADER_DIRECTION = "Buy/Sell"; // TODO "Take Offer to
private static final String COL_HEADER_NAME = "Name";
private static final String COL_HEADER_PAYMENT_METHOD = "Payment Method";
private static final String COL_HEADER_PRICE = "Price in %-3s for 1 BTC";
private static final String COL_HEADER_VOLUME = padEnd("%-3s(min - max)", 15, ' ');
private static final String COL_HEADER_UUID = padEnd("ID", 52, ' ');
static final TimeZone TZ_UTC = getTimeZone("UTC");
static final SimpleDateFormat DATE_FORMAT_ISO_8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

static String formatAddressBalanceTbl(List<AddressBalanceInfo> addressBalanceInfo) {
String headerLine = (COL_HEADER_ADDRESS + COL_HEADER_DELIMITER
Expand Down
118 changes: 118 additions & 0 deletions cli/src/main/java/bisq/cli/TradeFormat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* 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.cli;

import bisq.proto.grpc.TradeInfo;

import com.google.common.annotations.VisibleForTesting;

import java.util.function.Supplier;

import static bisq.cli.ColumnHeaderConstants.*;
import static bisq.cli.CurrencyFormat.formatOfferPrice;
import static bisq.cli.CurrencyFormat.formatSatoshis;
import static com.google.common.base.Strings.padEnd;

@VisibleForTesting
public class TradeFormat {

@VisibleForTesting
public static String format(TradeInfo tradeInfo) {
// Some column values might be longer than header, so we need to calculated them.
int shortIdColWidth = Math.max(COL_HEADER_TRADE_SHORT_ID.length(), tradeInfo.getShortId().length());
int roleColWidth = Math.max(COL_HEADER_TRADE_ROLE.length(), tradeInfo.getRole().length());

// We only show taker fee under its header when user is the taker.
boolean isTaker = tradeInfo.getRole().toLowerCase().contains("taker");
Supplier<String> takerFeeHeaderFormat = () -> isTaker ?
padEnd(COL_HEADER_TRADE_TAKER_FEE, 12, ' ') + COL_HEADER_DELIMITER
: "";
Supplier<String> takerFeeHeader = () -> isTaker ?
"%" + (COL_HEADER_TRADE_TAKER_FEE.length() + 1) + "s"
: "";

String headersFormat = padEnd(COL_HEADER_TRADE_SHORT_ID, shortIdColWidth, ' ') + COL_HEADER_DELIMITER
+ padEnd(COL_HEADER_TRADE_ROLE, roleColWidth, ' ') + COL_HEADER_DELIMITER
+ COL_HEADER_PRICE + COL_HEADER_DELIMITER // includes %s -> currencyCode
+ padEnd(COL_HEADER_TRADE_AMOUNT, 12, ' ') + COL_HEADER_DELIMITER
+ padEnd(COL_HEADER_TRADE_TX_FEE, 12, ' ') + COL_HEADER_DELIMITER
+ takerFeeHeaderFormat.get()
+ COL_HEADER_TRADE_DEPOSIT_PUBLISHED + COL_HEADER_DELIMITER
+ COL_HEADER_TRADE_DEPOSIT_CONFIRMED + COL_HEADER_DELIMITER
+ COL_HEADER_TRADE_FIAT_SENT + COL_HEADER_DELIMITER
+ COL_HEADER_TRADE_FIAT_RECEIVED + COL_HEADER_DELIMITER
+ COL_HEADER_TRADE_PAYOUT_PUBLISHED + COL_HEADER_DELIMITER
+ COL_HEADER_TRADE_WITHDRAWN + COL_HEADER_DELIMITER
+ "%n";

String counterCurrencyCode = tradeInfo.getOffer().getCounterCurrencyCode();
String baseCurrencyCode = tradeInfo.getOffer().getBaseCurrencyCode();
String headerLine = isTaker
? String.format(headersFormat, counterCurrencyCode, baseCurrencyCode, baseCurrencyCode, baseCurrencyCode)
: String.format(headersFormat, counterCurrencyCode, baseCurrencyCode, baseCurrencyCode);

String colDataFormat = "%-" + shortIdColWidth + "s" // left justify
+ " %-" + (roleColWidth + COL_HEADER_DELIMITER.length()) + "s" // left justify
+ "%" + (COL_HEADER_PRICE.length() - 1) + "s" // right justify
+ "%" + (COL_HEADER_TRADE_AMOUNT.length() + 1) + "s" // right justify
+ "%" + (COL_HEADER_TRADE_TX_FEE.length() + 1) + "s" // right justify
+ takerFeeHeader.get() // right justify
+ " %-" + COL_HEADER_TRADE_DEPOSIT_PUBLISHED.length() + "s" // left justify
+ " %-" + COL_HEADER_TRADE_DEPOSIT_CONFIRMED.length() + "s" // left justify
+ " %-" + COL_HEADER_TRADE_FIAT_SENT.length() + "s" // left justify
+ " %-" + COL_HEADER_TRADE_FIAT_RECEIVED.length() + "s" // left justify
+ " %-" + COL_HEADER_TRADE_PAYOUT_PUBLISHED.length() + "s" // left justify
+ " %-" + COL_HEADER_TRADE_WITHDRAWN.length() + "s"; // left justify

return headerLine +
(isTaker
? formatTradeForTaker(colDataFormat, tradeInfo)
: formatTradeForMaker(colDataFormat, tradeInfo));
}

private static String formatTradeForMaker(String format, TradeInfo tradeInfo) {
return String.format(format,
tradeInfo.getShortId(),
tradeInfo.getRole(),
formatOfferPrice(tradeInfo.getTradePrice()),
formatSatoshis(tradeInfo.getTradeAmountAsLong()),
formatSatoshis(tradeInfo.getTxFeeAsLong()),
tradeInfo.getIsDepositPublished() ? "YES" : "NO",
tradeInfo.getIsDepositConfirmed() ? "YES" : "NO",
tradeInfo.getIsFiatSent() ? "YES" : "NO",
tradeInfo.getIsFiatReceived() ? "YES" : "NO",
tradeInfo.getIsPayoutPublished() ? "YES" : "NO",
tradeInfo.getIsWithdrawn() ? "YES" : "NO");
}

private static String formatTradeForTaker(String format, TradeInfo tradeInfo) {
return String.format(format,
tradeInfo.getShortId(),
tradeInfo.getRole(),
formatOfferPrice(tradeInfo.getTradePrice()),
formatSatoshis(tradeInfo.getTradeAmountAsLong()),
formatSatoshis(tradeInfo.getTxFeeAsLong()),
formatSatoshis(tradeInfo.getTakerFeeAsLong()),
tradeInfo.getIsDepositPublished() ? "YES" : "NO",
tradeInfo.getIsDepositConfirmed() ? "YES" : "NO",
tradeInfo.getIsFiatSent() ? "YES" : "NO",
tradeInfo.getIsFiatReceived() ? "YES" : "NO",
tradeInfo.getIsPayoutPublished() ? "YES" : "NO",
tradeInfo.getIsWithdrawn() ? "YES" : "NO");
}
}
4 changes: 4 additions & 0 deletions core/src/main/java/bisq/core/api/CoreApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ public Trade getTrade(String tradeId) {
return coreTradesService.getTrade(tradeId);
}

public String getTradeRole(String tradeId) {
return coreTradesService.getTradeRole(tradeId);
}

///////////////////////////////////////////////////////////////////////////////////////////
// Wallets
///////////////////////////////////////////////////////////////////////////////////////////
Expand Down
Loading