Read wallet password in bot instance, not main()

- Remove some duplicated code in the bots' main() methods.
- Validate wallet password first.
- Fix a bot config text alignment problem.
This commit is contained in:
ghubstan 2022-06-26 11:52:46 -03:00
parent ee90359ebb
commit 03102125b5
No known key found for this signature in database
GPG Key ID: E35592D6800A861E
9 changed files with 41 additions and 41 deletions

View File

@ -84,8 +84,8 @@ public abstract class AbstractBot {
// Constructor // Constructor
public AbstractBot(String[] args) { public AbstractBot(String[] args) {
this.args = args; this.args = toArgsWithWalletPassword.apply(args);
Config bisqClientOpts = new Config(args, defaultPropertiesFilename.get()); Config bisqClientOpts = new Config(this.args, defaultPropertiesFilename.get());
this.walletPassword = bisqClientOpts.getWalletPassword(); this.walletPassword = bisqClientOpts.getWalletPassword();
this.conf = bisqClientOpts.getConf(); this.conf = bisqClientOpts.getConf();
this.grpcStubs = new GrpcStubs(bisqClientOpts.getHost(), bisqClientOpts.getPort(), bisqClientOpts.getPassword()); this.grpcStubs = new GrpcStubs(bisqClientOpts.getHost(), bisqClientOpts.getPort(), bisqClientOpts.getPassword());

View File

@ -256,6 +256,19 @@ public class BotUtils {
} }
} }
/**
* Reads a wallet password from the console, and appends it to the given program args
* array as an additional config option, e.g., --wallet-password="be careful".
* The returned String[] is the original args array, plus the wallet-password option.
*/
public static final Function<String[], String[]> toArgsWithWalletPassword = (args) -> {
var walletPasswordPrompt = "An encrypted wallet must be unlocked"
+ " for requests that read or update your wallet.\n"
+ "Please enter your wallet password:";
var unvalidatedWalletPassword = readWalletPassword(walletPasswordPrompt);
return appendWalletPasswordOpt(args, unvalidatedWalletPassword);
};
/** /**
* Return a wallet password read from stdin. If read from a command terminal, input will not be echoed. * Return a wallet password read from stdin. If read from a command terminal, input will not be echoed.
* If run in a virtual terminal (IDE console), the input will be echoed. * If run in a virtual terminal (IDE console), the input will be echoed.
@ -284,7 +297,7 @@ public class BotUtils {
} }
/** /**
* Return the given String[] args with an additional --wallet-password=xyz option appended to it. * Return the given String[] args with an additional --wallet-password="be careful" option appended to it.
* *
* @param args program arguments * @param args program arguments
* @param walletPassword wallet password * @param walletPassword wallet password

View File

@ -93,6 +93,7 @@ public class TakeBestPricedOfferToBuyBsq extends AbstractBot {
@Override @Override
public void run() { public void run() {
var startTime = new Date().getTime(); var startTime = new Date().getTime();
validateWalletPassword(walletPassword);
validatePollingInterval(pollingInterval); validatePollingInterval(pollingInterval);
printBotConfiguration(); printBotConfiguration();
@ -169,9 +170,9 @@ public class TakeBestPricedOfferToBuyBsq extends AbstractBot {
private void printBotConfiguration() { private void printBotConfiguration() {
var configsByLabel = new LinkedHashMap<String, Object>(); var configsByLabel = new LinkedHashMap<String, Object>();
configsByLabel.put("Bot OS:", "\t" + getOSName() + " " + getOSVersion()); configsByLabel.put("Bot OS:", getOSName() + " " + getOSVersion());
var network = getNetwork(); var network = getNetwork();
configsByLabel.put("BTC Network:", "\t" + network); configsByLabel.put("BTC Network:", network);
var isMainnet = network.equalsIgnoreCase("mainnet"); var isMainnet = network.equalsIgnoreCase("mainnet");
var mainnet30DayAvgBsqPrice = isMainnet ? get30DayAvgBsqPriceInBtc() : null; var mainnet30DayAvgBsqPrice = isMainnet ? get30DayAvgBsqPriceInBtc() : null;
configsByLabel.put("My Payment Account:", ""); configsByLabel.put("My Payment Account:", "");
@ -194,7 +195,7 @@ public class TakeBestPricedOfferToBuyBsq extends AbstractBot {
} else { } else {
configsByLabel.put("\tPreferred Trading Peers:", "N/A"); configsByLabel.put("\tPreferred Trading Peers:", "N/A");
} }
configsByLabel.put("Bot Polling Interval:", "\t" + pollingInterval + " ms"); configsByLabel.put("Bot Polling Interval:", pollingInterval + " ms");
log.info(toTable.apply("Bot Configuration", configsByLabel)); log.info(toTable.apply("Bot Configuration", configsByLabel));
} }
@ -260,11 +261,7 @@ public class TakeBestPricedOfferToBuyBsq extends AbstractBot {
BotUtils.isWithinBTCAmountBounds(offer, getMinAmount(), getMaxAmount()); BotUtils.isWithinBTCAmountBounds(offer, getMinAmount(), getMaxAmount());
public static void main(String[] args) { public static void main(String[] args) {
@SuppressWarnings("unused") TakeBestPricedOfferToBuyBsq bot = new TakeBestPricedOfferToBuyBsq(args);
String prompt = "An encrypted wallet must be unlocked before any offer can be taken.\n"
+ "Please enter your wallet password:";
String walletPassword = readWalletPassword(prompt);
TakeBestPricedOfferToBuyBsq bot = new TakeBestPricedOfferToBuyBsq(appendWalletPasswordOpt(args, walletPassword));
bot.run(); bot.run();
} }

View File

@ -132,8 +132,8 @@ public class TakeBestPricedOfferToBuyBtc extends AbstractBot {
@Override @Override
public void run() { public void run() {
var startTime = new Date().getTime(); var startTime = new Date().getTime();
validatePollingInterval(pollingInterval);
validateWalletPassword(walletPassword); validateWalletPassword(walletPassword);
validatePollingInterval(pollingInterval);
validateTradeFeeCurrencyCode(bisqTradeFeeCurrency); validateTradeFeeCurrencyCode(bisqTradeFeeCurrency);
validatePaymentAccount(paymentAccount); validatePaymentAccount(paymentAccount);
printBotConfiguration(); printBotConfiguration();
@ -306,9 +306,9 @@ public class TakeBestPricedOfferToBuyBtc extends AbstractBot {
private void printBotConfiguration() { private void printBotConfiguration() {
var configsByLabel = new LinkedHashMap<String, Object>(); var configsByLabel = new LinkedHashMap<String, Object>();
configsByLabel.put("Bot OS:", "\t" + getOSName() + " " + getOSVersion()); configsByLabel.put("Bot OS:", getOSName() + " " + getOSVersion());
var network = getNetwork(); var network = getNetwork();
configsByLabel.put("BTC Network:", "\t" + network); configsByLabel.put("BTC Network:", network);
configsByLabel.put("My Payment Account:", ""); configsByLabel.put("My Payment Account:", "");
configsByLabel.put("\tPayment Account Id:", paymentAccount.getId()); configsByLabel.put("\tPayment Account Id:", paymentAccount.getId());
configsByLabel.put("\tAccount Name:", paymentAccount.getAccountName()); configsByLabel.put("\tAccount Name:", paymentAccount.getAccountName());
@ -324,16 +324,12 @@ public class TakeBestPricedOfferToBuyBtc extends AbstractBot {
} else { } else {
configsByLabel.put("\tPreferred Trading Peers:", "N/A"); configsByLabel.put("\tPreferred Trading Peers:", "N/A");
} }
configsByLabel.put("Bot Polling Interval:", "\t" + pollingInterval + " ms"); configsByLabel.put("Bot Polling Interval:", pollingInterval + " ms");
log.info(toTable.apply("Bot Configuration", configsByLabel)); log.info(toTable.apply("Bot Configuration", configsByLabel));
} }
public static void main(String[] args) { public static void main(String[] args) {
@SuppressWarnings("unused") TakeBestPricedOfferToBuyBtc bot = new TakeBestPricedOfferToBuyBtc(args);
String prompt = "An encrypted wallet must be unlocked before any offer can be taken.\n"
+ "Please enter your wallet password:";
String walletPassword = readWalletPassword(prompt);
TakeBestPricedOfferToBuyBtc bot = new TakeBestPricedOfferToBuyBtc(appendWalletPasswordOpt(args, walletPassword));
bot.run(); bot.run();
} }

View File

@ -93,6 +93,7 @@ public class TakeBestPricedOfferToSellBsq extends AbstractBot {
@Override @Override
public void run() { public void run() {
var startTime = new Date().getTime(); var startTime = new Date().getTime();
validateWalletPassword(walletPassword);
validatePollingInterval(pollingInterval); validatePollingInterval(pollingInterval);
printBotConfiguration(); printBotConfiguration();
@ -169,9 +170,9 @@ public class TakeBestPricedOfferToSellBsq extends AbstractBot {
private void printBotConfiguration() { private void printBotConfiguration() {
var configsByLabel = new LinkedHashMap<String, Object>(); var configsByLabel = new LinkedHashMap<String, Object>();
configsByLabel.put("Bot OS:", "\t" + getOSName() + " " + getOSVersion()); configsByLabel.put("Bot OS:", getOSName() + " " + getOSVersion());
var network = getNetwork(); var network = getNetwork();
configsByLabel.put("BTC Network:", "\t" + network); configsByLabel.put("BTC Network:", network);
var isMainnet = network.equalsIgnoreCase("mainnet"); var isMainnet = network.equalsIgnoreCase("mainnet");
var mainnet30DayAvgBsqPrice = isMainnet ? get30DayAvgBsqPriceInBtc() : null; var mainnet30DayAvgBsqPrice = isMainnet ? get30DayAvgBsqPriceInBtc() : null;
configsByLabel.put("My Payment Account:", ""); configsByLabel.put("My Payment Account:", "");
@ -194,7 +195,7 @@ public class TakeBestPricedOfferToSellBsq extends AbstractBot {
} else { } else {
configsByLabel.put("\tPreferred Trading Peers:", "N/A"); configsByLabel.put("\tPreferred Trading Peers:", "N/A");
} }
configsByLabel.put("Bot Polling Interval:", "\t" + pollingInterval + " ms"); configsByLabel.put("Bot Polling Interval:", pollingInterval + " ms");
log.info(toTable.apply("Bot Configuration", configsByLabel)); log.info(toTable.apply("Bot Configuration", configsByLabel));
} }
@ -260,11 +261,7 @@ public class TakeBestPricedOfferToSellBsq extends AbstractBot {
BotUtils.isWithinBTCAmountBounds(offer, getMinAmount(), getMaxAmount()); BotUtils.isWithinBTCAmountBounds(offer, getMinAmount(), getMaxAmount());
public static void main(String[] args) { public static void main(String[] args) {
@SuppressWarnings("unused") TakeBestPricedOfferToSellBsq bot = new TakeBestPricedOfferToSellBsq(args);
String prompt = "An encrypted wallet must be unlocked before any offer can be taken.\n"
+ "Please enter your wallet password:";
String walletPassword = readWalletPassword(prompt);
TakeBestPricedOfferToSellBsq bot = new TakeBestPricedOfferToSellBsq(appendWalletPasswordOpt(args, walletPassword));
bot.run(); bot.run();
} }

View File

@ -133,6 +133,7 @@ public class TakeBestPricedOfferToSellBtc extends AbstractBot {
@Override @Override
public void run() { public void run() {
var startTime = new Date().getTime(); var startTime = new Date().getTime();
validateWalletPassword(walletPassword);
validatePollingInterval(pollingInterval); validatePollingInterval(pollingInterval);
validateTradeFeeCurrencyCode(bisqTradeFeeCurrency); validateTradeFeeCurrencyCode(bisqTradeFeeCurrency);
validatePaymentAccount(paymentAccount); validatePaymentAccount(paymentAccount);
@ -306,9 +307,9 @@ public class TakeBestPricedOfferToSellBtc extends AbstractBot {
private void printBotConfiguration() { private void printBotConfiguration() {
var configsByLabel = new LinkedHashMap<String, Object>(); var configsByLabel = new LinkedHashMap<String, Object>();
configsByLabel.put("Bot OS:", "\t" + getOSName() + " " + getOSVersion()); configsByLabel.put("Bot OS:", getOSName() + " " + getOSVersion());
var network = getNetwork(); var network = getNetwork();
configsByLabel.put("BTC Network:", "\t" + network); configsByLabel.put("BTC Network:", network);
configsByLabel.put("My Payment Account:", ""); configsByLabel.put("My Payment Account:", "");
configsByLabel.put("\tPayment Account Id:", paymentAccount.getId()); configsByLabel.put("\tPayment Account Id:", paymentAccount.getId());
configsByLabel.put("\tAccount Name:", paymentAccount.getAccountName()); configsByLabel.put("\tAccount Name:", paymentAccount.getAccountName());
@ -324,16 +325,12 @@ public class TakeBestPricedOfferToSellBtc extends AbstractBot {
} else { } else {
configsByLabel.put("\tPreferred Trading Peers:", "N/A"); configsByLabel.put("\tPreferred Trading Peers:", "N/A");
} }
configsByLabel.put("Bot Polling Interval:", "\t" + pollingInterval + " ms"); configsByLabel.put("Bot Polling Interval:", pollingInterval + " ms");
log.info(toTable.apply("Bot Configuration", configsByLabel)); log.info(toTable.apply("Bot Configuration", configsByLabel));
} }
public static void main(String[] args) { public static void main(String[] args) {
@SuppressWarnings("unused") TakeBestPricedOfferToSellBtc bot = new TakeBestPricedOfferToSellBtc(args);
String prompt = "An encrypted wallet must be unlocked before any offer can be taken.\n"
+ "Please enter your wallet password:";
String walletPassword = readWalletPassword(prompt);
TakeBestPricedOfferToSellBtc bot = new TakeBestPricedOfferToSellBtc(appendWalletPasswordOpt(args, walletPassword));
bot.run(); bot.run();
} }

View File

@ -3,7 +3,7 @@
maxTakeOffers=1 maxTakeOffers=1
# #
# Taker bot's payment account id. Only BUY BTC offers using the same payment method will be considered for taking. # Taker bot's payment account id. Only BUY BTC offers using the same payment method will be considered for taking.
paymentAccountId=28030c83-f07d-4f0b-b824-019529279630 paymentAccountId=6e58f3d9-e7a3-4799-aa38-e28e624d79a3
# #
# Taker bot's min market price margin. A candidate BUY BTC offer's price margin must be >= minMarketPriceMargin. # Taker bot's min market price margin. A candidate BUY BTC offer's price margin must be >= minMarketPriceMargin.
# #

View File

@ -1,18 +1,18 @@
# Maximum # of offers to take during one bot session. When reached, bot will shut down (but not the API daemon). # Maximum # of offers to take during one bot session. When reached, bot will shut down (but not the API daemon).
maxTakeOffers=10 maxTakeOffers=100
# #
# Maximum distance from 30-day average BSQ trade price. # Maximum distance from 30-day average BSQ trade price.
# Note: all BSQ Swap offers have a fixed-price, but the bot uses a margin (%) of the 30-day price for comparison. # Note: all BSQ Swap offers have a fixed-price, but the bot uses a margin (%) of the 30-day price for comparison.
maxMarketPriceMargin=0.00 maxMarketPriceMargin=0.00
# #
# Hard coded 30-day average BSQ trade price, used for development over regtest. # Hard coded 30-day average BSQ trade price, used for development over regtest.
regtest30DayAvgBsqPrice=0.00005 regtest30DayAvgBsqPrice=0.00037
# #
# Taker bot's min BTC amount to buy. The candidate BUY BTC offer's amount must be >= minAmount BTC. # Taker bot's min BTC amount to buy. The candidate BUY BTC offer's amount must be >= minAmount BTC.
minAmount=0.01 minAmount=0.01
# #
# Taker bot's max BTC amount to buy. The candidate BUY BTC offer's amount must be <= maxAmount BTC. # Taker bot's max BTC amount to buy. The candidate BUY BTC offer's amount must be <= maxAmount BTC.
maxAmount=0.50 maxAmount=0.90
# #
# Taker bot's max acceptable transaction fee rate (sats / byte). # Taker bot's max acceptable transaction fee rate (sats / byte).
# Regtest fee rates are from https://price.bisq.wiz.biz/getFees # Regtest fee rates are from https://price.bisq.wiz.biz/getFees

View File

@ -3,7 +3,7 @@
maxTakeOffers=4 maxTakeOffers=4
# #
# Taker bot's payment account id. Only SELL BTC offers using the same payment method will be considered for taking. # Taker bot's payment account id. Only SELL BTC offers using the same payment method will be considered for taking.
paymentAccountId=9ad3cc7a-7d32-453c-b9db-a3714b5b8f61 paymentAccountId=6e58f3d9-e7a3-4799-aa38-e28e624d79a3
# #
# Taker bot's max market price margin. A candidate SELL BTC offer's price margin must be <= maxMarketPriceMargin. # Taker bot's max market price margin. A candidate SELL BTC offer's price margin must be <= maxMarketPriceMargin.
maxMarketPriceMargin=3.00 maxMarketPriceMargin=3.00