Add API API method 'getnetwork'

Returns name of the BTC network API daemon is connected to.

I am working on some Java bot examples in another repo, and want to stop
worrying about accidentally simulating trade payments on mainnet, despite
all the warnings I add in comments.  The 'getnetwork' method allows bots
to know what network the API daemon is connected to, and gives API bot
devs and users a way to avoid one potential source of costly mistakes.

API CLI manpage and apitest case are included in this commit.
This commit is contained in:
ghubstan 2022-06-16 15:31:03 -03:00
parent 0fc22c02f4
commit ae41e98db9
No known key found for this signature in database
GPG Key ID: E35592D6800A861E
10 changed files with 157 additions and 6 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package bisq.apitest.method.wallet;
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 org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import bisq.apitest.method.MethodTest;
@SuppressWarnings("ConstantConditions")
@Disabled
@Slf4j
@TestMethodOrder(OrderAnnotation.class)
public class GetNetworkTest extends MethodTest {
@BeforeAll
public static void setUp() {
try {
setUpScaffold(alicedaemon);
} catch (Exception ex) {
fail(ex);
}
}
@Test
@Order(1)
public void testGetNetwork() {
var network = aliceClient.getNetwork();
assertEquals("regtest", network);
}
@AfterAll
public static void tearDown() {
tearDownScaffold();
}
}

View File

@ -44,6 +44,7 @@ import bisq.apitest.method.GetMethodHelpTest;
import bisq.apitest.method.GetVersionTest; import bisq.apitest.method.GetVersionTest;
import bisq.apitest.method.MethodTest; import bisq.apitest.method.MethodTest;
import bisq.apitest.method.RegisterDisputeAgentsTest; import bisq.apitest.method.RegisterDisputeAgentsTest;
import bisq.apitest.method.wallet.GetNetworkTest;
@Slf4j @Slf4j
@ -88,6 +89,13 @@ public class StartupTest extends MethodTest {
@Test @Test
@Order(3) @Order(3)
public void testGetNetwork() {
GetNetworkTest test = new GetNetworkTest();
test.testGetNetwork();
}
@Test
@Order(4)
public void testRegisterDisputeAgents() { public void testRegisterDisputeAgents() {
RegisterDisputeAgentsTest test = new RegisterDisputeAgentsTest(); RegisterDisputeAgentsTest test = new RegisterDisputeAgentsTest();
test.testRegisterArbitratorShouldThrowException(); test.testRegisterArbitratorShouldThrowException();
@ -98,7 +106,7 @@ public class StartupTest extends MethodTest {
} }
@Test @Test
@Order(4) @Order(5)
public void testGetCreateOfferHelp() { public void testGetCreateOfferHelp() {
GetMethodHelpTest test = new GetMethodHelpTest(); GetMethodHelpTest test = new GetMethodHelpTest();
test.testGetCreateOfferHelp(); test.testGetCreateOfferHelp();

View File

@ -164,6 +164,15 @@ public class CliMain {
out.println(version); out.println(version);
return; return;
} }
case getnetwork: {
if (new SimpleMethodOptionParser(args).parse().isForHelp()) {
out.println(client.getMethodHelp(method));
return;
}
var network = client.getNetwork();
out.println(network);
return;
}
case getbalance: { case getbalance: {
var opts = new GetBalanceOptionParser(args).parse(); var opts = new GetBalanceOptionParser(args).parse();
if (opts.isForHelp()) { if (opts.isForHelp()) {
@ -822,6 +831,8 @@ public class CliMain {
stream.format(rowFormat, "------", "------", "------------"); stream.format(rowFormat, "------", "------", "------------");
stream.format(rowFormat, getversion.name(), "", "Get server version"); stream.format(rowFormat, getversion.name(), "", "Get server version");
stream.println(); stream.println();
stream.format(rowFormat, getnetwork.name(), "", "Get BTC network: mainnet, testnet3, or regtest");
stream.println();
stream.format(rowFormat, getbalance.name(), "[--currency-code=<bsq|btc>]", "Get server wallet balances"); stream.format(rowFormat, getbalance.name(), "[--currency-code=<bsq|btc>]", "Get server wallet balances");
stream.println(); stream.println();
stream.format(rowFormat, getaddressbalance.name(), "--address=<btc-address>", "Get server wallet address balance"); stream.format(rowFormat, getaddressbalance.name(), "--address=<btc-address>", "Get server wallet address balance");

View File

@ -22,6 +22,7 @@ import bisq.proto.grpc.BalancesInfo;
import bisq.proto.grpc.BsqBalanceInfo; import bisq.proto.grpc.BsqBalanceInfo;
import bisq.proto.grpc.BtcBalanceInfo; import bisq.proto.grpc.BtcBalanceInfo;
import bisq.proto.grpc.GetMethodHelpRequest; import bisq.proto.grpc.GetMethodHelpRequest;
import bisq.proto.grpc.GetNetworkRequest;
import bisq.proto.grpc.GetTradesRequest; import bisq.proto.grpc.GetTradesRequest;
import bisq.proto.grpc.GetVersionRequest; import bisq.proto.grpc.GetVersionRequest;
import bisq.proto.grpc.OfferInfo; import bisq.proto.grpc.OfferInfo;
@ -74,6 +75,11 @@ public final class GrpcClient {
return grpcStubs.versionService.getVersion(request).getVersion(); return grpcStubs.versionService.getVersion(request).getVersion();
} }
public String getNetwork() {
var request = GetNetworkRequest.newBuilder().build();
return grpcStubs.walletsService.getNetwork(request).getNetwork();
}
public BalancesInfo getBalances() { public BalancesInfo getBalances() {
return walletsServiceRequest.getBalances(); return walletsServiceRequest.getBalances();
} }
@ -386,6 +392,7 @@ public final class GrpcClient {
tradeInstant); tradeInstant);
} }
@SuppressWarnings("unused")
public List<PaymentMethod> getCryptoPaymentMethods() { public List<PaymentMethod> getCryptoPaymentMethods() {
return paymentAccountsServiceRequest.getCryptoPaymentMethods(); return paymentAccountsServiceRequest.getCryptoPaymentMethods();
} }

View File

@ -36,6 +36,7 @@ public enum Method {
@Deprecated // Since 27-Dec-2021. @Deprecated // Since 27-Dec-2021.
getmyoffer, // Endpoint to be removed from future version. Use getoffer instead. getmyoffer, // Endpoint to be removed from future version. Use getoffer instead.
getmyoffers, getmyoffers,
getnetwork,
getoffer, getoffer,
getoffers, getoffers,
getpaymentacctform, getpaymentacctform,

View File

@ -360,6 +360,10 @@ public class CoreApi {
// Wallets // Wallets
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public String getNetworkName() {
return walletsService.getNetworkName();
}
public BalancesInfo getBalances(String currencyCode) { public BalancesInfo getBalances(String currencyCode) {
return walletsService.getBalances(currencyCode); return walletsService.getBalances(currencyCode);
} }

View File

@ -91,6 +91,8 @@ import static bisq.core.util.ParsingUtils.parseToCoin;
import static java.lang.String.format; import static java.lang.String.format;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static org.bitcoinj.core.NetworkParameters.PAYMENT_PROTOCOL_ID_REGTEST;
import static org.bitcoinj.core.NetworkParameters.PAYMENT_PROTOCOL_ID_TESTNET;
@Singleton @Singleton
@Slf4j @Slf4j
@ -151,6 +153,18 @@ class CoreWalletsService {
return btcWalletService.getWallet().getContext().getParams(); return btcWalletService.getWallet().getContext().getParams();
} }
String getNetworkName() {
var networkParameters = getNetworkParameters();
switch (networkParameters.getPaymentProtocolId()) {
case PAYMENT_PROTOCOL_ID_TESTNET:
return "testnet3";
case PAYMENT_PROTOCOL_ID_REGTEST:
return "regtest";
default:
return "mainnet";
}
}
BalancesInfo getBalances(String currencyCode) { BalancesInfo getBalances(String currencyCode) {
verifyWalletCurrencyCodeIsValid(currencyCode); verifyWalletCurrencyCodeIsValid(currencyCode);
verifyWalletsAreAvailable(); verifyWalletsAreAvailable();
@ -642,7 +656,7 @@ class CoreWalletsService {
.filter(e -> addressString.equals(e.getAddressString())) .filter(e -> addressString.equals(e.getAddressString()))
.findFirst(); .findFirst();
if (!addressEntry.isPresent()) if (addressEntry.isEmpty())
throw new NotFoundException(format("address %s not found in wallet", addressString)); throw new NotFoundException(format("address %s not found in wallet", addressString));
return addressEntry.get(); return addressEntry.get();

View File

@ -0,0 +1,18 @@
getnetwork
NAME
----
getnetwork - get BTC network name
SYNOPSIS
--------
getnetwork
DESCRIPTION
-----------
Returns the name of the BTC network the API daemon is connected to:
mainnet, testnet3, or regtest.
EXAMPLES
--------
$ ./bisq-cli --password=xyz --port=9998 getnetwork

View File

@ -29,6 +29,8 @@ import bisq.proto.grpc.GetBalancesReply;
import bisq.proto.grpc.GetBalancesRequest; import bisq.proto.grpc.GetBalancesRequest;
import bisq.proto.grpc.GetFundingAddressesReply; import bisq.proto.grpc.GetFundingAddressesReply;
import bisq.proto.grpc.GetFundingAddressesRequest; import bisq.proto.grpc.GetFundingAddressesRequest;
import bisq.proto.grpc.GetNetworkReply;
import bisq.proto.grpc.GetNetworkRequest;
import bisq.proto.grpc.GetTransactionReply; import bisq.proto.grpc.GetTransactionReply;
import bisq.proto.grpc.GetTransactionRequest; import bisq.proto.grpc.GetTransactionRequest;
import bisq.proto.grpc.GetTxFeeRateReply; import bisq.proto.grpc.GetTxFeeRateReply;
@ -95,6 +97,20 @@ class GrpcWalletsService extends WalletsImplBase {
this.exceptionHandler = exceptionHandler; this.exceptionHandler = exceptionHandler;
} }
@Override
public void getNetwork(GetNetworkRequest req, StreamObserver<GetNetworkReply> responseObserver) {
try {
var network = coreApi.getNetworkName();
var reply = GetNetworkReply.newBuilder()
.setNetwork(network)
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} catch (Throwable cause) {
exceptionHandler.handleException(log, cause, responseObserver);
}
}
@Override @Override
public void getBalances(GetBalancesRequest req, StreamObserver<GetBalancesReply> responseObserver) { public void getBalances(GetBalancesRequest req, StreamObserver<GetBalancesReply> responseObserver) {
try { try {

View File

@ -491,7 +491,7 @@ service Trades {
message TakeOfferRequest { message TakeOfferRequest {
string offer_id = 1; // The unique identifier of the offer being taken. string offer_id = 1; // The unique identifier of the offer being taken.
string payment_account_id = 2; // The unique identifier of the payment account used to take offer.. string payment_account_id = 2; // The unique identifier of the payment account used to take offer.
string taker_fee_currency_code = 3; // The code of the currency (BSQ or BTC) used to pay the taker's Bisq trade fee. string taker_fee_currency_code = 3; // The code of the currency (BSQ or BTC) used to pay the taker's Bisq trade fee.
} }
@ -695,6 +695,9 @@ message TxInfo {
* an encryption password on a a wallet, and unlocking / locking an encrypted wallet. * an encryption password on a a wallet, and unlocking / locking an encrypted wallet.
*/ */
service Wallets { service Wallets {
// Get the name of the BTC / BSQ network (mainnet, testnet3, or regtest).
rpc GetNetwork (GetNetworkRequest) returns (GetNetworkReply) {
}
// Get the Bisq wallet's current BSQ and BTC balances. // Get the Bisq wallet's current BSQ and BTC balances.
rpc GetBalances (GetBalancesRequest) returns (GetBalancesReply) { rpc GetBalances (GetBalancesRequest) returns (GetBalancesReply) {
} }
@ -718,7 +721,7 @@ service Wallets {
// Get the Bisq network's most recently available bitcoin miner transaction fee rate, or custom fee rate if set. // Get the Bisq network's most recently available bitcoin miner transaction fee rate, or custom fee rate if set.
rpc GetTxFeeRate (GetTxFeeRateRequest) returns (GetTxFeeRateReply) { rpc GetTxFeeRate (GetTxFeeRateRequest) returns (GetTxFeeRateReply) {
} }
// Set the Bisq daemon's custom bitcoin miner transaction fee rate, in sats/byte.. // Set the Bisq daemon's custom bitcoin miner transaction fee rate, in sats/byte.
rpc SetTxFeeRatePreference (SetTxFeeRatePreferenceRequest) returns (SetTxFeeRatePreferenceReply) { rpc SetTxFeeRatePreference (SetTxFeeRatePreferenceRequest) returns (SetTxFeeRatePreferenceReply) {
} }
// Remove the custom bitcoin miner transaction fee rate; revert to the Bisq network's bitcoin miner transaction fee rate. // Remove the custom bitcoin miner transaction fee rate; revert to the Bisq network's bitcoin miner transaction fee rate.
@ -747,6 +750,13 @@ service Wallets {
} }
} }
message GetNetworkRequest {
}
message GetNetworkReply {
string network = 1; // The BTC network name (mainnet, testnet3, or regtest).
}
message GetBalancesRequest { message GetBalancesRequest {
string currency_code = 1; // The Bisq wallet currency (BSQ or BTC) for the balances request. string currency_code = 1; // The Bisq wallet currency (BSQ or BTC) for the balances request.
} }
@ -885,7 +895,6 @@ message BalancesInfo {
BtcBalanceInfo btc = 2; // BTC wallet balance information. BtcBalanceInfo btc = 2; // BTC wallet balance information.
} }
// TODO Thoroughly review field descriptions.
message BsqBalanceInfo { message BsqBalanceInfo {
// The BSQ amount currently available to send to other addresses at the user's discretion, in satoshis. // The BSQ amount currently available to send to other addresses at the user's discretion, in satoshis.
uint64 available_confirmed_balance = 1; uint64 available_confirmed_balance = 1;
@ -904,7 +913,6 @@ message BsqBalanceInfo {
uint64 unlocking_bonds_balance = 6; uint64 unlocking_bonds_balance = 6;
} }
// TODO Thoroughly review field descriptions.
message BtcBalanceInfo { message BtcBalanceInfo {
// The BTC amount currently available to send to other addresses at the user's discretion, in satoshis. // The BTC amount currently available to send to other addresses at the user's discretion, in satoshis.
uint64 available_balance = 1; uint64 available_balance = 1;