From a067ba12286b2db0ad6abd7c836102b48e8074df Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Thu, 14 Jan 2021 10:19:39 -0300
Subject: [PATCH 01/10] Add new CoreHelpService and method help docs
Adds all the gRPC server boilerplate, and a simple help service
that serves method help in man page format. Help text is maintained
in text files located in core/src/main/resources/help.
Only some of the method help text files are defined in this
change, more to be added.
---
core/src/main/java/bisq/core/api/CoreApi.java | 13 ++-
.../java/bisq/core/api/CoreHelpService.java | 103 ++++++++++++++++++
.../main/resources/help/createoffer-help.txt | 64 +++++++++++
.../help/getfundingaddresses-help.txt | 17 +++
.../resources/help/getpaymentaccts-help.txt | 17 +++
.../resources/help/getpaymentmethods-help.txt | 17 +++
.../main/resources/help/gettxfeerate-help.txt | 17 +++
.../help/getunusedbsqaddress-help.txt | 17 +++
.../main/resources/help/getversion-help.txt | 17 +++
.../main/resources/help/lockwallet-help.txt | 17 +++
.../main/resources/help/takeoffer-help.txt | 35 ++++++
.../resources/help/unsettxfeerate-help.txt | 17 +++
.../bisq/daemon/grpc/GrpcHelpService.java | 56 ++++++++++
.../java/bisq/daemon/grpc/GrpcServer.java | 2 +
proto/src/main/proto/grpc.proto | 17 +++
15 files changed, 425 insertions(+), 1 deletion(-)
create mode 100644 core/src/main/java/bisq/core/api/CoreHelpService.java
create mode 100644 core/src/main/resources/help/createoffer-help.txt
create mode 100644 core/src/main/resources/help/getfundingaddresses-help.txt
create mode 100644 core/src/main/resources/help/getpaymentaccts-help.txt
create mode 100644 core/src/main/resources/help/getpaymentmethods-help.txt
create mode 100644 core/src/main/resources/help/gettxfeerate-help.txt
create mode 100644 core/src/main/resources/help/getunusedbsqaddress-help.txt
create mode 100644 core/src/main/resources/help/getversion-help.txt
create mode 100644 core/src/main/resources/help/lockwallet-help.txt
create mode 100644 core/src/main/resources/help/takeoffer-help.txt
create mode 100644 core/src/main/resources/help/unsettxfeerate-help.txt
create mode 100644 daemon/src/main/java/bisq/daemon/grpc/GrpcHelpService.java
diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java
index bbd12b7ccbd..bfc814c67a6 100644
--- a/core/src/main/java/bisq/core/api/CoreApi.java
+++ b/core/src/main/java/bisq/core/api/CoreApi.java
@@ -62,6 +62,7 @@ public class CoreApi {
@Getter
private final Config config;
private final CoreDisputeAgentsService coreDisputeAgentsService;
+ private final CoreHelpService coreHelpService;
private final CoreOffersService coreOffersService;
private final CorePaymentAccountsService paymentAccountsService;
private final CorePriceService corePriceService;
@@ -72,7 +73,7 @@ public class CoreApi {
@Inject
public CoreApi(Config config,
CoreDisputeAgentsService coreDisputeAgentsService,
- CoreOffersService coreOffersService,
+ CoreHelpService coreHelpService, CoreOffersService coreOffersService,
CorePaymentAccountsService paymentAccountsService,
CorePriceService corePriceService,
CoreTradesService coreTradesService,
@@ -80,6 +81,7 @@ public CoreApi(Config config,
TradeStatisticsManager tradeStatisticsManager) {
this.config = config;
this.coreDisputeAgentsService = coreDisputeAgentsService;
+ this.coreHelpService = coreHelpService;
this.coreOffersService = coreOffersService;
this.paymentAccountsService = paymentAccountsService;
this.coreTradesService = coreTradesService;
@@ -101,6 +103,15 @@ public void registerDisputeAgent(String disputeAgentType, String registrationKey
coreDisputeAgentsService.registerDisputeAgent(disputeAgentType, registrationKey);
}
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Help
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ public String getMethodHelp(String methodName) {
+ return coreHelpService.getMethodHelp(methodName);
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////
// Offers
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/core/src/main/java/bisq/core/api/CoreHelpService.java b/core/src/main/java/bisq/core/api/CoreHelpService.java
new file mode 100644
index 00000000000..a294dcad627
--- /dev/null
+++ b/core/src/main/java/bisq/core/api/CoreHelpService.java
@@ -0,0 +1,103 @@
+/*
+ * 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 .
+ */
+
+package bisq.core.api;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import lombok.extern.slf4j.Slf4j;
+
+import static java.io.File.separator;
+import static java.lang.String.format;
+import static java.lang.System.out;
+
+@Singleton
+@Slf4j
+class CoreHelpService {
+
+ @Inject
+ public CoreHelpService() {
+ }
+
+ public String getMethodHelp(String methodName) {
+ switch (methodName) {
+ case "createoffer":
+ case "getfundingaddresses":
+ case "getpaymentaccts":
+ case "getpaymentmethods":
+ case "gettxfeerate":
+ case "getunusedbsqaddress":
+ case "getversion":
+ case "lockwallet":
+ case "takeoffer":
+ case "unsettxfeerate":
+ return getHelpText(methodName);
+ default:
+ throw new IllegalStateException("no help found for " + methodName);
+ }
+ }
+
+ private String getHelpText(String methodName) {
+ String resourceFile = "/help" + separator + methodName + "-" + "help.txt";
+ try {
+ return readHelpFile(resourceFile);
+ } catch (NullPointerException ex) {
+ log.error("", ex);
+ throw new IllegalStateException(format("could not find %s help doc", methodName));
+ } catch (IOException ex) {
+ log.error("", ex);
+ throw new IllegalStateException(format("could not read %s help doc", methodName));
+ }
+ }
+
+ private String readHelpFile(String resourceFile) throws NullPointerException, IOException {
+ // The deployed text file is in the core.jar file, so use
+ // Class.getResourceAsStream to read it.
+ InputStream is = getClass().getResourceAsStream(resourceFile);
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ String line;
+ StringBuilder builder = new StringBuilder();
+ while ((line = br.readLine()) != null)
+ builder.append(line).append("\n");
+
+ return builder.toString();
+ }
+
+ // Main method for devs to view help text without running the server.
+ @SuppressWarnings("CommentedOutCode")
+ public static void main(String[] args) {
+ CoreHelpService coreHelpService = new CoreHelpService();
+ // out.println(coreHelpService.getMethodHelp("getversion"));
+ // out.println(coreHelpService.getMethodHelp("getfundingaddresses"));
+ // out.println(coreHelpService.getMethodHelp("getfundingaddresses"));
+ // out.println(coreHelpService.getMethodHelp("getunusedbsqaddress"));
+ // out.println(coreHelpService.getMethodHelp("unsettxfeerate"));
+ // out.println(coreHelpService.getMethodHelp("getpaymentmethods"));
+ // out.println(coreHelpService.getMethodHelp("getpaymentaccts"));
+ // out.println(coreHelpService.getMethodHelp("lockwallet"));
+ // out.println(coreHelpService.getMethodHelp("gettxfeerate"));
+ out.println(coreHelpService.getMethodHelp("createoffer"));
+ // out.println(coreHelpService.getMethodHelp("takeoffer"));
+ // out.println(coreHelpService.getMethodHelp("garbage"));
+ }
+}
diff --git a/core/src/main/resources/help/createoffer-help.txt b/core/src/main/resources/help/createoffer-help.txt
new file mode 100644
index 00000000000..536e2596b65
--- /dev/null
+++ b/core/src/main/resources/help/createoffer-help.txt
@@ -0,0 +1,64 @@
+createoffer
+
+NAME
+----
+createoffer - create offer to buy or sell BTC
+
+SYNOPSIS
+--------
+createoffer
+ --payment-account=
+ --direction=
+ --currency-code=
+ --market-price-margin= | --fixed-price=
+ --amount=
+ --min-amount=
+ --security-deposit=
+ [--fee-currency=]
+
+DESCRIPTION
+-----------
+Create and place an offer to buy or sell BTC using a fiat account.
+
+OPTIONS
+-------
+--payment-account
+ The ID of the fiat payment account used to send or receive funds during the trade.
+
+--direction
+ The direction of the trade (BUY or SELL).
+
+--currency-code
+ The three letter code for the fiat used to buy or sell BTC, e.g., EUR, USD, BRL, ...
+
+--market-price-margin
+ The % above or below market BTC price, e.g., 1.00 (1%).
+ If --market-price-margin is not present, --fixed-price must be.
+
+--fixed-price
+ The fixed BTC price in fiat used to buy or sell BTC, e.g., 34000 (USD).
+ If --fixed-price is not present, --market-price-margin must be.
+
+--amount
+ The amount of BTC to buy or sell, e.g., 0.125.
+
+--min-amount
+ The minimum amount of BTC to buy or sell, e.g., 0.006.
+ If --min-amount is not present, it defaults to the --amount value.
+
+--security-deposit
+ The percentage of the BTC amount being traded for the security deposit, e.g., 60.0 (60%).
+
+--fee-currency
+ The wallet currency used to pay the Bisq trade maker fee (BSQ|BTC). Default is BTC
+
+EXAMPLES
+--------
+To create a BUY 0.125 BTC with EUR offer
+ at the current market price,
+ using a payment account with ID 7413d263-225a-4f1b-837a-1e3094dc0d77,
+ putting up a 30 percent security deposit,
+ and paying the Bisq maker trading fee in BSQ:
+$ ./bisq-cli --password=xyz --port=9998 createoffer --payment-account=7413d263-225a-4f1b-837a-1e3094dc0d77 --direction=buy --currency-code=eur --amount=0.125 --market-price-margin=0.00 --security-deposit=30.0 --fee-currency=bsq
+
+ (TODO another 3 examples: selling @ mkt price, buying a fixed price, selling at fixed price...)
diff --git a/core/src/main/resources/help/getfundingaddresses-help.txt b/core/src/main/resources/help/getfundingaddresses-help.txt
new file mode 100644
index 00000000000..0d3e7ea6292
--- /dev/null
+++ b/core/src/main/resources/help/getfundingaddresses-help.txt
@@ -0,0 +1,17 @@
+getfundingaddresses
+
+NAME
+----
+getfundingaddresses - list BTC receiving address
+
+SYNOPSIS
+--------
+getfundingaddresses
+
+DESCRIPTION
+-----------
+Returns a list of receiving BTC addresses.
+
+EXAMPLES
+--------
+$ ./bisq-cli --password=xyz --port=9998 getfundingaddresses
diff --git a/core/src/main/resources/help/getpaymentaccts-help.txt b/core/src/main/resources/help/getpaymentaccts-help.txt
new file mode 100644
index 00000000000..f12b5bd4534
--- /dev/null
+++ b/core/src/main/resources/help/getpaymentaccts-help.txt
@@ -0,0 +1,17 @@
+getpaymentaccts
+
+NAME
+----
+getpaymentaccts - list user payment accounts
+
+SYNOPSIS
+--------
+getpaymentaccts
+
+DESCRIPTION
+-----------
+Returns the list of user payment accounts.
+
+EXAMPLES
+--------
+$ ./bisq-cli --password=xyz --port=9998 getpaymentaccts
diff --git a/core/src/main/resources/help/getpaymentmethods-help.txt b/core/src/main/resources/help/getpaymentmethods-help.txt
new file mode 100644
index 00000000000..b7f860548df
--- /dev/null
+++ b/core/src/main/resources/help/getpaymentmethods-help.txt
@@ -0,0 +1,17 @@
+getpaymentmethods
+
+NAME
+----
+getpaymentmethods - list fiat payment methods
+
+SYNOPSIS
+--------
+getpaymentmethods
+
+DESCRIPTION
+-----------
+Returns a list of currently supported fiat payment method IDs.
+
+EXAMPLES
+--------
+$ ./bisq-cli --password=xyz --port=9998 getpaymentmethods
diff --git a/core/src/main/resources/help/gettxfeerate-help.txt b/core/src/main/resources/help/gettxfeerate-help.txt
new file mode 100644
index 00000000000..3582d5dcf09
--- /dev/null
+++ b/core/src/main/resources/help/gettxfeerate-help.txt
@@ -0,0 +1,17 @@
+gettxfeerate
+
+NAME
+----
+gettxfeerate - get transaction fee rate
+
+SYNOPSIS
+--------
+gettxfeerate
+
+DESCRIPTION
+-----------
+Returns the most recent bitcoin network transaction fee the Bisq server could find.
+
+EXAMPLES
+--------
+$ ./bisq-cli --password=xyz --port=9998 gettxfeerate
diff --git a/core/src/main/resources/help/getunusedbsqaddress-help.txt b/core/src/main/resources/help/getunusedbsqaddress-help.txt
new file mode 100644
index 00000000000..308ad01ba7b
--- /dev/null
+++ b/core/src/main/resources/help/getunusedbsqaddress-help.txt
@@ -0,0 +1,17 @@
+getunusedbsqaddress
+
+NAME
+----
+getunusedbsqaddress - get BSQ receiving address
+
+SYNOPSIS
+--------
+getunusedbsqaddress
+
+DESCRIPTION
+-----------
+Returns an unused BSQ receiving address.
+
+EXAMPLES
+--------
+$ ./bisq-cli --password=xyz --port=9998 getunusedbsqaddress
diff --git a/core/src/main/resources/help/getversion-help.txt b/core/src/main/resources/help/getversion-help.txt
new file mode 100644
index 00000000000..ce3b801db4b
--- /dev/null
+++ b/core/src/main/resources/help/getversion-help.txt
@@ -0,0 +1,17 @@
+getversion
+
+NAME
+----
+getversion - get server version
+
+SYNOPSIS
+--------
+getversion
+
+DESCRIPTION
+-----------
+Returns the Bisq server version.
+
+EXAMPLES
+--------
+$ ./bisq-cli --password=xyz --port=9998 getversion
diff --git a/core/src/main/resources/help/lockwallet-help.txt b/core/src/main/resources/help/lockwallet-help.txt
new file mode 100644
index 00000000000..6639dcef5ea
--- /dev/null
+++ b/core/src/main/resources/help/lockwallet-help.txt
@@ -0,0 +1,17 @@
+lockwallet
+
+NAME
+----
+lockwallet - lock Bisq wallet
+
+SYNOPSIS
+--------
+lockwallet
+
+DESCRIPTION
+-----------
+Locks an unlocked wallet before an unlockwallet timeout expires.
+
+EXAMPLES
+--------
+$ ./bisq-cli --password=xyz --port=9998 lockwallet
diff --git a/core/src/main/resources/help/takeoffer-help.txt b/core/src/main/resources/help/takeoffer-help.txt
new file mode 100644
index 00000000000..89ab21fc9c0
--- /dev/null
+++ b/core/src/main/resources/help/takeoffer-help.txt
@@ -0,0 +1,35 @@
+takeoffer
+
+NAME
+----
+takeoffer - take an offer to buy or sell BTC
+
+SYNOPSIS
+--------
+takeoffer
+ --offer-id=
+ --payment-account=
+ --fee-currency=
+
+DESCRIPTION
+-----------
+Take an existing offer using a matching payment method. The Bisq trade fee can be paid in BSQ or BTC.
+
+OPTIONS
+-------
+--offer-id
+ The ID of the buy or sell offer to take.
+
+--payment-account
+ The ID of the fiat payment account used to send or receive funds during the trade.
+ The payment account's payment method must match that of the offer.
+
+--fee-currency
+ The wallet currency used to pay the Bisq trade taker fee (BSQ|BTC). Default is BTC
+
+EXAMPLES
+--------
+To take an offer with ID 83e8b2e2-51b6-4f39-a748-3ebd29c22aea
+ using a payment account with ID fe20cdbd-22be-4b8a-a4b6-d2608ff09d6e,
+ and paying the Bisq trading fee in BSQ:
+$ ./bisq-cli --password=xyz --port=9998 takeoffer -offer-id=83e8b2e2-51b6-4f39-a748-3ebd29c22aea -payment-account=fe20cdbd-22be-4b8a-a4b6-d2608ff09d6e -fee-currency=bsq
diff --git a/core/src/main/resources/help/unsettxfeerate-help.txt b/core/src/main/resources/help/unsettxfeerate-help.txt
new file mode 100644
index 00000000000..36767e6f1f0
--- /dev/null
+++ b/core/src/main/resources/help/unsettxfeerate-help.txt
@@ -0,0 +1,17 @@
+unsettxfeerate
+
+NAME
+----
+unsettxfeerate - unset transaction fee rate preference
+
+SYNOPSIS
+--------
+unsettxfeerate
+
+DESCRIPTION
+-----------
+Unsets (removes) the transaction fee rate user preference.
+
+EXAMPLES
+--------
+$ ./bisq-cli --password=xyz --port=9998 unsettxfeerate
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcHelpService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcHelpService.java
new file mode 100644
index 00000000000..1a62ed6f9f6
--- /dev/null
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcHelpService.java
@@ -0,0 +1,56 @@
+/*
+ * 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 .
+ */
+
+package bisq.daemon.grpc;
+
+import bisq.core.api.CoreApi;
+
+import bisq.proto.grpc.GetMethodHelpReply;
+import bisq.proto.grpc.GetMethodHelpRequest;
+import bisq.proto.grpc.HelpGrpc;
+
+import io.grpc.stub.StreamObserver;
+
+import javax.inject.Inject;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+class GrpcHelpService extends HelpGrpc.HelpImplBase {
+
+ private final CoreApi coreApi;
+ private final GrpcExceptionHandler exceptionHandler;
+
+ @Inject
+ public GrpcHelpService(CoreApi coreApi, GrpcExceptionHandler exceptionHandler) {
+ this.coreApi = coreApi;
+ this.exceptionHandler = exceptionHandler;
+ }
+
+ @Override
+ public void getMethodHelp(GetMethodHelpRequest req,
+ StreamObserver responseObserver) {
+ try {
+ String helpText = coreApi.getMethodHelp(req.getMethodName());
+ var reply = GetMethodHelpReply.newBuilder().setMethodHelp(helpText).build();
+ responseObserver.onNext(reply);
+ responseObserver.onCompleted();
+ } catch (Throwable cause) {
+ exceptionHandler.handleException(cause, responseObserver);
+ }
+ }
+}
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java
index 589645d77dd..8e50a98aa1f 100644
--- a/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java
@@ -50,6 +50,7 @@ public GrpcServer(CoreContext coreContext,
Config config,
PasswordAuthInterceptor passwordAuthInterceptor,
GrpcDisputeAgentsService disputeAgentsService,
+ GrpcHelpService helpService,
GrpcOffersService offersService,
GrpcPaymentAccountsService paymentAccountsService,
GrpcPriceService priceService,
@@ -60,6 +61,7 @@ public GrpcServer(CoreContext coreContext,
this.server = ServerBuilder.forPort(config.apiPort)
.executor(UserThread.getExecutor())
.addService(disputeAgentsService)
+ .addService(helpService)
.addService(offersService)
.addService(paymentAccountsService)
.addService(priceService)
diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto
index 3ac2ea4bf61..085c3f90741 100644
--- a/proto/src/main/proto/grpc.proto
+++ b/proto/src/main/proto/grpc.proto
@@ -40,6 +40,23 @@ message RegisterDisputeAgentRequest {
message RegisterDisputeAgentReply {
}
+///////////////////////////////////////////////////////////////////////////////////////////
+// Help
+///////////////////////////////////////////////////////////////////////////////////////////
+
+service Help {
+ rpc GetMethodHelp (GetMethodHelpRequest) returns (GetMethodHelpReply) {
+ }
+}
+
+message GetMethodHelpRequest {
+ string methodName = 1;
+}
+
+message GetMethodHelpReply {
+ string methodHelp = 1;
+}
+
///////////////////////////////////////////////////////////////////////////////////////////
// Offers
///////////////////////////////////////////////////////////////////////////////////////////
From 49a3b46960df6de01d6d94d026d7fde692823d15 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Thu, 14 Jan 2021 10:22:14 -0300
Subject: [PATCH 02/10] Add CoreHelpService gRPC stubs and test case
---
apitest/scripts/mainnet-test.sh | 26 ++++----
.../apitest/method/GetMethodHelpTest.java | 65 +++++++++++++++++++
.../java/bisq/apitest/method/MethodTest.java | 10 +++
.../bisq/apitest/scenario/StartupTest.java | 8 +++
cli/src/main/java/bisq/cli/GrpcStubs.java | 3 +
5 files changed, 99 insertions(+), 13 deletions(-)
create mode 100644 apitest/src/test/java/bisq/apitest/method/GetMethodHelpTest.java
diff --git a/apitest/scripts/mainnet-test.sh b/apitest/scripts/mainnet-test.sh
index 48fe4023bf1..d643ee716e0 100755
--- a/apitest/scripts/mainnet-test.sh
+++ b/apitest/scripts/mainnet-test.sh
@@ -27,7 +27,7 @@
run ./bisq-cli --bogus getversion
[ "$status" -eq 1 ]
echo "actual output: $output" >&2
- [ "$output" = "Error: bogus is not a recognized option" ]
+ [ "$output" = "Error: missing required 'password' option" ]
}
@test "test missing required password option error" {
@@ -61,7 +61,7 @@
}
@test "test setwalletpassword \"a b c\"" {
- run ./bisq-cli --password=xyz setwalletpassword "a b c"
+ run ./bisq-cli --password=xyz setwalletpassword --wallet-password="a b c"
[ "$status" -eq 0 ]
echo "actual output: $output" >&2
[ "$output" = "wallet encrypted" ]
@@ -76,7 +76,7 @@
}
@test "test unlockwallet without timeout arg" {
- run ./bisq-cli --password=xyz unlockwallet "a b c"
+ run ./bisq-cli --password=xyz unlockwallet --wallet-password="a b c"
[ "$status" -eq 1 ]
echo "actual output: $output" >&2
[ "$output" = "Error: no unlock timeout specified" ]
@@ -84,7 +84,7 @@
@test "test unlockwallet \"a b c\" 8" {
- run ./bisq-cli --password=xyz unlockwallet "a b c" 8
+ run ./bisq-cli --password=xyz unlockwallet --wallet-password="a b c" --timeout=8
[ "$status" -eq 0 ]
echo "actual output: $output" >&2
[ "$output" = "wallet unlocked" ]
@@ -97,7 +97,7 @@
}
@test "test unlockwallet \"a b c\" 6" {
- run ./bisq-cli --password=xyz unlockwallet "a b c" 6
+ run ./bisq-cli --password=xyz unlockwallet --wallet-password="a b c" --timeout=6
[ "$status" -eq 0 ]
echo "actual output: $output" >&2
[ "$output" = "wallet unlocked" ]
@@ -111,14 +111,14 @@
}
@test "test setwalletpassword incorrect old pwd error" {
- run ./bisq-cli --password=xyz setwalletpassword "z z z" "d e f"
+ run ./bisq-cli --password=xyz setwalletpassword --wallet-password="z z z" --new-wallet-password="d e f"
[ "$status" -eq 1 ]
echo "actual output: $output" >&2
[ "$output" = "Error: incorrect old password" ]
}
@test "test setwalletpassword oldpwd newpwd" {
- run ./bisq-cli --password=xyz setwalletpassword "a b c" "d e f"
+ run ./bisq-cli --password=xyz setwalletpassword --wallet-password="a b c" --new-wallet-password="d e f"
[ "$status" -eq 0 ]
echo "actual output: $output" >&2
[ "$output" = "wallet encrypted with new password" ]
@@ -133,7 +133,7 @@
}
@test "test removewalletpassword" {
- run ./bisq-cli --password=xyz removewalletpassword "d e f"
+ run ./bisq-cli --password=xyz removewalletpassword --wallet-password="d e f"
[ "$status" -eq 0 ]
echo "actual output: $output" >&2
[ "$output" = "wallet decrypted" ]
@@ -163,7 +163,7 @@
}
@test "test getaddressbalance bogus address argument" {
- run ./bisq-cli --password=xyz getaddressbalance bogus
+ run ./bisq-cli --password=xyz getaddressbalance --address=bogus
[ "$status" -eq 1 ]
echo "actual output: $output" >&2
[ "$output" = "Error: address bogus not found in wallet" ]
@@ -183,21 +183,21 @@
run ./bisq-cli --password=xyz getoffers
[ "$status" -eq 1 ]
echo "actual output: $output" >&2
- [ "$output" = "Error: incorrect parameter count, expecting direction (buy|sell), currency code" ]
+ [ "$output" = "Error: no direction (buy|sell) specified" ]
}
@test "test getoffers sell eur check return status" {
- run ./bisq-cli --password=xyz getoffers sell eur
+ run ./bisq-cli --password=xyz getoffers --direction=sell --currency-code=eur
[ "$status" -eq 0 ]
}
@test "test getoffers buy eur check return status" {
- run ./bisq-cli --password=xyz getoffers buy eur
+ run ./bisq-cli --password=xyz getoffers --direction=buy --currency-code=eur
[ "$status" -eq 0 ]
}
@test "test getoffers sell gbp check return status" {
- run ./bisq-cli --password=xyz getoffers sell gbp
+ run ./bisq-cli --password=xyz getoffers --direction=sell --currency-code=gbp
[ "$status" -eq 0 ]
}
diff --git a/apitest/src/test/java/bisq/apitest/method/GetMethodHelpTest.java b/apitest/src/test/java/bisq/apitest/method/GetMethodHelpTest.java
new file mode 100644
index 00000000000..99e7b4873f2
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/method/GetMethodHelpTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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 .
+ */
+
+package bisq.apitest.method;
+
+import bisq.proto.grpc.GetMethodHelpRequest;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import static bisq.apitest.config.BisqAppConfig.alicedaemon;
+import static bisq.cli.Method.createoffer;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
+
+@Disabled
+@Slf4j
+@TestMethodOrder(OrderAnnotation.class)
+public class GetMethodHelpTest extends MethodTest {
+
+ @BeforeAll
+ public static void setUp() {
+ try {
+ setUpScaffold(alicedaemon);
+ } catch (Exception ex) {
+ fail(ex);
+ }
+ }
+
+ @Test
+ @Order(1)
+ public void testGetCreateOfferHelp() {
+ var help = grpcStubs(alicedaemon).helpService
+ .getMethodHelp(GetMethodHelpRequest.newBuilder()
+ .setMethodName(createoffer.name()).build())
+ .getMethodHelp();
+ assertNotNull(help);
+ }
+
+ @AfterAll
+ public static void tearDown() {
+ tearDownScaffold();
+ }
+}
diff --git a/apitest/src/test/java/bisq/apitest/method/MethodTest.java b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
index f4fd94b517a..26fa8c422cb 100644
--- a/apitest/src/test/java/bisq/apitest/method/MethodTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
@@ -35,6 +35,7 @@
import bisq.proto.grpc.GetAddressBalanceRequest;
import bisq.proto.grpc.GetBalancesRequest;
import bisq.proto.grpc.GetFundingAddressesRequest;
+import bisq.proto.grpc.GetMethodHelpRequest;
import bisq.proto.grpc.GetMyOfferRequest;
import bisq.proto.grpc.GetOfferRequest;
import bisq.proto.grpc.GetPaymentAccountFormRequest;
@@ -271,6 +272,10 @@ protected final WithdrawFundsRequest createWithdrawFundsRequest(String tradeId,
.build();
}
+ protected final GetMethodHelpRequest createGetMethodHelpRequest(String methodName) {
+ return GetMethodHelpRequest.newBuilder().setMethodName(methodName).build();
+ }
+
// Convenience methods for calling frequently used & thoroughly tested gRPC services.
protected final BalancesInfo getBalances(BisqAppConfig bisqAppConfig, String currencyCode) {
return grpcStubs(bisqAppConfig).walletsService.getBalances(
@@ -490,6 +495,11 @@ public bisq.core.payment.PaymentAccount createDummyF2FAccount(BisqAppConfig bisq
return f2FAccount;
}
+ protected final String getMethodHelp(BisqAppConfig bisqAppConfig, String methodName) {
+ var req = createGetMethodHelpRequest(methodName);
+ return grpcStubs(bisqAppConfig).helpService.getMethodHelp(req).getMethodHelp();
+ }
+
// Static conveniences for test methods and test case fixture setups.
protected static RegisterDisputeAgentRequest createRegisterDisputeAgentRequest(String disputeAgentType) {
diff --git a/apitest/src/test/java/bisq/apitest/scenario/StartupTest.java b/apitest/src/test/java/bisq/apitest/scenario/StartupTest.java
index 5c017e8e4f8..3010a6568da 100644
--- a/apitest/src/test/java/bisq/apitest/scenario/StartupTest.java
+++ b/apitest/src/test/java/bisq/apitest/scenario/StartupTest.java
@@ -38,6 +38,7 @@
import bisq.apitest.method.CallRateMeteringInterceptorTest;
+import bisq.apitest.method.GetMethodHelpTest;
import bisq.apitest.method.GetVersionTest;
import bisq.apitest.method.MethodTest;
import bisq.apitest.method.RegisterDisputeAgentsTest;
@@ -92,6 +93,13 @@ public void testRegisterDisputeAgents() {
test.testRegisterRefundAgent();
}
+ @Test
+ @Order(4)
+ public void testGetCreateOfferHelp() {
+ GetMethodHelpTest test = new GetMethodHelpTest();
+ test.testGetCreateOfferHelp();
+ }
+
@AfterAll
public static void tearDown() {
tearDownScaffold();
diff --git a/cli/src/main/java/bisq/cli/GrpcStubs.java b/cli/src/main/java/bisq/cli/GrpcStubs.java
index 2db33fcbaa9..2094eb743c4 100644
--- a/cli/src/main/java/bisq/cli/GrpcStubs.java
+++ b/cli/src/main/java/bisq/cli/GrpcStubs.java
@@ -19,6 +19,7 @@
import bisq.proto.grpc.DisputeAgentsGrpc;
import bisq.proto.grpc.GetVersionGrpc;
+import bisq.proto.grpc.HelpGrpc;
import bisq.proto.grpc.OffersGrpc;
import bisq.proto.grpc.PaymentAccountsGrpc;
import bisq.proto.grpc.PriceGrpc;
@@ -33,6 +34,7 @@
public class GrpcStubs {
public final DisputeAgentsGrpc.DisputeAgentsBlockingStub disputeAgentsService;
+ public final HelpGrpc.HelpBlockingStub helpService;
public final GetVersionGrpc.GetVersionBlockingStub versionService;
public final OffersGrpc.OffersBlockingStub offersService;
public final PaymentAccountsGrpc.PaymentAccountsBlockingStub paymentAccountsService;
@@ -53,6 +55,7 @@ public GrpcStubs(String apiHost, int apiPort, String apiPassword) {
}));
this.disputeAgentsService = DisputeAgentsGrpc.newBlockingStub(channel).withCallCredentials(credentials);
+ this.helpService = HelpGrpc.newBlockingStub(channel).withCallCredentials(credentials);
this.versionService = GetVersionGrpc.newBlockingStub(channel).withCallCredentials(credentials);
this.offersService = OffersGrpc.newBlockingStub(channel).withCallCredentials(credentials);
this.paymentAccountsService = PaymentAccountsGrpc.newBlockingStub(channel).withCallCredentials(credentials);
From 37ad73d4f423f749b0fd03eea277e9422f84f083 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Thu, 14 Jan 2021 10:23:38 -0300
Subject: [PATCH 03/10] Add posix-style api method option parsers
---
.../cli/opts/AbstractMethodOptionParser.java | 59 ++++++++
.../main/java/bisq/cli/opts/ArgumentList.java | 123 +++++++++++++++
.../cli/opts/CancelOfferOptionParser.java | 52 +++++++
.../cli/opts/CreateOfferOptionParser.java | 140 ++++++++++++++++++
.../opts/CreatePaymentAcctOptionParser.java | 63 ++++++++
.../opts/GetAddressBalanceOptionParser.java | 52 +++++++
.../bisq/cli/opts/GetBalanceOptionParser.java | 43 ++++++
.../bisq/cli/opts/GetOfferOptionParser.java | 52 +++++++
.../bisq/cli/opts/GetOffersOptionParser.java | 64 ++++++++
.../opts/GetPaymentAcctFormOptionParser.java | 53 +++++++
.../bisq/cli/opts/GetTradeOptionParser.java | 62 ++++++++
.../cli/opts/GetTransactionOptionParser.java | 52 +++++++
.../main/java/bisq/cli/opts/MethodOpts.java | 26 ++++
cli/src/main/java/bisq/cli/opts/OptLabel.java | 51 +++++++
.../RegisterDisputeAgentOptionParser.java | 64 ++++++++
.../RemoveWalletPasswordOptionParser.java | 52 +++++++
.../bisq/cli/opts/SendBsqOptionParser.java | 73 +++++++++
.../bisq/cli/opts/SendBtcOptionParser.java | 82 ++++++++++
.../cli/opts/SetTxFeeRateOptionParser.java | 53 +++++++
.../opts/SetWalletPasswordOptionParser.java | 61 ++++++++
.../cli/opts/SimpleMethodOptionParser.java | 30 ++++
.../bisq/cli/opts/TakeOfferOptionParser.java | 73 +++++++++
.../cli/opts/UnlockWalletOptionParser.java | 65 ++++++++
.../cli/opts/WithdrawFundsOptionParser.java | 70 +++++++++
24 files changed, 1515 insertions(+)
create mode 100644 cli/src/main/java/bisq/cli/opts/AbstractMethodOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/ArgumentList.java
create mode 100644 cli/src/main/java/bisq/cli/opts/CancelOfferOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/CreatePaymentAcctOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/GetAddressBalanceOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/GetBalanceOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/GetOfferOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/GetOffersOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/GetPaymentAcctFormOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/GetTradeOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/GetTransactionOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/MethodOpts.java
create mode 100644 cli/src/main/java/bisq/cli/opts/OptLabel.java
create mode 100644 cli/src/main/java/bisq/cli/opts/RegisterDisputeAgentOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/RemoveWalletPasswordOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/SendBsqOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/SendBtcOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/SetTxFeeRateOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/SetWalletPasswordOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/SimpleMethodOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/TakeOfferOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/UnlockWalletOptionParser.java
create mode 100644 cli/src/main/java/bisq/cli/opts/WithdrawFundsOptionParser.java
diff --git a/cli/src/main/java/bisq/cli/opts/AbstractMethodOptionParser.java b/cli/src/main/java/bisq/cli/opts/AbstractMethodOptionParser.java
new file mode 100644
index 00000000000..4c495c06e5e
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/AbstractMethodOptionParser.java
@@ -0,0 +1,59 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
+
+import java.util.List;
+
+import lombok.Getter;
+
+import static bisq.cli.opts.OptLabel.OPT_HELP;
+
+abstract class AbstractMethodOptionParser implements MethodOpts {
+
+ // The full command line args passed to CliMain.main(String[] args).
+ // CLI and Method level arguments are derived from args by an ArgumentList(args).
+ protected final String[] args;
+
+ protected final OptionParser parser = new OptionParser();
+
+ // The help option for a specific api method, e.g., takeoffer -help.
+ protected final OptionSpec helpOpt = parser.accepts(OPT_HELP, "Print method help").forHelp();
+
+ @Getter
+ protected OptionSet options;
+ @Getter
+ protected List nonOptionArguments;
+
+ protected AbstractMethodOptionParser(String[] args) {
+ this.args = args;
+ }
+
+ public AbstractMethodOptionParser parse() {
+ options = parser.parse(new ArgumentList(args).getMethodArguments());
+ nonOptionArguments = (List) options.nonOptionArguments();
+ return this;
+ }
+
+ public boolean isForHelp() {
+ return options.has(helpOpt);
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/ArgumentList.java b/cli/src/main/java/bisq/cli/opts/ArgumentList.java
new file mode 100644
index 00000000000..3b52fb34a90
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/ArgumentList.java
@@ -0,0 +1,123 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+/**
+ * Wrapper for an array of command line arguments.
+ *
+ * Used to extract CLI connection and authentication arguments, or method arguments
+ * before parsing CLI or method opts
+ *
+ */
+public class ArgumentList {
+
+ private final Predicate isCliOpt = (o) ->
+ o.startsWith("--password") || o.startsWith("-password")
+ || o.startsWith("--port") || o.startsWith("-port")
+ || o.startsWith("--host") || o.startsWith("-host");
+
+
+ // The method name is the only positional opt in a command (easy to identify).
+ // If the positional argument does not match a Method, or there are more than one
+ // positional arguments, the joptsimple parser or CLI will fail as expected.
+ private final Predicate isMethodNameOpt = (o) -> !o.startsWith("-");
+
+ private final Predicate isHelpOpt = (o) -> o.startsWith("--help") || o.startsWith("-help");
+
+ private final String[] arguments;
+ private int currentIndex;
+
+ public ArgumentList(String... arguments) {
+ this.arguments = arguments.clone();
+ }
+
+ /**
+ * Returns only the CLI connection & authentication, and method name args
+ * (--password, --host, --port, --help, method name) contained in the original
+ * String[] args; excludes the method specific arguments.
+ *
+ * If String[] args contains both a method name (the only positional opt) and a help
+ * argument (--help, -help), it is assumed the user wants method help, not CLI help,
+ * and the help argument is not included in the returned String[].
+ */
+ public String[] getCLIArguments() {
+ currentIndex = 0;
+ Optional methodNameArgument = Optional.empty();
+ Optional helpArgument = Optional.empty();
+ List prunedArguments = new ArrayList<>();
+
+ while (hasMore()) {
+ String arg = peek();
+ if (isMethodNameOpt.test(arg)) {
+ methodNameArgument = Optional.of(arg);
+ prunedArguments.add(arg);
+ }
+
+ if (isCliOpt.test(arg))
+ prunedArguments.add(arg);
+
+ if (isHelpOpt.test(arg))
+ helpArgument = Optional.of(arg);
+
+ next();
+ }
+
+ // Include the saved CLI help argument if the positional method name argument
+ // was not found.
+ if (!methodNameArgument.isPresent() && helpArgument.isPresent())
+ prunedArguments.add(helpArgument.get());
+
+ return prunedArguments.toArray(new String[0]);
+ }
+
+ /**
+ * Returns only the method args contained in the original String[] args; excludes the
+ * CLI connection & authentication opts (--password, --host, --port), plus the
+ * positional method name arg.
+ */
+ public String[] getMethodArguments() {
+ List prunedArguments = new ArrayList<>();
+ currentIndex = 0;
+ while (hasMore()) {
+ String arg = peek();
+ if (!isCliOpt.test(arg) && !isMethodNameOpt.test(arg)) {
+ prunedArguments.add(arg);
+ }
+ next();
+ }
+ return prunedArguments.toArray(new String[0]);
+ }
+
+
+ boolean hasMore() {
+ return currentIndex < arguments.length;
+ }
+
+ String next() {
+ return arguments[currentIndex++];
+ }
+
+ String peek() {
+ return arguments[currentIndex];
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/CancelOfferOptionParser.java b/cli/src/main/java/bisq/cli/opts/CancelOfferOptionParser.java
new file mode 100644
index 00000000000..24ebc744211
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/CancelOfferOptionParser.java
@@ -0,0 +1,52 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_OFFER_ID;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class CancelOfferOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec offerIdOpt = parser.accepts(OPT_OFFER_ID, "id of offer to cancel")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ public CancelOfferOptionParser(String[] args) {
+ super(args);
+ }
+
+ public CancelOfferOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(offerIdOpt))
+ throw new IllegalArgumentException("no offer id specified");
+
+ return this;
+ }
+
+ public String getOfferId() {
+ return options.valueOf(offerIdOpt);
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java b/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java
new file mode 100644
index 00000000000..4cb6a24a4cc
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java
@@ -0,0 +1,140 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import java.math.BigDecimal;
+
+import static bisq.cli.opts.OptLabel.*;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class CreateOfferOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec paymentAccountIdOpt = parser.accepts(OPT_PAYMENT_ACCOUNT,
+ "id of payment account used for offer")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec directionOpt = parser.accepts(OPT_DIRECTION, "offer direction (buy|sell)")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec currencyCodeOpt = parser.accepts(OPT_CURRENCY_CODE, "currency code (eur|usd|...)")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec amountOpt = parser.accepts(OPT_AMOUNT, "amount of btc to buy or sell")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec minAmountOpt = parser.accepts(OPT_MIN_AMOUNT, "minimum amount of btc to buy or sell")
+ .withOptionalArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec mktPriceMarginOpt = parser.accepts(OPT_MKT_PRICE_MARGIN, "market btc price margin (%)")
+ .withOptionalArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec fixedPriceOpt = parser.accepts(OPT_FIXED_PRICE, "fixed btc price")
+ .withOptionalArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec securityDepositOpt = parser.accepts(OPT_SECURITY_DEPOSIT, "maker security deposit (%)")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec makerFeeCurrencyCodeOpt = parser.accepts(OPT_FEE_CURRENCY, "maker fee currency code (bsq|btc)")
+ .withOptionalArg()
+ .defaultsTo("btc");
+
+ public CreateOfferOptionParser(String[] args) {
+ super(args);
+ }
+
+ public CreateOfferOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(paymentAccountIdOpt))
+ throw new IllegalArgumentException("no payment account id specified");
+
+ if (!options.has(directionOpt))
+ throw new IllegalArgumentException("no direction (buy|sell) specified");
+
+ if (!options.has(amountOpt))
+ throw new IllegalArgumentException("no btc amount specified");
+
+ if (!options.has(mktPriceMarginOpt) && !options.has(fixedPriceOpt))
+ throw new IllegalArgumentException("no market price margin or fixed price specified");
+
+ if (!options.has(securityDepositOpt))
+ throw new IllegalArgumentException("no security deposit specified");
+
+ return this;
+ }
+
+ public String getPaymentAccountId() {
+ return options.valueOf(paymentAccountIdOpt);
+ }
+
+ public String getDirection() {
+ return options.valueOf(directionOpt);
+ }
+
+ public String getCurrencyCode() {
+ return options.valueOf(currencyCodeOpt);
+ }
+
+ public String getAmount() {
+ return options.valueOf(amountOpt);
+ }
+
+ public String getMinAmount() {
+ return options.has(minAmountOpt) ? options.valueOf(minAmountOpt) : getAmount();
+ }
+
+ public boolean isUsingMktPriceMargin() {
+ return options.has(mktPriceMarginOpt);
+ }
+
+ @SuppressWarnings("unused")
+ public String getMktPriceMargin() {
+ return isUsingMktPriceMargin() ? options.valueOf(mktPriceMarginOpt) : "";
+ }
+
+ public BigDecimal getMktPriceMarginAsBigDecimal() {
+ return isUsingMktPriceMargin() ? new BigDecimal(options.valueOf(mktPriceMarginOpt)) : BigDecimal.ZERO;
+ }
+
+ public String getFixedPrice() {
+ return options.has(fixedPriceOpt) ? options.valueOf(fixedPriceOpt) : "";
+ }
+
+ public String getSecurityDeposit() {
+ return options.valueOf(securityDepositOpt);
+ }
+
+ public String getMakerFeeCurrencyCode() {
+ return options.has(makerFeeCurrencyCodeOpt) ? options.valueOf(makerFeeCurrencyCodeOpt) : "btc";
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/CreatePaymentAcctOptionParser.java b/cli/src/main/java/bisq/cli/opts/CreatePaymentAcctOptionParser.java
new file mode 100644
index 00000000000..21fb01bcec5
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/CreatePaymentAcctOptionParser.java
@@ -0,0 +1,63 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static bisq.cli.opts.OptLabel.OPT_PAYMENT_ACCOUNT_FORM;
+import static java.lang.String.format;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class CreatePaymentAcctOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec paymentAcctFormPathOpt = parser.accepts(OPT_PAYMENT_ACCOUNT_FORM,
+ "path to json payment account form")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ public CreatePaymentAcctOptionParser(String[] args) {
+ super(args);
+ }
+
+ public CreatePaymentAcctOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(paymentAcctFormPathOpt))
+ throw new IllegalArgumentException("no path to json payment account form specified");
+
+ Path path = Paths.get(options.valueOf(paymentAcctFormPathOpt));
+ if (!path.toFile().exists())
+ throw new IllegalStateException(
+ format("json payment account form '%s' could not be found",
+ path.toString()));
+
+ return this;
+ }
+
+ public Path getPaymentAcctForm() {
+ return Paths.get(options.valueOf(paymentAcctFormPathOpt));
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/GetAddressBalanceOptionParser.java b/cli/src/main/java/bisq/cli/opts/GetAddressBalanceOptionParser.java
new file mode 100644
index 00000000000..80537ffc89d
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/GetAddressBalanceOptionParser.java
@@ -0,0 +1,52 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_ADDRESS;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class GetAddressBalanceOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec addressOpt = parser.accepts(OPT_ADDRESS, "wallet btc address")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ public GetAddressBalanceOptionParser(String[] args) {
+ super(args);
+ }
+
+ public GetAddressBalanceOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(addressOpt))
+ throw new IllegalArgumentException("no address specified");
+
+ return this;
+ }
+
+ public String getAddress() {
+ return options.valueOf(addressOpt);
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/GetBalanceOptionParser.java b/cli/src/main/java/bisq/cli/opts/GetBalanceOptionParser.java
new file mode 100644
index 00000000000..206e590c3d2
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/GetBalanceOptionParser.java
@@ -0,0 +1,43 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_CURRENCY_CODE;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class GetBalanceOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec currencyCodeOpt = parser.accepts(OPT_CURRENCY_CODE, "wallet currency code (bsq|btc)")
+ .withOptionalArg()
+ .defaultsTo(EMPTY);
+
+ public GetBalanceOptionParser(String[] args) {
+ super(args);
+ }
+
+ public GetBalanceOptionParser parse() {
+ return (GetBalanceOptionParser) super.parse();
+ }
+
+ public String getCurrencyCode() {
+ return options.has(currencyCodeOpt) ? options.valueOf(currencyCodeOpt) : "";
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/GetOfferOptionParser.java b/cli/src/main/java/bisq/cli/opts/GetOfferOptionParser.java
new file mode 100644
index 00000000000..600e7672c45
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/GetOfferOptionParser.java
@@ -0,0 +1,52 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_OFFER_ID;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class GetOfferOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec offerIdOpt = parser.accepts(OPT_OFFER_ID, "id of offer to get")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ public GetOfferOptionParser(String[] args) {
+ super(args);
+ }
+
+ public GetOfferOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(offerIdOpt))
+ throw new IllegalArgumentException("no offer id specified");
+
+ return this;
+ }
+
+ public String getOfferId() {
+ return options.valueOf(offerIdOpt);
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/GetOffersOptionParser.java b/cli/src/main/java/bisq/cli/opts/GetOffersOptionParser.java
new file mode 100644
index 00000000000..29360886f87
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/GetOffersOptionParser.java
@@ -0,0 +1,64 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_CURRENCY_CODE;
+import static bisq.cli.opts.OptLabel.OPT_DIRECTION;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class GetOffersOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec directionOpt = parser.accepts(OPT_DIRECTION, "offer direction (buy|sell)")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec currencyCodeOpt = parser.accepts(OPT_CURRENCY_CODE, "currency code (eur|usd|...)")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ public GetOffersOptionParser(String[] args) {
+ super(args);
+ }
+
+ public GetOffersOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(directionOpt))
+ throw new IllegalArgumentException("no direction (buy|sell) specified");
+
+ if (!options.has(currencyCodeOpt))
+ throw new IllegalArgumentException("no currency code specified");
+
+ return this;
+ }
+
+ public String getDirection() {
+ return options.valueOf(directionOpt);
+ }
+
+ public String getCurrencyCode() {
+ return options.valueOf(currencyCodeOpt);
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/GetPaymentAcctFormOptionParser.java b/cli/src/main/java/bisq/cli/opts/GetPaymentAcctFormOptionParser.java
new file mode 100644
index 00000000000..ef5bd5b454c
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/GetPaymentAcctFormOptionParser.java
@@ -0,0 +1,53 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_PAYMENT_METHOD_ID;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class GetPaymentAcctFormOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec paymentMethodIdOpt = parser.accepts(OPT_PAYMENT_METHOD_ID,
+ "id of payment method type used by a payment account")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ public GetPaymentAcctFormOptionParser(String[] args) {
+ super(args);
+ }
+
+ public GetPaymentAcctFormOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(paymentMethodIdOpt))
+ throw new IllegalArgumentException("no payment method id specified");
+
+ return this;
+ }
+
+ public String getPaymentMethodId() {
+ return options.valueOf(paymentMethodIdOpt);
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/GetTradeOptionParser.java b/cli/src/main/java/bisq/cli/opts/GetTradeOptionParser.java
new file mode 100644
index 00000000000..d1edf181063
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/GetTradeOptionParser.java
@@ -0,0 +1,62 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_SHOW_CONTRACT;
+import static bisq.cli.opts.OptLabel.OPT_TRADE_ID;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class GetTradeOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec tradeIdOpt = parser.accepts(OPT_TRADE_ID, "id of trade to get")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec showContractOpt = parser.accepts(OPT_SHOW_CONTRACT, "show trade's json contract")
+ .withOptionalArg()
+ .ofType(boolean.class)
+ .defaultsTo(Boolean.FALSE);
+
+ public GetTradeOptionParser(String[] args) {
+ super(args);
+ }
+
+ public GetTradeOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(tradeIdOpt))
+ throw new IllegalArgumentException("no trade id specified");
+
+ return this;
+ }
+
+ public String getTradeId() {
+ return options.valueOf(tradeIdOpt);
+ }
+
+ public boolean getShowContract() {
+ return options.has(showContractOpt) ? options.valueOf(showContractOpt) : false;
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/GetTransactionOptionParser.java b/cli/src/main/java/bisq/cli/opts/GetTransactionOptionParser.java
new file mode 100644
index 00000000000..d4266eb9ff7
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/GetTransactionOptionParser.java
@@ -0,0 +1,52 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_TRANSACTION_ID;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class GetTransactionOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec txIdOpt = parser.accepts(OPT_TRANSACTION_ID, "id of transaction")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ public GetTransactionOptionParser(String[] args) {
+ super(args);
+ }
+
+ public GetTransactionOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(txIdOpt))
+ throw new IllegalArgumentException("no tx id specified");
+
+ return this;
+ }
+
+ public String getTxId() {
+ return options.valueOf(txIdOpt);
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/MethodOpts.java b/cli/src/main/java/bisq/cli/opts/MethodOpts.java
new file mode 100644
index 00000000000..da639857522
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/MethodOpts.java
@@ -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 .
+ */
+
+package bisq.cli.opts;
+
+public interface MethodOpts {
+
+ MethodOpts parse();
+
+ boolean isForHelp();
+
+}
diff --git a/cli/src/main/java/bisq/cli/opts/OptLabel.java b/cli/src/main/java/bisq/cli/opts/OptLabel.java
new file mode 100644
index 00000000000..5cbd068ce53
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/OptLabel.java
@@ -0,0 +1,51 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+/**
+ * CLI opt label definitions.
+ */
+public class OptLabel {
+ public final static String OPT_ADDRESS = "address";
+ public final static String OPT_AMOUNT = "amount";
+ public final static String OPT_CURRENCY_CODE = "currency-code";
+ public final static String OPT_DIRECTION = "direction";
+ public final static String OPT_DISPUTE_AGENT_TYPE = "dispute-agent-type";
+ public final static String OPT_FEE_CURRENCY = "fee-currency";
+ public final static String OPT_FIXED_PRICE = "fixed-price";
+ public final static String OPT_HELP = "help";
+ public final static String OPT_HOST = "host";
+ public final static String OPT_MEMO = "memo";
+ public final static String OPT_MKT_PRICE_MARGIN = "market-price-margin";
+ public final static String OPT_MIN_AMOUNT = "min-amount";
+ public final static String OPT_OFFER_ID = "offer-id";
+ public final static String OPT_PASSWORD = "password";
+ public final static String OPT_PAYMENT_ACCOUNT = "payment-account";
+ public final static String OPT_PAYMENT_ACCOUNT_FORM = "payment-account-form";
+ public final static String OPT_PAYMENT_METHOD_ID = "payment-method-id";
+ public final static String OPT_PORT = "port";
+ public final static String OPT_REGISTRATION_KEY = "registration-key";
+ public final static String OPT_SECURITY_DEPOSIT = "security-deposit";
+ public final static String OPT_SHOW_CONTRACT = "show-contract";
+ public final static String OPT_TRADE_ID = "trade-id";
+ public final static String OPT_TIMEOUT = "timeout";
+ public final static String OPT_TRANSACTION_ID = "transaction-id";
+ public final static String OPT_TX_FEE_RATE = "tx-fee-rate";
+ public final static String OPT_WALLET_PASSWORD = "wallet-password";
+ public final static String OPT_NEW_WALLET_PASSWORD = "new-wallet-password";
+}
diff --git a/cli/src/main/java/bisq/cli/opts/RegisterDisputeAgentOptionParser.java b/cli/src/main/java/bisq/cli/opts/RegisterDisputeAgentOptionParser.java
new file mode 100644
index 00000000000..428555a3493
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/RegisterDisputeAgentOptionParser.java
@@ -0,0 +1,64 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_DISPUTE_AGENT_TYPE;
+import static bisq.cli.opts.OptLabel.OPT_REGISTRATION_KEY;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class RegisterDisputeAgentOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec disputeAgentTypeOpt = parser.accepts(OPT_DISPUTE_AGENT_TYPE, "dispute agent type")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec registrationKeyOpt = parser.accepts(OPT_REGISTRATION_KEY, "registration key")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ public RegisterDisputeAgentOptionParser(String[] args) {
+ super(args);
+ }
+
+ public RegisterDisputeAgentOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(disputeAgentTypeOpt))
+ throw new IllegalArgumentException("no dispute agent type specified");
+
+ if (!options.has(registrationKeyOpt))
+ throw new IllegalArgumentException("no registration key specified");
+
+ return this;
+ }
+
+ public String getDisputeAgentType() {
+ return options.valueOf(disputeAgentTypeOpt);
+ }
+
+ public String getRegistrationKey() {
+ return options.valueOf(registrationKeyOpt);
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/RemoveWalletPasswordOptionParser.java b/cli/src/main/java/bisq/cli/opts/RemoveWalletPasswordOptionParser.java
new file mode 100644
index 00000000000..5b9a3915941
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/RemoveWalletPasswordOptionParser.java
@@ -0,0 +1,52 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_WALLET_PASSWORD;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class RemoveWalletPasswordOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec passwordOpt = parser.accepts(OPT_WALLET_PASSWORD, "bisq wallet password")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ public RemoveWalletPasswordOptionParser(String[] args) {
+ super(args);
+ }
+
+ public RemoveWalletPasswordOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(passwordOpt))
+ throw new IllegalArgumentException("no password specified");
+
+ return this;
+ }
+
+ public String getPassword() {
+ return options.valueOf(passwordOpt);
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/SendBsqOptionParser.java b/cli/src/main/java/bisq/cli/opts/SendBsqOptionParser.java
new file mode 100644
index 00000000000..3bffce785c4
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/SendBsqOptionParser.java
@@ -0,0 +1,73 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_ADDRESS;
+import static bisq.cli.opts.OptLabel.OPT_AMOUNT;
+import static bisq.cli.opts.OptLabel.OPT_TX_FEE_RATE;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class SendBsqOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec addressOpt = parser.accepts(OPT_ADDRESS, "destination bsq address")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec amountOpt = parser.accepts(OPT_AMOUNT, "amount of bsq to send")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec feeRateOpt = parser.accepts(OPT_TX_FEE_RATE, "optional tx fee rate (sats/byte)")
+ .withOptionalArg()
+ .defaultsTo(EMPTY);
+
+ public SendBsqOptionParser(String[] args) {
+ super(args);
+ }
+
+ public SendBsqOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(addressOpt))
+ throw new IllegalArgumentException("no bsq address specified");
+
+ if (!options.has(amountOpt))
+ throw new IllegalArgumentException("no bsq amount specified");
+
+ return this;
+ }
+
+ public String getAddress() {
+ return options.valueOf(addressOpt);
+ }
+
+ public String getAmount() {
+ return options.valueOf(amountOpt);
+ }
+
+ public String getFeeRate() {
+ return options.has(feeRateOpt) ? options.valueOf(feeRateOpt) : "";
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/SendBtcOptionParser.java b/cli/src/main/java/bisq/cli/opts/SendBtcOptionParser.java
new file mode 100644
index 00000000000..8c3f9762019
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/SendBtcOptionParser.java
@@ -0,0 +1,82 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_ADDRESS;
+import static bisq.cli.opts.OptLabel.OPT_AMOUNT;
+import static bisq.cli.opts.OptLabel.OPT_MEMO;
+import static bisq.cli.opts.OptLabel.OPT_TX_FEE_RATE;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class SendBtcOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec addressOpt = parser.accepts(OPT_ADDRESS, "destination btc address")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec amountOpt = parser.accepts(OPT_AMOUNT, "amount of btc to send")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec feeRateOpt = parser.accepts(OPT_TX_FEE_RATE, "optional tx fee rate (sats/byte)")
+ .withOptionalArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec memoOpt = parser.accepts(OPT_MEMO, "optional tx memo")
+ .withOptionalArg()
+ .defaultsTo(EMPTY);
+
+ public SendBtcOptionParser(String[] args) {
+ super(args);
+ }
+
+ public SendBtcOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(addressOpt))
+ throw new IllegalArgumentException("no btc address specified");
+
+ if (!options.has(amountOpt))
+ throw new IllegalArgumentException("no btc amount specified");
+
+ return this;
+ }
+
+ public String getAddress() {
+ return options.valueOf(addressOpt);
+ }
+
+ public String getAmount() {
+ return options.valueOf(amountOpt);
+ }
+
+ public String getFeeRate() {
+ return options.has(feeRateOpt) ? options.valueOf(feeRateOpt) : "";
+ }
+
+ public String getMemo() {
+ return options.has(memoOpt) ? options.valueOf(memoOpt) : "";
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/SetTxFeeRateOptionParser.java b/cli/src/main/java/bisq/cli/opts/SetTxFeeRateOptionParser.java
new file mode 100644
index 00000000000..9d4b5e71b3e
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/SetTxFeeRateOptionParser.java
@@ -0,0 +1,53 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_TX_FEE_RATE;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class SetTxFeeRateOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec feeRateOpt = parser.accepts(OPT_TX_FEE_RATE,
+ "tx fee rate preference (sats/byte)")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ public SetTxFeeRateOptionParser(String[] args) {
+ super(args);
+ }
+
+ public SetTxFeeRateOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(feeRateOpt))
+ throw new IllegalArgumentException("no tx fee rate specified");
+
+ return this;
+ }
+
+ public String getFeeRate() {
+ return options.valueOf(feeRateOpt);
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/SetWalletPasswordOptionParser.java b/cli/src/main/java/bisq/cli/opts/SetWalletPasswordOptionParser.java
new file mode 100644
index 00000000000..d55b1bf33b4
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/SetWalletPasswordOptionParser.java
@@ -0,0 +1,61 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_NEW_WALLET_PASSWORD;
+import static bisq.cli.opts.OptLabel.OPT_WALLET_PASSWORD;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class SetWalletPasswordOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec passwordOpt = parser.accepts(OPT_WALLET_PASSWORD, "bisq wallet password")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec newPasswordOpt = parser.accepts(OPT_NEW_WALLET_PASSWORD, "new bisq wallet password")
+ .withOptionalArg()
+ .defaultsTo(EMPTY);
+
+ public SetWalletPasswordOptionParser(String[] args) {
+ super(args);
+ }
+
+ public SetWalletPasswordOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(passwordOpt))
+ throw new IllegalArgumentException("no password specified");
+
+ return this;
+ }
+
+ public String getPassword() {
+ return options.valueOf(passwordOpt);
+ }
+
+ public String getNewPassword() {
+ return options.has(newPasswordOpt) ? options.valueOf(newPasswordOpt) : "";
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/SimpleMethodOptionParser.java b/cli/src/main/java/bisq/cli/opts/SimpleMethodOptionParser.java
new file mode 100644
index 00000000000..a0e396d63af
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/SimpleMethodOptionParser.java
@@ -0,0 +1,30 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+public class SimpleMethodOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ public SimpleMethodOptionParser(String[] args) {
+ super(args);
+ }
+
+ public SimpleMethodOptionParser parse() {
+ return (SimpleMethodOptionParser) super.parse();
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/TakeOfferOptionParser.java b/cli/src/main/java/bisq/cli/opts/TakeOfferOptionParser.java
new file mode 100644
index 00000000000..75ef2885b04
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/TakeOfferOptionParser.java
@@ -0,0 +1,73 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_FEE_CURRENCY;
+import static bisq.cli.opts.OptLabel.OPT_OFFER_ID;
+import static bisq.cli.opts.OptLabel.OPT_PAYMENT_ACCOUNT;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class TakeOfferOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec offerIdOpt = parser.accepts(OPT_OFFER_ID, "id of offer to take")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec paymentAccountIdOpt = parser.accepts(OPT_PAYMENT_ACCOUNT, "id of payment account used for trade")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec takerFeeCurrencyCodeOpt = parser.accepts(OPT_FEE_CURRENCY, "taker fee currency code (bsq|btc)")
+ .withOptionalArg()
+ .defaultsTo("btc");
+
+ public TakeOfferOptionParser(String[] args) {
+ super(args);
+ }
+
+ public TakeOfferOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(offerIdOpt))
+ throw new IllegalArgumentException("no offer id specified");
+
+ if (!options.has(paymentAccountIdOpt))
+ throw new IllegalArgumentException("no payment account id specified");
+
+ return this;
+ }
+
+ public String getOfferId() {
+ return options.valueOf(offerIdOpt);
+ }
+
+ public String getPaymentAccountId() {
+ return options.valueOf(paymentAccountIdOpt);
+ }
+
+ public String getTakerFeeCurrencyCode() {
+ return options.has(takerFeeCurrencyCodeOpt) ? options.valueOf(takerFeeCurrencyCodeOpt) : "btc";
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/UnlockWalletOptionParser.java b/cli/src/main/java/bisq/cli/opts/UnlockWalletOptionParser.java
new file mode 100644
index 00000000000..4446138dd37
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/UnlockWalletOptionParser.java
@@ -0,0 +1,65 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_TIMEOUT;
+import static bisq.cli.opts.OptLabel.OPT_WALLET_PASSWORD;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class UnlockWalletOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec passwordOpt = parser.accepts(OPT_WALLET_PASSWORD, "bisq wallet password")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec unlockTimeoutOpt = parser.accepts(OPT_TIMEOUT, "wallet unlock timeout (s)")
+ .withRequiredArg()
+ .ofType(long.class)
+ .defaultsTo(0L);
+
+ public UnlockWalletOptionParser(String[] args) {
+ super(args);
+ }
+
+ public UnlockWalletOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(passwordOpt))
+ throw new IllegalArgumentException("no password specified");
+
+ if (!options.has(unlockTimeoutOpt) || options.valueOf(unlockTimeoutOpt) <= 0)
+ throw new IllegalArgumentException("no unlock timeout specified");
+
+ return this;
+ }
+
+ public String getPassword() {
+ return options.valueOf(passwordOpt);
+ }
+
+ public long getUnlockTimeout() {
+ return options.valueOf(unlockTimeoutOpt);
+ }
+}
diff --git a/cli/src/main/java/bisq/cli/opts/WithdrawFundsOptionParser.java b/cli/src/main/java/bisq/cli/opts/WithdrawFundsOptionParser.java
new file mode 100644
index 00000000000..382fe2c883a
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/opts/WithdrawFundsOptionParser.java
@@ -0,0 +1,70 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli.opts;
+
+
+import joptsimple.OptionSpec;
+
+import static bisq.cli.opts.OptLabel.OPT_ADDRESS;
+import static bisq.cli.opts.OptLabel.OPT_MEMO;
+import static bisq.cli.opts.OptLabel.OPT_TRADE_ID;
+import static joptsimple.internal.Strings.EMPTY;
+
+public class WithdrawFundsOptionParser extends AbstractMethodOptionParser implements MethodOpts {
+
+ final OptionSpec tradeIdOpt = parser.accepts(OPT_TRADE_ID, "id of trade to get")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec addressOpt = parser.accepts(OPT_ADDRESS, "destination btc address")
+ .withRequiredArg()
+ .defaultsTo(EMPTY);
+
+ final OptionSpec memoOpt = parser.accepts(OPT_MEMO, "optional tx memo")
+ .withOptionalArg()
+ .defaultsTo(EMPTY);
+
+ public WithdrawFundsOptionParser(String[] args) {
+ super(args);
+ }
+
+ public WithdrawFundsOptionParser parse() {
+ super.parse();
+
+ // Short circuit opt validation if user just wants help.
+ if (options.has(helpOpt))
+ return this;
+
+ if (!options.has(tradeIdOpt))
+ throw new IllegalArgumentException("no trade id specified");
+
+ return this;
+ }
+
+ public String getTradeId() {
+ return options.valueOf(tradeIdOpt);
+ }
+
+ public String getAddress() {
+ return options.valueOf(addressOpt);
+ }
+
+ public String getMemo() {
+ return options.has(memoOpt) ? options.valueOf(memoOpt) : "";
+ }
+}
From f4e735faec3233c0a0e892382bb6f4f4ab42239e Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Thu, 14 Jan 2021 10:25:08 -0300
Subject: [PATCH 04/10] Move CLI method enum to it's own class
This helps reduce size of growing CLI class file.
---
cli/src/main/java/bisq/cli/Method.java | 56 ++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
create mode 100644 cli/src/main/java/bisq/cli/Method.java
diff --git a/cli/src/main/java/bisq/cli/Method.java b/cli/src/main/java/bisq/cli/Method.java
new file mode 100644
index 00000000000..037468b9bd0
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/Method.java
@@ -0,0 +1,56 @@
+/*
+ * 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 .
+ */
+
+package bisq.cli;
+
+/**
+ * Currently supported api methods.
+ */
+public enum Method {
+ createoffer,
+ canceloffer,
+ getoffer,
+ getmyoffer,
+ getoffers,
+ getmyoffers,
+ takeoffer,
+ gettrade,
+ confirmpaymentstarted,
+ confirmpaymentreceived,
+ keepfunds,
+ withdrawfunds,
+ getpaymentmethods,
+ getpaymentacctform,
+ createpaymentacct,
+ getpaymentaccts,
+ getversion,
+ getbalance,
+ getaddressbalance,
+ getfundingaddresses,
+ getunusedbsqaddress,
+ sendbsq,
+ sendbtc,
+ gettxfeerate,
+ settxfeerate,
+ unsettxfeerate,
+ gettransaction,
+ lockwallet,
+ unlockwallet,
+ removewalletpassword,
+ setwalletpassword,
+ registerdisputeagent
+}
From 9f0f083cf7f29d1820c6b7326d6e25ae0e3ad230 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Thu, 14 Jan 2021 10:26:11 -0300
Subject: [PATCH 05/10] Change CLI opts to posix-style
---
cli/src/main/java/bisq/cli/CliMain.java | 628 +++++++++++++-----------
1 file changed, 351 insertions(+), 277 deletions(-)
diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java
index 6df23f9b730..6c3e796942f 100644
--- a/cli/src/main/java/bisq/cli/CliMain.java
+++ b/cli/src/main/java/bisq/cli/CliMain.java
@@ -25,6 +25,7 @@
import bisq.proto.grpc.GetAddressBalanceRequest;
import bisq.proto.grpc.GetBalancesRequest;
import bisq.proto.grpc.GetFundingAddressesRequest;
+import bisq.proto.grpc.GetMethodHelpRequest;
import bisq.proto.grpc.GetMyOfferRequest;
import bisq.proto.grpc.GetMyOffersRequest;
import bisq.proto.grpc.GetOfferRequest;
@@ -69,8 +70,6 @@
import java.io.PrintStream;
import java.io.PrintWriter;
-import java.math.BigDecimal;
-
import java.util.Date;
import java.util.List;
@@ -79,15 +78,43 @@
import static bisq.cli.CurrencyFormat.formatTxFeeRateInfo;
import static bisq.cli.CurrencyFormat.toSatoshis;
import static bisq.cli.CurrencyFormat.toSecurityDepositAsPct;
-import static bisq.cli.NegativeNumberOptions.hasNegativeNumberOptions;
+import static bisq.cli.Method.*;
import static bisq.cli.TableFormat.*;
+import static bisq.cli.opts.OptLabel.OPT_HELP;
+import static bisq.cli.opts.OptLabel.OPT_HOST;
+import static bisq.cli.opts.OptLabel.OPT_PASSWORD;
+import static bisq.cli.opts.OptLabel.OPT_PORT;
+import static bisq.proto.grpc.HelpGrpc.HelpBlockingStub;
import static java.lang.String.format;
import static java.lang.System.err;
import static java.lang.System.exit;
import static java.lang.System.out;
-import static java.math.BigDecimal.ZERO;
import static java.util.Collections.singletonList;
+
+
+import bisq.cli.opts.ArgumentList;
+import bisq.cli.opts.CancelOfferOptionParser;
+import bisq.cli.opts.CreateOfferOptionParser;
+import bisq.cli.opts.CreatePaymentAcctOptionParser;
+import bisq.cli.opts.GetAddressBalanceOptionParser;
+import bisq.cli.opts.GetBalanceOptionParser;
+import bisq.cli.opts.GetOfferOptionParser;
+import bisq.cli.opts.GetOffersOptionParser;
+import bisq.cli.opts.GetPaymentAcctFormOptionParser;
+import bisq.cli.opts.GetTradeOptionParser;
+import bisq.cli.opts.GetTransactionOptionParser;
+import bisq.cli.opts.RegisterDisputeAgentOptionParser;
+import bisq.cli.opts.RemoveWalletPasswordOptionParser;
+import bisq.cli.opts.SendBsqOptionParser;
+import bisq.cli.opts.SendBtcOptionParser;
+import bisq.cli.opts.SetTxFeeRateOptionParser;
+import bisq.cli.opts.SetWalletPasswordOptionParser;
+import bisq.cli.opts.SimpleMethodOptionParser;
+import bisq.cli.opts.TakeOfferOptionParser;
+import bisq.cli.opts.UnlockWalletOptionParser;
+import bisq.cli.opts.WithdrawFundsOptionParser;
+
/**
* A command-line client for the Bisq gRPC API.
*/
@@ -95,41 +122,6 @@
@Slf4j
public class CliMain {
- private enum Method {
- createoffer,
- canceloffer,
- getoffer,
- getmyoffer,
- getoffers,
- getmyoffers,
- takeoffer,
- gettrade,
- confirmpaymentstarted,
- confirmpaymentreceived,
- keepfunds,
- withdrawfunds,
- getpaymentmethods,
- getpaymentacctform,
- createpaymentacct,
- getpaymentaccts,
- getversion,
- getbalance,
- getaddressbalance,
- getfundingaddresses,
- getunusedbsqaddress,
- sendbsq,
- sendbtc,
- gettxfeerate,
- settxfeerate,
- unsettxfeerate,
- gettransaction,
- lockwallet,
- unlockwallet,
- removewalletpassword,
- setwalletpassword,
- registerdisputeagent
- }
-
public static void main(String[] args) {
try {
run(args);
@@ -142,48 +134,47 @@ public static void main(String[] args) {
public static void run(String[] args) {
var parser = new OptionParser();
- var helpOpt = parser.accepts("help", "Print this help text")
+ var helpOpt = parser.accepts(OPT_HELP, "Print this help text")
.forHelp();
- var hostOpt = parser.accepts("host", "rpc server hostname or IP")
+ var hostOpt = parser.accepts(OPT_HOST, "rpc server hostname or ip")
.withRequiredArg()
.defaultsTo("localhost");
- var portOpt = parser.accepts("port", "rpc server port")
+ var portOpt = parser.accepts(OPT_PORT, "rpc server port")
.withRequiredArg()
.ofType(Integer.class)
.defaultsTo(9998);
- var passwordOpt = parser.accepts("password", "rpc server password")
+ var passwordOpt = parser.accepts(OPT_PASSWORD, "rpc server password")
.withRequiredArg();
- var negativeNumberOpts = hasNegativeNumberOptions(args)
- ? new NegativeNumberOptions()
- : null;
-
- // Cache any negative number params that will not be accepted by the parser.
- if (negativeNumberOpts != null)
- args = negativeNumberOpts.removeNegativeNumberOptions(args);
-
- // Parse the options after temporarily removing any negative number params we
- // do not want the parser recognizing as invalid option arguments, e.g., -0.05.
- OptionSet options = parser.parse(args);
-
- if (options.has(helpOpt)) {
- printHelp(parser, out);
- return;
- }
-
+ // Parse the CLI opts host, port, password, method name, and help. The help opt
+ // may indicate the user is asking for method level help, and will be excluded
+ // from the parsed options if a method opt is present in String[] args.
+ OptionSet options = parser.parse(new ArgumentList(args).getCLIArguments());
@SuppressWarnings("unchecked")
var nonOptionArgs = (List) options.nonOptionArguments();
- if (nonOptionArgs.isEmpty()) {
+
+ // If neither the help opt nor a method name is present, print CLI level help
+ // to stderr and throw an exception.
+ if (!options.has(helpOpt) && nonOptionArgs.isEmpty()) {
printHelp(parser, err);
throw new IllegalArgumentException("no method specified");
}
- // Restore any cached negative number params to the nonOptionArgs list.
- if (negativeNumberOpts != null)
- nonOptionArgs = negativeNumberOpts.restoreNegativeNumberOptions(nonOptionArgs);
+ // If the help opt is present, but not a method name, print CLI level help
+ // to stdout.
+ if (options.has(helpOpt) && nonOptionArgs.isEmpty()) {
+ printHelp(parser, out);
+ return;
+ }
+
+ var host = options.valueOf(hostOpt);
+ var port = options.valueOf(portOpt);
+ var password = options.valueOf(passwordOpt);
+ if (password == null)
+ throw new IllegalArgumentException("missing required 'password' option");
var methodName = nonOptionArgs.get(0);
Method method;
@@ -193,14 +184,9 @@ public static void run(String[] args) {
throw new IllegalArgumentException(format("'%s' is not a supported method", methodName));
}
- var host = options.valueOf(hostOpt);
- var port = options.valueOf(portOpt);
- var password = options.valueOf(passwordOpt);
- if (password == null)
- throw new IllegalArgumentException("missing required 'password' option");
-
GrpcStubs grpcStubs = new GrpcStubs(host, port, password);
var disputeAgentsService = grpcStubs.disputeAgentsService;
+ var helpService = grpcStubs.helpService;
var offersService = grpcStubs.offersService;
var paymentAccountsService = grpcStubs.paymentAccountsService;
var tradesService = grpcStubs.tradesService;
@@ -210,15 +196,22 @@ public static void run(String[] args) {
try {
switch (method) {
case getversion: {
+ if (new SimpleMethodOptionParser(args).parse().isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
var request = GetVersionRequest.newBuilder().build();
var version = versionService.getVersion(request).getVersion();
out.println(version);
return;
}
case getbalance: {
- var currencyCode = nonOptionArgs.size() == 2
- ? nonOptionArgs.get(1)
- : "";
+ var opts = new GetBalanceOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var currencyCode = opts.getCurrencyCode();
var request = GetBalancesRequest.newBuilder()
.setCurrencyCode(currencyCode)
.build();
@@ -238,41 +231,50 @@ public static void run(String[] args) {
return;
}
case getaddressbalance: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("no address specified");
-
+ var opts = new GetAddressBalanceOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var address = opts.getAddress();
var request = GetAddressBalanceRequest.newBuilder()
- .setAddress(nonOptionArgs.get(1)).build();
+ .setAddress(address).build();
var reply = walletsService.getAddressBalance(request);
out.println(formatAddressBalanceTbl(singletonList(reply.getAddressBalanceInfo())));
return;
}
case getfundingaddresses: {
+ if (new SimpleMethodOptionParser(args).parse().isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
var request = GetFundingAddressesRequest.newBuilder().build();
var reply = walletsService.getFundingAddresses(request);
out.println(formatAddressBalanceTbl(reply.getAddressBalanceInfoList()));
return;
}
case getunusedbsqaddress: {
+ if (new SimpleMethodOptionParser(args).parse().isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
var request = GetUnusedBsqAddressRequest.newBuilder().build();
var reply = walletsService.getUnusedBsqAddress(request);
out.println(reply.getAddress());
return;
}
case sendbsq: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("no bsq address specified");
-
- var address = nonOptionArgs.get(1);
-
- if (nonOptionArgs.size() < 3)
- throw new IllegalArgumentException("no bsq amount specified");
-
- var amount = nonOptionArgs.get(2);
+ var opts = new SendBsqOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var address = opts.getAddress();
+ var amount = opts.getAmount();
verifyStringIsValidDecimal(amount);
- var txFeeRate = nonOptionArgs.size() == 4 ? nonOptionArgs.get(3) : "";
- if (!txFeeRate.isEmpty())
+ var txFeeRate = opts.getFeeRate();
+ if (txFeeRate.isEmpty())
verifyStringIsValidLong(txFeeRate);
var request = SendBsqRequest.newBuilder()
@@ -289,24 +291,20 @@ public static void run(String[] args) {
return;
}
case sendbtc: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("no btc address specified");
-
- var address = nonOptionArgs.get(1);
-
- if (nonOptionArgs.size() < 3)
- throw new IllegalArgumentException("no btc amount specified");
-
- var amount = nonOptionArgs.get(2);
+ var opts = new SendBtcOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var address = opts.getAddress();
+ var amount = opts.getAmount();
verifyStringIsValidDecimal(amount);
- // TODO Find a better way to handle the two optional parameters.
- var txFeeRate = nonOptionArgs.size() >= 4 ? nonOptionArgs.get(3) : "";
- if (!txFeeRate.isEmpty())
+ var txFeeRate = opts.getFeeRate();
+ if (txFeeRate.isEmpty())
verifyStringIsValidLong(txFeeRate);
- var memo = nonOptionArgs.size() == 5 ? nonOptionArgs.get(4) : "";
-
+ var memo = opts.getMemo();
var request = SendBtcRequest.newBuilder()
.setAddress(address)
.setAmount(amount)
@@ -322,16 +320,22 @@ public static void run(String[] args) {
return;
}
case gettxfeerate: {
+ if (new SimpleMethodOptionParser(args).parse().isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
var request = GetTxFeeRateRequest.newBuilder().build();
var reply = walletsService.getTxFeeRate(request);
out.println(formatTxFeeRateInfo(reply.getTxFeeRateInfo()));
return;
}
case settxfeerate: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("no tx fee rate specified");
-
- var txFeeRate = toLong(nonOptionArgs.get(2));
+ var opts = new SetTxFeeRateOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var txFeeRate = toLong(opts.getFeeRate());
var request = SetTxFeeRatePreferenceRequest.newBuilder()
.setTxFeeRatePreference(txFeeRate)
.build();
@@ -340,16 +344,22 @@ public static void run(String[] args) {
return;
}
case unsettxfeerate: {
+ if (new SimpleMethodOptionParser(args).parse().isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
var request = UnsetTxFeeRatePreferenceRequest.newBuilder().build();
var reply = walletsService.unsetTxFeeRatePreference(request);
out.println(formatTxFeeRateInfo(reply.getTxFeeRateInfo()));
return;
}
case gettransaction: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("no tx id specified");
-
- var txId = nonOptionArgs.get(1);
+ var opts = new GetTransactionOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var txId = opts.getTxId();
var request = GetTransactionRequest.newBuilder()
.setTxId(txId)
.build();
@@ -358,30 +368,21 @@ public static void run(String[] args) {
return;
}
case createoffer: {
- if (nonOptionArgs.size() < 9)
- throw new IllegalArgumentException("incorrect parameter count,"
- + " expecting payment acct id, buy | sell, currency code, amount, min amount,"
- + " use-market-based-price, fixed-price | mkt-price-margin, security-deposit"
- + " [,maker-fee-currency-code = bsq|btc]");
-
- var paymentAcctId = nonOptionArgs.get(1);
- var direction = nonOptionArgs.get(2);
- var currencyCode = nonOptionArgs.get(3);
- var amount = toSatoshis(nonOptionArgs.get(4));
- var minAmount = toSatoshis(nonOptionArgs.get(5));
- var useMarketBasedPrice = Boolean.parseBoolean(nonOptionArgs.get(6));
- var fixedPrice = ZERO.toString();
- var marketPriceMargin = ZERO;
- if (useMarketBasedPrice)
- marketPriceMargin = new BigDecimal(nonOptionArgs.get(7));
- else
- fixedPrice = nonOptionArgs.get(7);
-
- var securityDeposit = toSecurityDepositAsPct(nonOptionArgs.get(8));
- var makerFeeCurrencyCode = nonOptionArgs.size() == 10
- ? nonOptionArgs.get(9)
- : "btc";
-
+ var opts = new CreateOfferOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var paymentAcctId = opts.getPaymentAccountId();
+ var direction = opts.getDirection();
+ var currencyCode = opts.getCurrencyCode();
+ var amount = toSatoshis(opts.getAmount());
+ var minAmount = toSatoshis(opts.getMinAmount());
+ var useMarketBasedPrice = opts.isUsingMktPriceMargin();
+ var fixedPrice = opts.getFixedPrice();
+ var marketPriceMargin = opts.getMktPriceMarginAsBigDecimal();
+ var securityDeposit = toSecurityDepositAsPct(opts.getSecurityDeposit());
+ var makerFeeCurrencyCode = opts.getMakerFeeCurrencyCode();
var request = CreateOfferRequest.newBuilder()
.setDirection(direction)
.setCurrencyCode(currencyCode)
@@ -399,10 +400,12 @@ public static void run(String[] args) {
return;
}
case canceloffer: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("incorrect parameter count, expecting offer id");
-
- var offerId = nonOptionArgs.get(1);
+ var opts = new CancelOfferOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var offerId = opts.getOfferId();
var request = CancelOfferRequest.newBuilder()
.setId(offerId)
.build();
@@ -411,10 +414,12 @@ public static void run(String[] args) {
return;
}
case getoffer: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("incorrect parameter count, expecting offer id");
-
- var offerId = nonOptionArgs.get(1);
+ var opts = new GetOfferOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var offerId = opts.getOfferId();
var request = GetOfferRequest.newBuilder()
.setId(offerId)
.build();
@@ -424,10 +429,12 @@ public static void run(String[] args) {
return;
}
case getmyoffer: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("incorrect parameter count, expecting offer id");
-
- var offerId = nonOptionArgs.get(1);
+ var opts = new GetOfferOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var offerId = opts.getOfferId();
var request = GetMyOfferRequest.newBuilder()
.setId(offerId)
.build();
@@ -437,13 +444,13 @@ public static void run(String[] args) {
return;
}
case getoffers: {
- if (nonOptionArgs.size() < 3)
- throw new IllegalArgumentException("incorrect parameter count,"
- + " expecting direction (buy|sell), currency code");
-
- var direction = nonOptionArgs.get(1);
- var currencyCode = nonOptionArgs.get(2);
-
+ var opts = new GetOffersOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var direction = opts.getDirection();
+ var currencyCode = opts.getCurrencyCode();
var request = GetOffersRequest.newBuilder()
.setDirection(direction)
.setCurrencyCode(currencyCode)
@@ -459,13 +466,13 @@ public static void run(String[] args) {
return;
}
case getmyoffers: {
- if (nonOptionArgs.size() < 3)
- throw new IllegalArgumentException("incorrect parameter count,"
- + " expecting direction (buy|sell), currency code");
-
- var direction = nonOptionArgs.get(1);
- var currencyCode = nonOptionArgs.get(2);
-
+ var opts = new GetOffersOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var direction = opts.getDirection();
+ var currencyCode = opts.getCurrencyCode();
var request = GetMyOffersRequest.newBuilder()
.setDirection(direction)
.setCurrencyCode(currencyCode)
@@ -481,16 +488,14 @@ public static void run(String[] args) {
return;
}
case takeoffer: {
- if (nonOptionArgs.size() < 3)
- throw new IllegalArgumentException("incorrect parameter count, " +
- " expecting offer id, payment acct id [,taker fee currency code = bsq|btc]");
-
- var offerId = nonOptionArgs.get(1);
- var paymentAccountId = nonOptionArgs.get(2);
- var takerFeeCurrencyCode = nonOptionArgs.size() == 4
- ? nonOptionArgs.get(3)
- : "btc";
-
+ var opts = new TakeOfferOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var offerId = opts.getOfferId();
+ var paymentAccountId = opts.getPaymentAccountId();
+ var takerFeeCurrencyCode = opts.getTakerFeeCurrencyCode();
var request = TakeOfferRequest.newBuilder()
.setOfferId(offerId)
.setPaymentAccountId(paymentAccountId)
@@ -502,30 +507,32 @@ public static void run(String[] args) {
}
case gettrade: {
// TODO make short-id a valid argument?
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("incorrect parameter count, "
- + " expecting trade id [,showcontract = true|false]");
-
- var tradeId = nonOptionArgs.get(1);
- var showContract = false;
- if (nonOptionArgs.size() == 3)
- showContract = Boolean.getBoolean(nonOptionArgs.get(2));
-
+ var opts = new GetTradeOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var tradeId = opts.getTradeId();
+ var showContract = opts.getShowContract();
var request = GetTradeRequest.newBuilder()
.setTradeId(tradeId)
.build();
var reply = tradesService.getTrade(request);
+
if (showContract)
out.println(reply.getTrade().getContractAsJson());
else
out.println(TradeFormat.format(reply.getTrade()));
+
return;
}
case confirmpaymentstarted: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("incorrect parameter count, expecting trade id");
-
- var tradeId = nonOptionArgs.get(1);
+ var opts = new GetTradeOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var tradeId = opts.getTradeId();
var request = ConfirmPaymentStartedRequest.newBuilder()
.setTradeId(tradeId)
.build();
@@ -534,10 +541,12 @@ public static void run(String[] args) {
return;
}
case confirmpaymentreceived: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("incorrect parameter count, expecting trade id");
-
- var tradeId = nonOptionArgs.get(1);
+ var opts = new GetTradeOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var tradeId = opts.getTradeId();
var request = ConfirmPaymentReceivedRequest.newBuilder()
.setTradeId(tradeId)
.build();
@@ -546,10 +555,12 @@ public static void run(String[] args) {
return;
}
case keepfunds: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("incorrect parameter count, expecting trade id");
-
- var tradeId = nonOptionArgs.get(1);
+ var opts = new GetTradeOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var tradeId = opts.getTradeId();
var request = KeepFundsRequest.newBuilder()
.setTradeId(tradeId)
.build();
@@ -558,16 +569,15 @@ public static void run(String[] args) {
return;
}
case withdrawfunds: {
- if (nonOptionArgs.size() < 3)
- throw new IllegalArgumentException("incorrect parameter count, "
- + " expecting trade id, bitcoin wallet address [,\"memo\"]");
-
- var tradeId = nonOptionArgs.get(1);
- var address = nonOptionArgs.get(2);
- // A multi-word memo must be double quoted.
- var memo = nonOptionArgs.size() == 4
- ? nonOptionArgs.get(3)
- : "";
+ var opts = new WithdrawFundsOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var tradeId = opts.getTradeId();
+ var address = opts.getAddress();
+ // Multi-word memos must be double quoted.
+ var memo = opts.getMemo();
var request = WithdrawFundsRequest.newBuilder()
.setTradeId(tradeId)
.setAddress(address)
@@ -578,16 +588,22 @@ public static void run(String[] args) {
return;
}
case getpaymentmethods: {
+ if (new SimpleMethodOptionParser(args).parse().isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
var request = GetPaymentMethodsRequest.newBuilder().build();
var reply = paymentAccountsService.getPaymentMethods(request);
reply.getPaymentMethodsList().forEach(p -> out.println(p.getId()));
return;
}
case getpaymentacctform: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("incorrect parameter count, expecting payment method id");
-
- var paymentMethodId = nonOptionArgs.get(1);
+ var opts = new GetPaymentAcctFormOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var paymentMethodId = opts.getPaymentMethodId();
var request = GetPaymentAccountFormRequest.newBuilder()
.setPaymentMethodId(paymentMethodId)
.build();
@@ -602,22 +618,18 @@ public static void run(String[] args) {
return;
}
case createpaymentacct: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException(
- "incorrect parameter count, expecting path to payment account form");
-
- var paymentAccountFormPath = Paths.get(nonOptionArgs.get(1));
- if (!paymentAccountFormPath.toFile().exists())
- throw new IllegalStateException(
- format("payment account form '%s' could not be found",
- paymentAccountFormPath.toString()));
-
+ var opts = new CreatePaymentAcctOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var paymentAccountForm = opts.getPaymentAcctForm();
String jsonString;
try {
- jsonString = new String(Files.readAllBytes(paymentAccountFormPath));
+ jsonString = new String(Files.readAllBytes(paymentAccountForm));
} catch (IOException e) {
throw new IllegalStateException(
- format("could not read %s", paymentAccountFormPath.toString()));
+ format("could not read %s", paymentAccountForm.toString()));
}
var request = CreatePaymentAccountRequest.newBuilder()
@@ -629,6 +641,10 @@ public static void run(String[] args) {
return;
}
case getpaymentaccts: {
+ if (new SimpleMethodOptionParser(args).parse().isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
var request = GetPaymentAccountsRequest.newBuilder().build();
var reply = paymentAccountsService.getPaymentAccounts(request);
@@ -641,56 +657,66 @@ public static void run(String[] args) {
return;
}
case lockwallet: {
+ if (new SimpleMethodOptionParser(args).parse().isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
var request = LockWalletRequest.newBuilder().build();
walletsService.lockWallet(request);
out.println("wallet locked");
return;
}
case unlockwallet: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("no password specified");
-
- if (nonOptionArgs.size() < 3)
- throw new IllegalArgumentException("no unlock timeout specified");
-
- var timeout = toLong(nonOptionArgs.get(2));
+ var opts = new UnlockWalletOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var walletPassword = opts.getPassword();
+ var timeout = opts.getUnlockTimeout();
var request = UnlockWalletRequest.newBuilder()
- .setPassword(nonOptionArgs.get(1))
+ .setPassword(walletPassword)
.setTimeout(timeout).build();
walletsService.unlockWallet(request);
out.println("wallet unlocked");
return;
}
case removewalletpassword: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("no password specified");
-
+ var opts = new RemoveWalletPasswordOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var walletPassword = opts.getPassword();
var request = RemoveWalletPasswordRequest.newBuilder()
- .setPassword(nonOptionArgs.get(1)).build();
+ .setPassword(walletPassword).build();
walletsService.removeWalletPassword(request);
out.println("wallet decrypted");
return;
}
case setwalletpassword: {
- if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("no password specified");
-
+ var opts = new SetWalletPasswordOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var walletPassword = opts.getPassword();
+ var newWalletPassword = opts.getNewPassword();
var requestBuilder = SetWalletPasswordRequest.newBuilder()
- .setPassword(nonOptionArgs.get(1));
- var hasNewPassword = nonOptionArgs.size() == 3;
- if (hasNewPassword)
- requestBuilder.setNewPassword(nonOptionArgs.get(2));
+ .setPassword(walletPassword)
+ .setNewPassword(newWalletPassword);
walletsService.setWalletPassword(requestBuilder.build());
- out.println("wallet encrypted" + (hasNewPassword ? " with new password" : ""));
+ out.println("wallet encrypted" + (!newWalletPassword.isEmpty() ? " with new password" : ""));
return;
}
case registerdisputeagent: {
- if (nonOptionArgs.size() < 3)
- throw new IllegalArgumentException(
- "incorrect parameter count, expecting dispute agent type, registration key");
-
- var disputeAgentType = nonOptionArgs.get(1);
- var registrationKey = nonOptionArgs.get(2);
+ var opts = new RegisterDisputeAgentOptionParser(args).parse();
+ if (opts.isForHelp()) {
+ out.println(getMethodHelp(helpService, method));
+ return;
+ }
+ var disputeAgentType = opts.getDisputeAgentType();
+ var registrationKey = opts.getRegistrationKey();
var requestBuilder = RegisterDisputeAgentRequest.newBuilder()
.setDisputeAgentType(disputeAgentType).setRegistrationKey(registrationKey);
disputeAgentsService.registerDisputeAgent(requestBuilder.build());
@@ -759,7 +785,7 @@ private static File saveFileToDisk(String prefix,
}
}
- private static void printHelp(OptionParser parser, PrintStream stream) {
+ private static void printHelp(OptionParser parser, @SuppressWarnings("SameParameterValue") PrintStream stream) {
try {
stream.println("Bisq RPC Client");
stream.println();
@@ -770,45 +796,93 @@ private static void printHelp(OptionParser parser, PrintStream stream) {
String rowFormat = "%-24s%-52s%s%n";
stream.format(rowFormat, "Method", "Params", "Description");
stream.format(rowFormat, "------", "------", "------------");
- stream.format(rowFormat, "getversion", "", "Get server version");
- stream.format(rowFormat, "getbalance", "[currency code = bsq|btc]", "Get server wallet balances");
- stream.format(rowFormat, "getaddressbalance", "address", "Get server wallet address balance");
- stream.format(rowFormat, "getfundingaddresses", "", "Get BTC funding addresses");
- stream.format(rowFormat, "getunusedbsqaddress", "", "Get unused BSQ address");
- stream.format(rowFormat, "sendbsq", "address, amount [,tx fee rate (sats/byte)]", "Send BSQ");
- stream.format(rowFormat, "sendbtc", "address, amount [,tx fee rate (sats/byte), \"memo\"]", "Send BTC");
- stream.format(rowFormat, "gettxfeerate", "", "Get current tx fee rate in sats/byte");
- stream.format(rowFormat, "settxfeerate", "satoshis (per byte)", "Set custom tx fee rate in sats/byte");
- stream.format(rowFormat, "unsettxfeerate", "", "Unset custom tx fee rate");
- stream.format(rowFormat, "gettransaction", "transaction id", "Get transaction with id");
- stream.format(rowFormat, "createoffer", "payment acct id, buy | sell, currency code, \\", "Create and place an offer");
- stream.format(rowFormat, "", "amount (btc), min amount, use mkt based price, \\", "");
- stream.format(rowFormat, "", "fixed price (btc) | mkt price margin (%), security deposit (%) \\", "");
- stream.format(rowFormat, "", "[,maker fee currency code = bsq|btc]", "");
- stream.format(rowFormat, "canceloffer", "offer id", "Cancel offer with id");
- stream.format(rowFormat, "getoffer", "offer id", "Get current offer with id");
- stream.format(rowFormat, "getmyoffer", "offer id", "Get my current offer with id");
- stream.format(rowFormat, "getoffers", "buy | sell, currency code", "Get current offers");
- stream.format(rowFormat, "getmyoffers", "buy | sell, currency code", "Get my current offers");
- stream.format(rowFormat, "takeoffer", "offer id [,taker fee currency code = bsq|btc]", "Take offer with id");
- stream.format(rowFormat, "gettrade", "trade id [,showcontract = true|false]", "Get trade summary or full contract");
- stream.format(rowFormat, "confirmpaymentstarted", "trade id", "Confirm payment started");
- stream.format(rowFormat, "confirmpaymentreceived", "trade id", "Confirm payment received");
- stream.format(rowFormat, "keepfunds", "trade id", "Keep received funds in Bisq wallet");
- stream.format(rowFormat, "withdrawfunds", "trade id, bitcoin wallet address [,\"memo\"]",
+ stream.format(rowFormat, getversion.name(), "", "Get server version");
+ stream.println();
+ stream.format(rowFormat, getbalance.name(), "[--currency-code=]", "Get server wallet balances");
+ stream.println();
+ stream.format(rowFormat, getaddressbalance.name(), "--address=", "Get server wallet address balance");
+ stream.println();
+ stream.format(rowFormat, getfundingaddresses.name(), "", "Get BTC funding addresses");
+ stream.println();
+ stream.format(rowFormat, getunusedbsqaddress.name(), "", "Get unused BSQ address");
+ stream.println();
+ stream.format(rowFormat, sendbsq.name(), "--address= --amount= \\", "Send BSQ");
+ stream.format(rowFormat, "", "[--tx-fee-rate=]", "");
+ stream.println();
+ stream.format(rowFormat, sendbtc.name(), "--address= --amount= \\", "Send BTC");
+ stream.format(rowFormat, "", "[--tx-fee-rate=]", "");
+ stream.println();
+ stream.format(rowFormat, gettxfeerate.name(), "", "Get current tx fee rate in sats/byte");
+ stream.println();
+ stream.format(rowFormat, settxfeerate.name(), "--tx-fee-rate=", "Set custom tx fee rate in sats/byte");
+ stream.println();
+ stream.format(rowFormat, unsettxfeerate.name(), "", "Unset custom tx fee rate");
+ stream.println();
+ stream.format(rowFormat, gettransaction.name(), "--transaction-id=", "Get transaction with id");
+ stream.println();
+ stream.format(rowFormat, createoffer.name(), "--payment-account= \\", "Create and place an offer");
+ stream.format(rowFormat, "", "--direction= \\", "");
+ stream.format(rowFormat, "", "--currency-code= \\", "");
+ stream.format(rowFormat, "", "--amount= \\", "");
+ stream.format(rowFormat, "", "[--min-amount=] \\", "");
+ stream.format(rowFormat, "", "--fixed-price= | --market-price=margin= \\", "");
+ stream.format(rowFormat, "", "--security-deposit= \\", "");
+ stream.format(rowFormat, "", "[--fee-currency=]", "");
+ stream.println();
+ stream.format(rowFormat, canceloffer.name(), "--offer-id=", "Cancel offer with id");
+ stream.println();
+ stream.format(rowFormat, getoffer.name(), "--offer-id=", "Get current offer with id");
+ stream.println();
+ stream.format(rowFormat, getmyoffer.name(), "--offer-id=", "Get my current offer with id");
+ stream.println();
+ stream.format(rowFormat, getoffers.name(), "--direction= \\", "Get current offers");
+ stream.format(rowFormat, "", "--currency-code=", "");
+ stream.println();
+ stream.format(rowFormat, getmyoffers.name(), "--direction= \\", "Get my current offers");
+ stream.format(rowFormat, "", "--currency-code=", "");
+ stream.println();
+ stream.format(rowFormat, takeoffer.name(), "--offer-id= [--fee-currency=]", "Take offer with id");
+ stream.println();
+ stream.format(rowFormat, gettrade.name(), "--trade-id= \\", "Get trade summary or full contract");
+ stream.format(rowFormat, "", "[--show-contract=]", "");
+ stream.println();
+ stream.format(rowFormat, confirmpaymentstarted.name(), "--trade-id=", "Confirm payment started");
+ stream.println();
+ stream.format(rowFormat, confirmpaymentreceived.name(), "--trade-id=", "Confirm payment received");
+ stream.println();
+ stream.format(rowFormat, keepfunds.name(), "--trade-id=", "Keep received funds in Bisq wallet");
+ stream.println();
+ stream.format(rowFormat, withdrawfunds.name(), "--trade-id= --address= \\",
"Withdraw received funds to external wallet address");
- stream.format(rowFormat, "getpaymentmethods", "", "Get list of supported payment account method ids");
- stream.format(rowFormat, "getpaymentacctform", "payment method id", "Get a new payment account form");
- stream.format(rowFormat, "createpaymentacct", "path to payment account form", "Create a new payment account");
- stream.format(rowFormat, "getpaymentaccts", "", "Get user payment accounts");
- stream.format(rowFormat, "lockwallet", "", "Remove wallet password from memory, locking the wallet");
- stream.format(rowFormat, "unlockwallet", "password timeout",
+ stream.format(rowFormat, "", "[--memo=<\"memo\">]", "");
+ stream.println();
+ stream.format(rowFormat, getpaymentmethods.name(), "", "Get list of supported payment account method ids");
+ stream.println();
+ stream.format(rowFormat, getpaymentacctform.name(), "--payment-method-id=", "Get a new payment account form");
+ stream.println();
+ stream.format(rowFormat, createpaymentacct.name(), "--payment-account-form=", "Create a new payment account");
+ stream.println();
+ stream.format(rowFormat, getpaymentaccts.name(), "", "Get user payment accounts");
+ stream.println();
+ stream.format(rowFormat, lockwallet.name(), "", "Remove wallet password from memory, locking the wallet");
+ stream.println();
+ stream.format(rowFormat, unlockwallet.name(), "--wallet-password= --timeout=",
"Store wallet password in memory for timeout seconds");
- stream.format(rowFormat, "setwalletpassword", "password [newpassword]",
+ stream.println();
+ stream.format(rowFormat, setwalletpassword.name(), "--wallet-password= \\",
"Encrypt wallet with password, or set new password on encrypted wallet");
+ stream.format(rowFormat, "", "[--new-wallet-password=]", "");
+ stream.println();
+ stream.println("Method Help Usage: bisq-cli [options] --help");
stream.println();
} catch (IOException ex) {
ex.printStackTrace(stream);
}
}
+
+ private static String getMethodHelp(HelpBlockingStub helpService, Method method) {
+ var request = GetMethodHelpRequest.newBuilder().setMethodName(method.name()).build();
+ var reply = helpService.getMethodHelp(request);
+ return reply.getMethodHelp();
+ }
}
From acf2c7c50ef1bf7c3f03f35c71a81ebc3b0e98eb Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Thu, 14 Jan 2021 10:27:47 -0300
Subject: [PATCH 06/10] Remove deprecated NegativeNumberOptions
Not needed anymore, and all method opts are posix style.
(The opts parsing lib used to treat negative numbers as opt labels.)
---
.../java/bisq/cli/NegativeNumberOptions.java | 97 -------------------
1 file changed, 97 deletions(-)
delete mode 100644 cli/src/main/java/bisq/cli/NegativeNumberOptions.java
diff --git a/cli/src/main/java/bisq/cli/NegativeNumberOptions.java b/cli/src/main/java/bisq/cli/NegativeNumberOptions.java
deleted file mode 100644
index 6623f9ad150..00000000000
--- a/cli/src/main/java/bisq/cli/NegativeNumberOptions.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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 .
- */
-
-package bisq.cli;
-
-import java.math.BigDecimal;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Predicate;
-
-import static java.util.Arrays.stream;
-import static java.util.stream.IntStream.range;
-
-class NegativeNumberOptions {
-
- private final Map negativeNumberParams = new HashMap<>();
-
- String[] removeNegativeNumberOptions(String[] args) {
- // Cache any negative number params that will be rejected by the parser.
- // This should be called before command line parsing.
- int skipped = getIndexOfMethodInArgs(args);
- for (int i = skipped; i < args.length; i++) {
- if (isNegativeNumber.test(args[i])) {
- String param = args[i];
- negativeNumberParams.put(i - skipped, new BigDecimal(param).toString());
- // Substitute a zero placeholder at the index containing the
- // negative number positional option value.
- args[i] = "0";
- }
- }
- return args;
- }
-
- List restoreNegativeNumberOptions(List nonOptionArgs) {
- // Put cached negative number params into a clone of the nonOptionArgs list.
- // This should be called after command line parsing.
- if (!negativeNumberParams.isEmpty()) {
- List nonOptionArgsClone = new ArrayList<>(nonOptionArgs);
- negativeNumberParams.forEach((k, v) -> {
- int idx = k;
- nonOptionArgsClone.set(idx, v);
- });
- return Collections.unmodifiableList(nonOptionArgsClone);
- } else {
- // This should never happen. Instances of this class should not be created
- // if there are no negative number options.
- return nonOptionArgs;
- }
- }
-
- static boolean hasNegativeNumberOptions(String[] args) {
- return stream(args).anyMatch(isNegativeNumber);
- }
-
- private static final Predicate isNegativeNumber = (param) -> {
- if (param.length() > 1 && param.startsWith("-")) {
- try {
- new BigDecimal(param);
- return true;
- } catch (NumberFormatException ignored) {
- // empty
- }
- }
- return false;
- };
-
- private int getIndexOfMethodInArgs(String[] args) {
- // The first argument that does not start with '-' or '--' is the method name.
- // Skip over the --password=xyz [--host=s --port=n] options.
- int skipped = range(0, args.length)
- .filter(i -> !args[i].startsWith("-"))
- .findFirst()
- .orElse(-1);
- if (skipped >= 0)
- return skipped;
- else
- throw new IllegalArgumentException("required --password option not found");
- }
-}
From baf79e2b50024998e2d3bda8886cfa01ada1f041 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Thu, 14 Jan 2021 19:03:49 -0300
Subject: [PATCH 07/10] Make opt description more generic
---
cli/src/main/java/bisq/cli/opts/GetTradeOptionParser.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cli/src/main/java/bisq/cli/opts/GetTradeOptionParser.java b/cli/src/main/java/bisq/cli/opts/GetTradeOptionParser.java
index d1edf181063..2b7681f3c69 100644
--- a/cli/src/main/java/bisq/cli/opts/GetTradeOptionParser.java
+++ b/cli/src/main/java/bisq/cli/opts/GetTradeOptionParser.java
@@ -26,7 +26,7 @@
public class GetTradeOptionParser extends AbstractMethodOptionParser implements MethodOpts {
- final OptionSpec tradeIdOpt = parser.accepts(OPT_TRADE_ID, "id of trade to get")
+ final OptionSpec tradeIdOpt = parser.accepts(OPT_TRADE_ID, "id of trade")
.withRequiredArg()
.defaultsTo(EMPTY);
From f2a899917c19aa8337cb46c238dff9a8ca2387c6 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Thu, 14 Jan 2021 19:05:27 -0300
Subject: [PATCH 08/10] Fix default opt values
---
.../main/java/bisq/cli/opts/CreateOfferOptionParser.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java b/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java
index 4cb6a24a4cc..d4d7c05c7ad 100644
--- a/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java
+++ b/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java
@@ -50,7 +50,7 @@ public class CreateOfferOptionParser extends AbstractMethodOptionParser implemen
final OptionSpec mktPriceMarginOpt = parser.accepts(OPT_MKT_PRICE_MARGIN, "market btc price margin (%)")
.withOptionalArg()
- .defaultsTo(EMPTY);
+ .defaultsTo("0.00");
final OptionSpec fixedPriceOpt = parser.accepts(OPT_FIXED_PRICE, "fixed btc price")
.withOptionalArg()
@@ -119,7 +119,7 @@ public boolean isUsingMktPriceMargin() {
@SuppressWarnings("unused")
public String getMktPriceMargin() {
- return isUsingMktPriceMargin() ? options.valueOf(mktPriceMarginOpt) : "";
+ return isUsingMktPriceMargin() ? options.valueOf(mktPriceMarginOpt) : "0.00";
}
public BigDecimal getMktPriceMarginAsBigDecimal() {
@@ -127,7 +127,7 @@ public BigDecimal getMktPriceMarginAsBigDecimal() {
}
public String getFixedPrice() {
- return options.has(fixedPriceOpt) ? options.valueOf(fixedPriceOpt) : "";
+ return options.has(fixedPriceOpt) ? options.valueOf(fixedPriceOpt) : "0.00";
}
public String getSecurityDeposit() {
From ec9f783eb5be49e92f8dcffd0a13150e7ce352fb Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Fri, 15 Jan 2021 16:25:39 -0300
Subject: [PATCH 09/10] Remove switch(hardcoded enum.name)
There is no need for a switch here, the doc exists or it does not.
---
.../java/bisq/core/api/CoreHelpService.java | 24 +++++--------------
1 file changed, 6 insertions(+), 18 deletions(-)
diff --git a/core/src/main/java/bisq/core/api/CoreHelpService.java b/core/src/main/java/bisq/core/api/CoreHelpService.java
index a294dcad627..a562856bbbf 100644
--- a/core/src/main/java/bisq/core/api/CoreHelpService.java
+++ b/core/src/main/java/bisq/core/api/CoreHelpService.java
@@ -40,21 +40,7 @@ public CoreHelpService() {
}
public String getMethodHelp(String methodName) {
- switch (methodName) {
- case "createoffer":
- case "getfundingaddresses":
- case "getpaymentaccts":
- case "getpaymentmethods":
- case "gettxfeerate":
- case "getunusedbsqaddress":
- case "getversion":
- case "lockwallet":
- case "takeoffer":
- case "unsettxfeerate":
- return getHelpText(methodName);
- default:
- throw new IllegalStateException("no help found for " + methodName);
- }
+ return getHelpText(methodName);
}
private String getHelpText(String methodName) {
@@ -63,7 +49,7 @@ private String getHelpText(String methodName) {
return readHelpFile(resourceFile);
} catch (NullPointerException ex) {
log.error("", ex);
- throw new IllegalStateException(format("could not find %s help doc", methodName));
+ throw new IllegalStateException(format("no help found for api method %s", methodName));
} catch (IOException ex) {
log.error("", ex);
throw new IllegalStateException(format("could not read %s help doc", methodName));
@@ -87,7 +73,7 @@ private String readHelpFile(String resourceFile) throws NullPointerException, IO
@SuppressWarnings("CommentedOutCode")
public static void main(String[] args) {
CoreHelpService coreHelpService = new CoreHelpService();
- // out.println(coreHelpService.getMethodHelp("getversion"));
+ out.println(coreHelpService.getMethodHelp("getversion"));
// out.println(coreHelpService.getMethodHelp("getfundingaddresses"));
// out.println(coreHelpService.getMethodHelp("getfundingaddresses"));
// out.println(coreHelpService.getMethodHelp("getunusedbsqaddress"));
@@ -96,8 +82,10 @@ public static void main(String[] args) {
// out.println(coreHelpService.getMethodHelp("getpaymentaccts"));
// out.println(coreHelpService.getMethodHelp("lockwallet"));
// out.println(coreHelpService.getMethodHelp("gettxfeerate"));
- out.println(coreHelpService.getMethodHelp("createoffer"));
+ // out.println(coreHelpService.getMethodHelp("createoffer"));
// out.println(coreHelpService.getMethodHelp("takeoffer"));
// out.println(coreHelpService.getMethodHelp("garbage"));
+ // out.println(coreHelpService.getMethodHelp(""));
+ // out.println(coreHelpService.getMethodHelp(null));
}
}
From 1ad7b351b62de1f4e50f752b94952a49bb1ccbf5 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Fri, 15 Jan 2021 16:33:52 -0300
Subject: [PATCH 10/10] Remove uneeded method
---
core/src/main/java/bisq/core/api/CoreHelpService.java | 4 ----
1 file changed, 4 deletions(-)
diff --git a/core/src/main/java/bisq/core/api/CoreHelpService.java b/core/src/main/java/bisq/core/api/CoreHelpService.java
index a562856bbbf..6a4605f7484 100644
--- a/core/src/main/java/bisq/core/api/CoreHelpService.java
+++ b/core/src/main/java/bisq/core/api/CoreHelpService.java
@@ -40,10 +40,6 @@ public CoreHelpService() {
}
public String getMethodHelp(String methodName) {
- return getHelpText(methodName);
- }
-
- private String getHelpText(String methodName) {
String resourceFile = "/help" + separator + methodName + "-" + "help.txt";
try {
return readHelpFile(resourceFile);