diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java
index bbd12b7ccb..bfc814c67a 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 class CoreApi {
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 class CoreApi {
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 0000000000..a294dcad62
--- /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 0000000000..536e2596b6
--- /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 0000000000..0d3e7ea629
--- /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 0000000000..f12b5bd453
--- /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 0000000000..b7f860548d
--- /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 0000000000..3582d5dcf0
--- /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 0000000000..308ad01ba7
--- /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 0000000000..ce3b801db4
--- /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 0000000000..6639dcef5e
--- /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 0000000000..89ab21fc9c
--- /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 0000000000..36767e6f1f
--- /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 0000000000..1a62ed6f9f
--- /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 589645d77d..8e50a98aa1 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 class GrpcServer {
Config config,
PasswordAuthInterceptor passwordAuthInterceptor,
GrpcDisputeAgentsService disputeAgentsService,
+ GrpcHelpService helpService,
GrpcOffersService offersService,
GrpcPaymentAccountsService paymentAccountsService,
GrpcPriceService priceService,
@@ -60,6 +61,7 @@ public class GrpcServer {
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 3ac2ea4bf6..085c3f9074 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
///////////////////////////////////////////////////////////////////////////////////////////