mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 18:03:12 +01:00
Merge pull request #5093 from ghubstan/02-trading-scripts
Add api trade simulation scripts
This commit is contained in:
commit
570d6a8b38
28
apitest/scripts/editf2faccountform.py
Normal file
28
apitest/scripts/editf2faccountform.py
Normal file
@ -0,0 +1,28 @@
|
||||
import sys, os, json
|
||||
|
||||
# Writes a Bisq json F2F payment account form for the given country_code to the current working directory.
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("usage: editf2faccountform.py country_code")
|
||||
exit(1)
|
||||
|
||||
country_code = str(sys.argv[1]).upper()
|
||||
acct_form = {
|
||||
"_COMMENTS_": [
|
||||
"Do not manually edit the paymentMethodId field.",
|
||||
"Edit the salt field only if you are recreating a payment account on a new installation and wish to preserve the account age."
|
||||
],
|
||||
"paymentMethodId": "F2F",
|
||||
"accountName": "Face to Face Payment Account",
|
||||
"city": "Anytown",
|
||||
"contact": "Me",
|
||||
"country": country_code,
|
||||
"extraInfo": "",
|
||||
"salt": ""
|
||||
}
|
||||
target=os.path.dirname(os.path.realpath(__file__)) + '/' + 'f2f-acct.json'
|
||||
with open (target, 'w') as outfile:
|
||||
json.dump(acct_form, outfile, indent=2)
|
||||
outfile.write('\n')
|
||||
|
||||
exit(0)
|
159
apitest/scripts/limit-order-simulation.sh
Executable file
159
apitest/scripts/limit-order-simulation.sh
Executable file
@ -0,0 +1,159 @@
|
||||
#! /bin/bash
|
||||
|
||||
# Demonstrates a way to create a limit order (offer) using the API CLI with a local regtest bitcoin node.
|
||||
#
|
||||
# A country code argument is used to create a country based face to face payment account for the simulated offer.
|
||||
#
|
||||
# Prerequisites:
|
||||
#
|
||||
# - Linux or OSX with bash, Java 10, or Java 11-12 (JDK language compatibility 10), and bitcoin-core (v0.19, v0.20).
|
||||
#
|
||||
# - Bisq must be fully built with apitest dao setup files installed.
|
||||
# Build command: `./gradlew clean build :apitest:installDaoSetup`
|
||||
#
|
||||
# - All supporting nodes must be run locally, in dev/dao/regtest mode:
|
||||
# bitcoind, seednode, arbdaemon, alicedaemon, bobdaemon
|
||||
#
|
||||
# These should be run using the apitest harness. From the root project dir, run:
|
||||
# `$ ./bisq-apitest --apiPassword=xyz --supportingApps=bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon --shutdownAfterTests=false`
|
||||
#
|
||||
# - Only regtest btc can be bought or sold with the test payment account.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# This script must be run from the root of the project, e.g.:
|
||||
#
|
||||
# `$ apitest/scripts/limit-order-simulation.sh -l 40000 -d buy -c fr -m 3.00 -a 0.125`
|
||||
#
|
||||
# Script options: -l <limit-price> -d <direction> -c <country-code> (-m <mkt-price-margin(%)> || -f <fixed-price>) -a <amount(btc)> [-w <price-poll-interval(s)>]
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# Create a sell/eur offer to sell 0.125 btc at a fixed-price of 38,000 euros, using a France face to face
|
||||
# payment account, when the BTC market price rises to or above 40,000 EUR:
|
||||
#
|
||||
# `$ apitest/scripts/limit-order-simulation.sh -l 40000 -d sell -c fr -m 0.00 -a 0.125`
|
||||
|
||||
APP_HOME=$(pwd -P)
|
||||
APITEST_SCRIPTS_HOME="${APP_HOME}/apitest/scripts"
|
||||
|
||||
source "${APITEST_SCRIPTS_HOME}/trade-simulation-env.sh"
|
||||
source "${APITEST_SCRIPTS_HOME}/trade-simulation-utils.sh"
|
||||
|
||||
checksetup
|
||||
parselimitorderopts "$@"
|
||||
|
||||
printdate "Started ${APP_BASE_NAME} with parameters:"
|
||||
printscriptparams
|
||||
printbreak
|
||||
|
||||
editpaymentaccountform "$COUNTRY_CODE"
|
||||
exitoncommandalert $?
|
||||
cat "${APITEST_SCRIPTS_HOME}/${F2F_ACCT_FORM}"
|
||||
printbreak
|
||||
|
||||
# Create F2F payment accounts for $COUNTRY_CODE, and get the $CURRENCY_CODE.
|
||||
printdate "Creating Alice's face to face ${COUNTRY_CODE} payment account."
|
||||
CMD="${CLI_BASE} --port=${ALICE_PORT} createpaymentacct --payment-account-form=${APITEST_SCRIPTS_HOME}/${F2F_ACCT_FORM}"
|
||||
printdate "ALICE CLI: ${CMD}"
|
||||
CMD_OUTPUT=$(createpaymentacct "${CMD}")
|
||||
exitoncommandalert $?
|
||||
echo "${CMD_OUTPUT}"
|
||||
ALICE_ACCT_ID=$(getnewpaymentacctid "${CMD_OUTPUT}")
|
||||
exitoncommandalert $?
|
||||
CURRENCY_CODE=$(getnewpaymentacctcurrency "${CMD_OUTPUT}")
|
||||
exitoncommandalert $?
|
||||
printdate "ALICE F2F payment-account-id = ${ALICE_ACCT_ID}, currency-code = ${CURRENCY_CODE}."
|
||||
printbreak
|
||||
|
||||
printdate "Creating Bob's face to face ${COUNTRY_CODE} payment account."
|
||||
CMD="${CLI_BASE} --port=${BOB_PORT} createpaymentacct --payment-account-form=${APITEST_SCRIPTS_HOME}/${F2F_ACCT_FORM}"
|
||||
printdate "BOB CLI: ${CMD}"
|
||||
CMD_OUTPUT=$(createpaymentacct "${CMD}")
|
||||
exitoncommandalert $?
|
||||
echo "${CMD_OUTPUT}"
|
||||
BOB_ACCT_ID=$(getnewpaymentacctid "${CMD_OUTPUT}")
|
||||
exitoncommandalert $?
|
||||
CURRENCY_CODE=$(getnewpaymentacctcurrency "${CMD_OUTPUT}")
|
||||
exitoncommandalert $?
|
||||
printdate "BOB F2F payment-account-id = ${BOB_ACCT_ID}, currency-code = ${CURRENCY_CODE}."
|
||||
printbreak
|
||||
|
||||
# Bob & Alice now have matching payment accounts, now loop until the price limit is reached, then create an offer.
|
||||
if [ "$DIRECTION" = "BUY" ]
|
||||
then
|
||||
printdate "Create a BUY / ${CURRENCY_CODE} offer when the market price falls to or below ${LIMIT_PRICE} ${CURRENCY_CODE}."
|
||||
else
|
||||
printdate "Create a SELL / ${CURRENCY_CODE} offer when the market price rises to or above ${LIMIT_PRICE} ${CURRENCY_CODE}."
|
||||
fi
|
||||
|
||||
DONE=0
|
||||
while : ; do
|
||||
if [ "$DONE" -ne 0 ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
CURRENT_PRICE=$(getcurrentprice "$ALICE_PORT" "$CURRENCY_CODE")
|
||||
exitoncommandalert $?
|
||||
printdate "Current Market Price: $CURRENT_PRICE"
|
||||
|
||||
if [ "$DIRECTION" = "BUY" ] && [ "$CURRENT_PRICE" -le "$LIMIT_PRICE" ]; then
|
||||
printdate "Limit price reached."
|
||||
DONE=1
|
||||
break
|
||||
fi
|
||||
|
||||
if [ "$DIRECTION" = "SELL" ] && [ "$CURRENT_PRICE" -ge "$LIMIT_PRICE" ]; then
|
||||
printdate "Limit price reached."
|
||||
DONE=1
|
||||
break
|
||||
fi
|
||||
|
||||
sleep "$WAIT"
|
||||
done
|
||||
|
||||
printdate "ALICE: Creating ${DIRECTION} ${CURRENCY_CODE} offer with payment acct ${ALICE_ACCT_ID}."
|
||||
CMD="$CLI_BASE --port=${ALICE_PORT} createoffer"
|
||||
CMD+=" --payment-account=${ALICE_ACCT_ID}"
|
||||
CMD+=" --direction=${DIRECTION}"
|
||||
CMD+=" --currency-code=${CURRENCY_CODE}"
|
||||
CMD+=" --amount=${AMOUNT}"
|
||||
if [ -z "${MKT_PRICE_MARGIN}" ]; then
|
||||
CMD+=" --fixed-price=${FIXED_PRICE}"
|
||||
else
|
||||
CMD+=" --market-price-margin=${MKT_PRICE_MARGIN}"
|
||||
fi
|
||||
CMD+=" --security-deposit=50.0"
|
||||
CMD+=" --fee-currency=BSQ"
|
||||
printdate "ALICE CLI: ${CMD}"
|
||||
OFFER_ID=$(createoffer "${CMD}")
|
||||
exitoncommandalert $?
|
||||
printdate "ALICE: Created offer with id: ${OFFER_ID}."
|
||||
printbreak
|
||||
sleeptraced 3
|
||||
|
||||
# Show Alice's new offer.
|
||||
printdate "ALICE: Looking at her new ${DIRECTION} ${CURRENCY_CODE} offer."
|
||||
CMD="$CLI_BASE --port=${ALICE_PORT} getmyoffer --offer-id=${OFFER_ID}"
|
||||
printdate "ALICE CLI: ${CMD}"
|
||||
OFFER=$($CMD)
|
||||
exitoncommandalert $?
|
||||
echo "${OFFER}"
|
||||
printbreak
|
||||
sleeptraced 7
|
||||
|
||||
# Generate some btc blocks.
|
||||
printdate "Generating btc blocks after publishing Alice's offer."
|
||||
genbtcblocks 3 3
|
||||
printbreak
|
||||
sleeptraced 5
|
||||
|
||||
# Show Alice's offer in Bob's CLI.
|
||||
printdate "BOB: Looking at ${DIRECTION} ${CURRENCY_CODE} offers."
|
||||
CMD="$CLI_BASE --port=${BOB_PORT} getoffers --direction=${DIRECTION} --currency-code=${CURRENCY_CODE}"
|
||||
printdate "BOB CLI: ${CMD}"
|
||||
OFFERS=$($CMD)
|
||||
exitoncommandalert $?
|
||||
echo "${OFFERS}"
|
||||
|
||||
exit 0
|
219
apitest/scripts/trade-simulation-env.sh
Executable file
219
apitest/scripts/trade-simulation-env.sh
Executable file
@ -0,0 +1,219 @@
|
||||
#! /bin/bash
|
||||
|
||||
# This file must be sourced by the main driver.
|
||||
|
||||
export CLI_BASE="./bisq-cli --password=xyz"
|
||||
export ARBITRATOR_PORT=9997
|
||||
export ALICE_PORT=9998
|
||||
export BOB_PORT=9999
|
||||
export F2F_ACCT_FORM="f2f-acct.json"
|
||||
|
||||
checksetup() {
|
||||
apitestusage() {
|
||||
echo "The apitest harness must be running a local bitcoin regtest node, a seednode, arbitration node, and Bob & Alice daemons."
|
||||
echo ""
|
||||
echo "From the project's root dir, start all supporting nodes from a terminal:"
|
||||
echo "./bisq-apitest --apiPassword=xyz --supportingApps=bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon --shutdownAfterTests=false"
|
||||
echo ""
|
||||
echo "Register dispute agents in the arbitration daemon after it initializes."
|
||||
echo "./bisq-cli --password=xyz --port=9997 registerdisputeagent --dispute-agent-type=mediator \
|
||||
--registration-key=6ac43ea1df2a290c1c8391736aa42e4339c5cb4f110ff0257a13b63211977b7a"
|
||||
echo "./bisq-cli --password=xyz --port=9997 registerdisputeagent --dispute-agent-type=refundagent \
|
||||
--registration-key=6ac43ea1df2a290c1c8391736aa42e4339c5cb4f110ff0257a13b63211977b7a"
|
||||
exit 1;
|
||||
}
|
||||
printdate "Checking ${APP_HOME} for some expected directories and files."
|
||||
if [ -d "${APP_HOME}/apitest" ]; then
|
||||
printdate "Subproject apitest exists.";
|
||||
else
|
||||
printdate "Error: Subproject apitest not found, maybe because you are not running the script from the project root dir."
|
||||
exit 1
|
||||
fi
|
||||
if [ -f "${APP_HOME}/bisq-cli" ]; then
|
||||
printdate "The bisq-cli script exists.";
|
||||
else
|
||||
printdate "Error: The bisq-cli script not found, maybe because you are not running the script from the project root dir."
|
||||
exit 1
|
||||
fi
|
||||
printdate "Checking to see local bitcoind is running."
|
||||
checkbitcoindrunning
|
||||
printdate "Checking to see bisq servers are running."
|
||||
if pgrep -f "bisq.seednode.SeedNodeMain" > /dev/null ; then
|
||||
printdate "The seednode is running on host."
|
||||
else
|
||||
printdate "Error: seed is not running on host, exiting."
|
||||
apitestusage
|
||||
fi
|
||||
if pgrep -f "bisq.daemon.app.BisqDaemonMain --appName=bisq-BTC_REGTEST_Arb_dao" > /dev/null ; then
|
||||
printdate "The arbitration node is running on host."
|
||||
else
|
||||
printdate "Error: arbitration node is not running on host, exiting."
|
||||
apitestusage
|
||||
fi
|
||||
if pgrep -f "bisq.daemon.app.BisqDaemonMain --appName=bisq-BTC_REGTEST_Alice_dao" > /dev/null ; then
|
||||
printdate "Alice's daemon node is running on host."
|
||||
else
|
||||
printdate "Error: Alice's daemon node is not running on host, exiting."
|
||||
apitestusage
|
||||
fi
|
||||
if pgrep -f "bisq.daemon.app.BisqDaemonMain --appName=bisq-BTC_REGTEST_Bob_dao" > /dev/null ; then
|
||||
printdate "Bob's daemon node is running on host."
|
||||
else
|
||||
printdate "Error: Bob's daemon node is not running on host, exiting."
|
||||
apitestusage
|
||||
fi
|
||||
}
|
||||
|
||||
parseopts() {
|
||||
usage() {
|
||||
echo "Usage: $0 [-d buy|sell] [-c <country-code>] [-f <fixed-price> || -m <margin-from-price>] [-a <amount in btc>]" 1>&2
|
||||
exit 1;
|
||||
}
|
||||
|
||||
local OPTIND o d c f m a
|
||||
while getopts "d:c:f:m:a:" o; do
|
||||
case "${o}" in
|
||||
d) d=$(echo "${OPTARG}" | tr '[:lower:]' '[:upper:]')
|
||||
((d == "BUY" || d == "SELL")) || usage
|
||||
export DIRECTION=${d}
|
||||
;;
|
||||
c) c=$(echo "${OPTARG}"| tr '[:lower:]' '[:upper:]')
|
||||
export COUNTRY_CODE=${c}
|
||||
;;
|
||||
f) f=${OPTARG}
|
||||
export FIXED_PRICE=${f}
|
||||
;;
|
||||
m) m=${OPTARG}
|
||||
export MKT_PRICE_MARGIN=${m}
|
||||
;;
|
||||
a) a=${OPTARG}
|
||||
export AMOUNT=${a}
|
||||
;;
|
||||
*) usage ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [ -z "${d}" ] || [ -z "${c}" ] || [ -z "${a}" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -z "${f}" ] && [ -z "${m}" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -n "${f}" ] && [ -n "${m}" ]; then
|
||||
printdate "Must use margin-from-price param (-m) or fixed-price param (-f), not both."
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ "$DIRECTION" = "SELL" ]
|
||||
then
|
||||
export BOB_ROLE="(taker/buyer)"
|
||||
export ALICE_ROLE="(maker/seller)"
|
||||
else
|
||||
export BOB_ROLE="(taker/seller)"
|
||||
export ALICE_ROLE="(maker/buyer)"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
parselimitorderopts() {
|
||||
usage() {
|
||||
echo "Usage: $0 [-l limit-price] [-d buy|sell] [-c <country-code>] [-f <fixed-price> || -m <margin-from-price>] [-a <amount in btc>] [-w <price-poll-interval(s)>]" 1>&2
|
||||
exit 1;
|
||||
}
|
||||
|
||||
local OPTIND o l d c f m a w
|
||||
while getopts "l:d:c:f:m:a:w:" o; do
|
||||
case "${o}" in
|
||||
l) l=${OPTARG}
|
||||
export LIMIT_PRICE=${l}
|
||||
;;
|
||||
d) d=$(echo "${OPTARG}" | tr '[:lower:]' '[:upper:]')
|
||||
((d == "BUY" || d == "SELL")) || usage
|
||||
export DIRECTION=${d}
|
||||
;;
|
||||
c) c=$(echo "${OPTARG}"| tr '[:lower:]' '[:upper:]')
|
||||
export COUNTRY_CODE=${c}
|
||||
;;
|
||||
f) f=${OPTARG}
|
||||
export FIXED_PRICE=${f}
|
||||
;;
|
||||
m) m=${OPTARG}
|
||||
export MKT_PRICE_MARGIN=${m}
|
||||
;;
|
||||
a) a=${OPTARG}
|
||||
export AMOUNT=${a}
|
||||
;;
|
||||
w) w=${OPTARG}
|
||||
export WAIT=${w}
|
||||
;;
|
||||
*) usage ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [ -z "${l}" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -z "${d}" ] || [ -z "${c}" ] || [ -z "${a}" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -z "${f}" ] && [ -z "${m}" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -n "${f}" ] && [ -n "${m}" ]; then
|
||||
printdate "Must use margin-from-price param (-m) or fixed-price param (-f), not both."
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -z "${w}" ]; then
|
||||
WAIT=120
|
||||
elif [ "$w" -lt 20 ]; then
|
||||
printdate "The -w <price-poll-interval(s)> option is too low, minimum allowed is 20s. Using default 120s."
|
||||
WAIT=120
|
||||
fi
|
||||
}
|
||||
|
||||
checkbitcoindrunning() {
|
||||
# There may be a '+' char in the path and we have to escape it for pgrep.
|
||||
if [[ ${APP_HOME} == *"+"* ]]; then
|
||||
ESCAPED_APP_HOME=$(escapepluschar "${APP_HOME}")
|
||||
else
|
||||
ESCAPED_APP_HOME="${APP_HOME}"
|
||||
fi
|
||||
if pgrep -f "bitcoind -datadir=${ESCAPED_APP_HOME}/apitest/build/resources/main/Bitcoin-regtest" > /dev/null ; then
|
||||
printdate "The regtest bitcoind node is running on host."
|
||||
else
|
||||
printdate "Error: regtest bitcoind node is not running on host, exiting."
|
||||
apitestusage
|
||||
fi
|
||||
}
|
||||
|
||||
printscriptparams() {
|
||||
if [ -n "${LIMIT_PRICE+1}" ]; then
|
||||
echo " LIMIT_PRICE = ${LIMIT_PRICE}"
|
||||
fi
|
||||
|
||||
echo " DIRECTION = ${DIRECTION}"
|
||||
echo " COUNTRY_CODE = ${COUNTRY_CODE}"
|
||||
echo " FIXED_PRICE = ${FIXED_PRICE}"
|
||||
echo " MKT_PRICE_MARGIN = ${MKT_PRICE_MARGIN}"
|
||||
echo " AMOUNT = ${AMOUNT}"
|
||||
|
||||
if [ -n "${BOB_ROLE+1}" ]; then
|
||||
echo " BOB_ROLE = ${BOB_ROLE}"
|
||||
fi
|
||||
|
||||
if [ -n "${ALICE_ROLE+1}" ]; then
|
||||
echo " ALICE_ROLE = ${ALICE_ROLE}"
|
||||
fi
|
||||
|
||||
if [ -n "${WAIT+1}" ]; then
|
||||
echo " WAIT = ${WAIT}"
|
||||
fi
|
||||
}
|
179
apitest/scripts/trade-simulation-utils.sh
Executable file
179
apitest/scripts/trade-simulation-utils.sh
Executable file
@ -0,0 +1,179 @@
|
||||
#! /bin/bash
|
||||
|
||||
# This file must be sourced by the main driver.
|
||||
|
||||
source "${APITEST_SCRIPTS_HOME}/trade-simulation-env.sh"
|
||||
|
||||
printdate() {
|
||||
echo "[$(date)] $@"
|
||||
}
|
||||
|
||||
printbreak() {
|
||||
echo ""
|
||||
echo ""
|
||||
}
|
||||
|
||||
printcmd() {
|
||||
echo -en "$@\n"
|
||||
}
|
||||
|
||||
sleeptraced() {
|
||||
PERIOD="$1"
|
||||
printdate "sleeping for $PERIOD"
|
||||
sleep "$PERIOD"
|
||||
}
|
||||
|
||||
commandalert() {
|
||||
# Used in a script function when it needs to fail early with an error message, & pass the error code to the caller.
|
||||
# usage: commandalert <$?> <msg-prefix>
|
||||
if [ "$1" -ne 0 ]
|
||||
then
|
||||
printdate "Error: $2" >&2
|
||||
exit "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# TODO rename exitonalert ?
|
||||
exitoncommandalert() {
|
||||
# Used in a parent script when you need it to fail immediately, with no error message.
|
||||
# usage: exitoncommandalert <$?>
|
||||
if [ "$1" -ne 0 ]
|
||||
then
|
||||
exit "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
registerdisputeagents() {
|
||||
# Silently register dev dispute agents. It's easy to forget.
|
||||
REG_KEY="6ac43ea1df2a290c1c8391736aa42e4339c5cb4f110ff0257a13b63211977b7a"
|
||||
CMD="${CLI_BASE} --port=${ARBITRATOR_PORT} registerdisputeagent --dispute-agent-type=mediator --registration-key=${REG_KEY}"
|
||||
SILENT=$($CMD)
|
||||
commandalert $? "Could not register dev/test mediator."
|
||||
CMD="${CLI_BASE} --port=${ARBITRATOR_PORT} registerdisputeagent --dispute-agent-type=refundagent --registration-key=${REG_KEY}"
|
||||
SILENT=$($CMD)
|
||||
commandalert $? "Could not register dev/test refundagent."
|
||||
# Do something with $SILENT to keep codacy happy.
|
||||
echo "$SILENT" > /dev/null
|
||||
}
|
||||
|
||||
getbtcoreaddress() {
|
||||
CMD="bitcoin-cli -regtest -rpcport=19443 -rpcuser=apitest -rpcpassword=apitest getnewaddress"
|
||||
NEW_ADDRESS=$($CMD)
|
||||
echo "${NEW_ADDRESS}"
|
||||
}
|
||||
|
||||
genbtcblocks() {
|
||||
NUM_BLOCKS="$1"
|
||||
SECONDS_BETWEEN_BLOCKS="$2"
|
||||
ADDR_PARAM="$(getbtcoreaddress)"
|
||||
CMD_PREFIX="bitcoin-cli -regtest -rpcport=19443 -rpcuser=apitest -rpcpassword=apitest generatetoaddress 1"
|
||||
# Print the generatetoaddress command with double quoted address param, to make it cut & pastable from the console.
|
||||
printdate "$CMD_PREFIX \"$ADDR_PARAM\""
|
||||
# Now create the full generatetoaddress command to be run now.
|
||||
CMD="$CMD_PREFIX $ADDR_PARAM"
|
||||
for i in $(seq -f "%02g" 1 "$NUM_BLOCKS")
|
||||
do
|
||||
NEW_BLOCK_HASH=$(genbtcblock "$CMD")
|
||||
printdate "Block Hash #$i:${NEW_BLOCK_HASH}"
|
||||
sleep "$SECONDS_BETWEEN_BLOCKS"
|
||||
done
|
||||
}
|
||||
|
||||
genbtcblock() {
|
||||
CMD="$1"
|
||||
NEW_BLOCK_HASH=$($CMD | sed -n '2p')
|
||||
echo "$NEW_BLOCK_HASH"
|
||||
}
|
||||
|
||||
escapepluschar() {
|
||||
STRING="$1"
|
||||
NEW_STRING=$(echo "${STRING//+/\\+}")
|
||||
echo "${NEW_STRING}"
|
||||
}
|
||||
|
||||
printbalances() {
|
||||
PORT="$1"
|
||||
printcmd "${CLI_BASE} --port=${PORT} getbalance"
|
||||
$CLI_BASE --port="$PORT" getbalance
|
||||
}
|
||||
|
||||
getpaymentaccountmethods() {
|
||||
CMD="$1"
|
||||
CMD_OUTPUT=$($CMD)
|
||||
commandalert $? "Could not get payment method ids."
|
||||
printdate "Payment Method IDs:"
|
||||
echo "${CMD_OUTPUT}"
|
||||
}
|
||||
|
||||
getpaymentaccountform() {
|
||||
CMD="$1"
|
||||
CMD_OUTPUT=$($CMD)
|
||||
commandalert $? "Could not get new payment account form."
|
||||
echo "${CMD_OUTPUT}"
|
||||
}
|
||||
|
||||
editpaymentaccountform() {
|
||||
COUNTRY_CODE="$1"
|
||||
CMD="python3 ${APITEST_SCRIPTS_HOME}/editf2faccountform.py $COUNTRY_CODE"
|
||||
CMD_OUTPUT=$($CMD)
|
||||
commandalert $? "Could not edit payment account form."
|
||||
printdate "Saved payment account form as ${F2F_ACCT_FORM}."
|
||||
}
|
||||
|
||||
getnewpaymentacctid() {
|
||||
CREATE_PAYMENT_ACCT_OUTPUT="$1"
|
||||
PAYMENT_ACCT_DETAIL=$(echo -e "${CREATE_PAYMENT_ACCT_OUTPUT}" | sed -n '3p')
|
||||
ACCT_ID=$(echo -e "$PAYMENT_ACCT_DETAIL" | awk '{print $NF}')
|
||||
echo "${ACCT_ID}"
|
||||
}
|
||||
|
||||
getnewpaymentacctcurrency() {
|
||||
CREATE_PAYMENT_ACCT_OUTPUT="$1"
|
||||
PAYMENT_ACCT_DETAIL=$(echo -e "${CREATE_PAYMENT_ACCT_OUTPUT}" | sed -n '3p')
|
||||
# This is brittle; it requires the account name field to have N words,
|
||||
# e.g, "Face to Face Payment Account" as defined in editf2faccountform.py.
|
||||
CURRENCY_CODE=$(echo -e "$PAYMENT_ACCT_DETAIL" | awk '{print $6}')
|
||||
echo "${CURRENCY_CODE}"
|
||||
}
|
||||
|
||||
createpaymentacct() {
|
||||
CMD="$1"
|
||||
CMD_OUTPUT=$($CMD)
|
||||
commandalert $? "Could not create new payment account."
|
||||
echo "${CMD_OUTPUT}"
|
||||
}
|
||||
|
||||
getpaymentaccounts() {
|
||||
PORT="$1"
|
||||
printcmd "${CLI_BASE} --port=${PORT} getpaymentaccts"
|
||||
CMD="$CLI_BASE --port=$PORT getpaymentaccts"
|
||||
CMD_OUTPUT=$($CMD)
|
||||
commandalert $? "Could not get payment accounts."
|
||||
echo "${CMD_OUTPUT}"
|
||||
}
|
||||
|
||||
createoffer() {
|
||||
CREATE_OFFER_CMD="$1"
|
||||
OFFER_DESC=$($CREATE_OFFER_CMD)
|
||||
|
||||
# If the CLI command exited with an error, print the CLI error, and
|
||||
# return from this function now, passing the error status code to the caller.
|
||||
commandalert $? "Could not create offer."
|
||||
|
||||
OFFER_DETAIL=$(echo -e "${OFFER_DESC}" | sed -n '2p')
|
||||
NEW_OFFER_ID=$(echo -e "${OFFER_DETAIL}" | awk '{print $NF}')
|
||||
echo "${NEW_OFFER_ID}"
|
||||
}
|
||||
|
||||
getcurrentprice() {
|
||||
PORT="$1"
|
||||
CURRENCY_CODE="$2"
|
||||
CMD="$CLI_BASE --port=$PORT getbtcprice --currency-code=$CURRENCY_CODE"
|
||||
CMD_OUTPUT=$($CMD)
|
||||
commandalert $? "Could not get current market $CURRENCY_CODE price."
|
||||
FLOOR=$(echo "$CMD_OUTPUT" | cut -d'.' -f 1)
|
||||
commandalert $? "Could not get the floor of the current market $CURRENCY_CODE price."
|
||||
INTEGER=$(echo "$FLOOR" | tr -cd '[[:digit:]]')
|
||||
commandalert $? "Could not convert the current market $CURRENCY_CODE price string to an integer."
|
||||
echo "$INTEGER"
|
||||
}
|
240
apitest/scripts/trade-simulation.sh
Executable file
240
apitest/scripts/trade-simulation.sh
Executable file
@ -0,0 +1,240 @@
|
||||
#! /bin/bash
|
||||
|
||||
# Runs fiat <-> btc trading scenarios using the API CLI with a local regtest bitcoin node.
|
||||
#
|
||||
# A country code argument is used to create a country based face to face payment account for the simulated
|
||||
# trade, and the maker's face to face payment account's currency code is used when creating the offer.
|
||||
#
|
||||
# Prerequisites:
|
||||
#
|
||||
# - Linux or OSX with bash, Java 10, or Java 11-12 (JDK language compatibility 10), and bitcoin-core (v0.19, v0.20).
|
||||
#
|
||||
# - Bisq must be fully built with apitest dao setup files installed.
|
||||
# Build command: `./gradlew clean build :apitest:installDaoSetup`
|
||||
#
|
||||
# - All supporting nodes must be run locally, in dev/dao/regtest mode:
|
||||
# bitcoind, seednode, arbdaemon, alicedaemon, bobdaemon
|
||||
#
|
||||
# These should be run using the apitest harness. From the root project dir, run:
|
||||
# `$ ./bisq-apitest --apiPassword=xyz --supportingApps=bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon --shutdownAfterTests=false`
|
||||
#
|
||||
# - Only regtest btc can be bought or sold with the test payment account.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# This script must be run from the root of the project, e.g.:
|
||||
#
|
||||
# `$ apitest/scripts/trade-simulation.sh -d buy -c fr -m 3.00 -a 0.125`
|
||||
#
|
||||
# Script options: -d <direction> -c <country-code> -m <mkt-price-margin(%)> - f <fixed-price> -a <amount(btc)>
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# Create a buy/eur offer to buy 0.125 btc at a mkt-price-margin of 0%, using an Italy face to face payment account:
|
||||
#
|
||||
# `$ apitest/scripts/trade-simulation.sh -d buy -c it -m 0.00 -a 0.125`
|
||||
#
|
||||
# Create a sell/eur offer to sell 0.125 btc at a fixed-price of 38,000 euros, using a France face to face
|
||||
# payment account:
|
||||
#
|
||||
# `$ apitest/scripts/trade-simulation.sh -d sell -c fr -f 38000 -a 0.125`
|
||||
|
||||
export APP_BASE_NAME=$(basename "$0")
|
||||
export APP_HOME=$(pwd -P)
|
||||
export APITEST_SCRIPTS_HOME="${APP_HOME}/apitest/scripts"
|
||||
|
||||
source "${APITEST_SCRIPTS_HOME}/trade-simulation-env.sh"
|
||||
source "${APITEST_SCRIPTS_HOME}/trade-simulation-utils.sh"
|
||||
|
||||
checksetup
|
||||
parseopts "$@"
|
||||
|
||||
printdate "Started ${APP_BASE_NAME} with parameters:"
|
||||
printscriptparams
|
||||
printbreak
|
||||
|
||||
registerdisputeagents
|
||||
|
||||
printdate "Alice looks for the ID of the face to face payment account method (Bob will use same payment method)."
|
||||
CMD="${CLI_BASE} --port=${ALICE_PORT} getpaymentmethods"
|
||||
printdate "ALICE CLI: ${CMD}"
|
||||
getpaymentaccountmethods "$CMD"
|
||||
printbreak
|
||||
|
||||
printdate "Alice uses the F2F payment method id to create a face to face payment account in country ${COUNTRY_CODE}."
|
||||
CMD="${CLI_BASE} --port=${ALICE_PORT} getpaymentacctform --payment-method-id=F2F"
|
||||
printdate "ALICE CLI: ${CMD}"
|
||||
getpaymentaccountform "$CMD"
|
||||
printbreak
|
||||
|
||||
printdate "Bob & Alice edit their ${COUNTRY_CODE} payment account forms, and renames them to ${F2F_ACCT_FORM}"
|
||||
editpaymentaccountform "$COUNTRY_CODE"
|
||||
cat "${APITEST_SCRIPTS_HOME}/${F2F_ACCT_FORM}"
|
||||
|
||||
# Remove the autogenerated json template because we are going to use one created by a python script in the next step.
|
||||
CMD="rm -v ${APP_HOME}/f2f_*.json"
|
||||
DELETE_JSON_TEMPLATE=$($CMD)
|
||||
printdate "$DELETE_JSON_TEMPLATE"
|
||||
printbreak
|
||||
|
||||
printdate "Bob and Alice create their face to face ${COUNTRY_CODE} payment accounts."
|
||||
CMD="${CLI_BASE} --port=${BOB_PORT} createpaymentacct --payment-account-form=${APITEST_SCRIPTS_HOME}/${F2F_ACCT_FORM}"
|
||||
printdate "BOB CLI: ${CMD}"
|
||||
CMD_OUTPUT=$(createpaymentacct "${CMD}")
|
||||
echo "${CMD_OUTPUT}"
|
||||
BOB_ACCT_ID=$(getnewpaymentacctid "${CMD_OUTPUT}")
|
||||
BOB_ACCT_CURRENCY_CODE=$(getnewpaymentacctcurrency "${CMD_OUTPUT}")
|
||||
printdate "BOB F2F payment-account-id = ${BOB_ACCT_ID}, currency-code = ${BOB_ACCT_CURRENCY_CODE}."
|
||||
printbreak
|
||||
|
||||
CMD="${CLI_BASE} --port=${ALICE_PORT} createpaymentacct --payment-account-form=${APITEST_SCRIPTS_HOME}/${F2F_ACCT_FORM}"
|
||||
printdate "ALICE CLI: ${CMD}"
|
||||
CMD_OUTPUT=$(createpaymentacct "${CMD}")
|
||||
echo "${CMD_OUTPUT}"
|
||||
ALICE_ACCT_ID=$(getnewpaymentacctid "${CMD_OUTPUT}")
|
||||
ALICE_ACCT_CURRENCY_CODE=$(getnewpaymentacctcurrency "${CMD_OUTPUT}")
|
||||
printdate "ALICE F2F payment-account-id = ${ALICE_ACCT_ID}, currency-code = ${ALICE_ACCT_CURRENCY_CODE}."
|
||||
printbreak
|
||||
|
||||
printdate "ALICE ${ALICE_ROLE}: Creating ${DIRECTION} ${ALICE_ACCT_CURRENCY_CODE} offer with payment acct ${ALICE_ACCT_ID}."
|
||||
CURRENT_PRICE=$(getcurrentprice "$ALICE_PORT" "$ALICE_ACCT_CURRENCY_CODE")
|
||||
exitoncommandalert $?
|
||||
printdate "Current Market Price: $CURRENT_PRICE"
|
||||
CMD="$CLI_BASE --port=${ALICE_PORT} createoffer"
|
||||
CMD+=" --payment-account=${ALICE_ACCT_ID}"
|
||||
CMD+=" --direction=${DIRECTION}"
|
||||
CMD+=" --currency-code=${ALICE_ACCT_CURRENCY_CODE}"
|
||||
CMD+=" --amount=${AMOUNT}"
|
||||
if [ -z "${MKT_PRICE_MARGIN}" ]; then
|
||||
CMD+=" --fixed-price=${FIXED_PRICE}"
|
||||
else
|
||||
CMD+=" --market-price-margin=${MKT_PRICE_MARGIN}"
|
||||
fi
|
||||
CMD+=" --security-deposit=15.0"
|
||||
CMD+=" --fee-currency=BSQ"
|
||||
printdate "ALICE CLI: ${CMD}"
|
||||
OFFER_ID=$(createoffer "${CMD}")
|
||||
exitoncommandalert $?
|
||||
printdate "ALICE ${ALICE_ROLE}: Created offer with id: ${OFFER_ID}."
|
||||
printbreak
|
||||
sleeptraced 3
|
||||
|
||||
# Show Alice's new offer.
|
||||
printdate "ALICE ${ALICE_ROLE}: Looking at her new ${DIRECTION} ${CURRENCY_CODE} offer."
|
||||
CMD="$CLI_BASE --port=${ALICE_PORT} getmyoffer --offer-id=${OFFER_ID}"
|
||||
printdate "ALICE CLI: ${CMD}"
|
||||
OFFER=$($CMD)
|
||||
exitoncommandalert $?
|
||||
echo "${OFFER}"
|
||||
printbreak
|
||||
sleeptraced 7
|
||||
|
||||
# Generate some btc blocks.
|
||||
printdate "Generating btc blocks after publishing Alice's offer."
|
||||
genbtcblocks 3 5
|
||||
printbreak
|
||||
sleeptraced 10
|
||||
|
||||
# List offers.
|
||||
printdate "BOB ${BOB_ROLE}: Looking at ${DIRECTION} ${BOB_ACCT_CURRENCY_CODE} offers."
|
||||
CMD="$CLI_BASE --port=${BOB_PORT} getoffers --direction=${DIRECTION} --currency-code=${BOB_ACCT_CURRENCY_CODE}"
|
||||
printdate "BOB CLI: ${CMD}"
|
||||
OFFERS=$($CMD)
|
||||
exitoncommandalert $?
|
||||
echo "${OFFERS}"
|
||||
printbreak
|
||||
sleeptraced 3
|
||||
|
||||
# Take offer.
|
||||
printdate "BOB ${BOB_ROLE}: Taking offer ${OFFER_ID} with payment acct ${BOB_ACCT_ID}."
|
||||
CMD="$CLI_BASE --port=${BOB_PORT} takeoffer --offer-id=${OFFER_ID} --payment-account=${BOB_ACCT_ID} --fee-currency=bsq"
|
||||
printdate "BOB CLI: ${CMD}"
|
||||
TRADE=$($CMD)
|
||||
commandalert $? "Could not take offer."
|
||||
|
||||
echo "${TRADE}"
|
||||
printbreak
|
||||
sleeptraced 10
|
||||
|
||||
# Generating some btc blocks
|
||||
printdate "Generating btc blocks after Bob takes Alice's offer."
|
||||
genbtcblocks 3 3
|
||||
printbreak
|
||||
sleeptraced 6
|
||||
|
||||
# Send payment sent and received messages.
|
||||
if [ "${DIRECTION}" = "BUY" ]
|
||||
then
|
||||
PAYER="ALICE ${ALICE_ROLE}"
|
||||
PAYER_PORT=${ALICE_PORT}
|
||||
PAYER_CLI="ALICE CLI"
|
||||
PAYEE="BOB ${BOB_ROLE}"
|
||||
PAYEE_PORT=${BOB_PORT}
|
||||
PAYEE_CLI="BOB CLI"
|
||||
else
|
||||
PAYER="BOB ${BOB_ROLE}"
|
||||
PAYER_PORT=${BOB_PORT}
|
||||
PAYER_CLI="BOB CLI"
|
||||
PAYEE="ALICE ${ALICE_ROLE}"
|
||||
PAYEE_PORT=${ALICE_PORT}
|
||||
PAYEE_CLI="ALICE CLI"
|
||||
fi
|
||||
|
||||
# Confirm payment started.
|
||||
printdate "${PAYER}: Sending fiat payment sent msg."
|
||||
CMD="$CLI_BASE --port=${PAYER_PORT} confirmpaymentstarted --trade-id=${OFFER_ID}"
|
||||
printdate "${PAYER_CLI}: ${CMD}"
|
||||
SENT_MSG=$($CMD)
|
||||
commandalert $? "Could not send confirmpaymentstarted message."
|
||||
|
||||
printdate "${SENT_MSG}"
|
||||
printbreak
|
||||
|
||||
sleeptraced 2
|
||||
printdate "Generating btc blocks after fiat payment sent msg."
|
||||
genbtcblocks 3 5
|
||||
sleeptraced 2
|
||||
|
||||
# Confirm payment received.
|
||||
printdate "${PAYEE}: Sending fiat payment received msg."
|
||||
CMD="$CLI_BASE --port=${PAYEE_PORT} confirmpaymentreceived --trade-id=${OFFER_ID}"
|
||||
printdate "${PAYEE_CLI}: ${CMD}"
|
||||
RCVD_MSG=$($CMD)
|
||||
commandalert $? "Could not send confirmpaymentreceived message."
|
||||
printdate "${RCVD_MSG}"
|
||||
printbreak
|
||||
sleeptraced 4
|
||||
|
||||
# Generate some btc blocks
|
||||
printdate "Generating btc blocks after fiat transfer."
|
||||
genbtcblocks 3 5
|
||||
printbreak
|
||||
sleeptraced 3
|
||||
|
||||
# Complete the trade on the seller side.
|
||||
if [ "${DIRECTION}" = "BUY" ]
|
||||
then
|
||||
printdate "BOB ${BOB_ROLE}: Closing trade by keeping funds in Bisq wallet."
|
||||
CMD="$CLI_BASE --port=${BOB_PORT} keepfunds --trade-id=${OFFER_ID}"
|
||||
printdate "BOB CLI: ${CMD}"
|
||||
else
|
||||
printdate "ALICE (taker): Closing trade by keeping funds in Bisq wallet."
|
||||
CMD="$CLI_BASE --port=${ALICE_PORT} keepfunds --trade-id=${OFFER_ID}"
|
||||
printdate "ALICE CLI: ${CMD}"
|
||||
fi
|
||||
KEEP_FUNDS_MSG=$($CMD)
|
||||
commandalert $? "Could close trade with keepfunds command."
|
||||
printdate "${KEEP_FUNDS_MSG}"
|
||||
sleeptraced 5
|
||||
printbreak
|
||||
|
||||
# Get balances after trade completion.
|
||||
printdate "Bob & Alice's balances after trade:"
|
||||
printdate "ALICE CLI:"
|
||||
printbalances "$ALICE_PORT"
|
||||
printbreak
|
||||
printdate "BOB CLI:"
|
||||
printbalances "$BOB_PORT"
|
||||
printbreak
|
||||
|
||||
exit 0
|
@ -40,6 +40,7 @@ import bisq.proto.grpc.GetUnusedBsqAddressRequest;
|
||||
import bisq.proto.grpc.GetVersionRequest;
|
||||
import bisq.proto.grpc.KeepFundsRequest;
|
||||
import bisq.proto.grpc.LockWalletRequest;
|
||||
import bisq.proto.grpc.MarketPriceRequest;
|
||||
import bisq.proto.grpc.OfferInfo;
|
||||
import bisq.proto.grpc.RegisterDisputeAgentRequest;
|
||||
import bisq.proto.grpc.RemoveWalletPasswordRequest;
|
||||
@ -75,6 +76,7 @@ import java.util.List;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static bisq.cli.CurrencyFormat.formatMarketPrice;
|
||||
import static bisq.cli.CurrencyFormat.formatTxFeeRateInfo;
|
||||
import static bisq.cli.CurrencyFormat.toSatoshis;
|
||||
import static bisq.cli.CurrencyFormat.toSecurityDepositAsPct;
|
||||
@ -98,6 +100,7 @@ import bisq.cli.opts.CancelOfferOptionParser;
|
||||
import bisq.cli.opts.CreateOfferOptionParser;
|
||||
import bisq.cli.opts.CreatePaymentAcctOptionParser;
|
||||
import bisq.cli.opts.GetAddressBalanceOptionParser;
|
||||
import bisq.cli.opts.GetBTCMarketPriceOptionParser;
|
||||
import bisq.cli.opts.GetBalanceOptionParser;
|
||||
import bisq.cli.opts.GetOfferOptionParser;
|
||||
import bisq.cli.opts.GetOffersOptionParser;
|
||||
@ -189,6 +192,7 @@ public class CliMain {
|
||||
var helpService = grpcStubs.helpService;
|
||||
var offersService = grpcStubs.offersService;
|
||||
var paymentAccountsService = grpcStubs.paymentAccountsService;
|
||||
var priceService = grpcStubs.priceService;
|
||||
var tradesService = grpcStubs.tradesService;
|
||||
var versionService = grpcStubs.versionService;
|
||||
var walletsService = grpcStubs.walletsService;
|
||||
@ -243,6 +247,20 @@ public class CliMain {
|
||||
out.println(formatAddressBalanceTbl(singletonList(reply.getAddressBalanceInfo())));
|
||||
return;
|
||||
}
|
||||
case getbtcprice: {
|
||||
var opts = new GetBTCMarketPriceOptionParser(args).parse();
|
||||
if (opts.isForHelp()) {
|
||||
out.println(getMethodHelp(helpService, method));
|
||||
return;
|
||||
}
|
||||
var currencyCode = opts.getCurrencyCode();
|
||||
var request = MarketPriceRequest.newBuilder()
|
||||
.setCurrencyCode(currencyCode)
|
||||
.build();
|
||||
var reply = priceService.getMarketPrice(request);
|
||||
out.println(formatMarketPrice(reply.getPrice()));
|
||||
return;
|
||||
}
|
||||
case getfundingaddresses: {
|
||||
if (new SimpleMethodOptionParser(args).parse().isForHelp()) {
|
||||
out.println(getMethodHelp(helpService, method));
|
||||
@ -802,15 +820,18 @@ public class CliMain {
|
||||
stream.println();
|
||||
stream.format(rowFormat, getaddressbalance.name(), "--address=<btc-address>", "Get server wallet address balance");
|
||||
stream.println();
|
||||
stream.format(rowFormat, getbtcprice.name(), "--currency-code=<currency-code>", "Get current market btc price");
|
||||
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=<btc-address> --amount=<btc-amount> \\", "Send BSQ");
|
||||
stream.format(rowFormat, sendbsq.name(), "--address=<bsq-address> --amount=<bsq-amount> \\", "Send BSQ");
|
||||
stream.format(rowFormat, "", "[--tx-fee-rate=<sats/byte>]", "");
|
||||
stream.println();
|
||||
stream.format(rowFormat, sendbtc.name(), "--address=<bsq-address> --amount=<bsq-amount> \\", "Send BTC");
|
||||
stream.format(rowFormat, sendbtc.name(), "--address=<btc-address> --amount=<btc-amount> \\", "Send BTC");
|
||||
stream.format(rowFormat, "", "[--tx-fee-rate=<sats/byte>]", "");
|
||||
stream.format(rowFormat, "", "[--memo=<\"memo\">]", "");
|
||||
stream.println();
|
||||
stream.format(rowFormat, gettxfeerate.name(), "", "Get current tx fee rate in sats/byte");
|
||||
stream.println();
|
||||
|
@ -77,6 +77,11 @@ public class CurrencyFormat {
|
||||
: formatOfferVolume(volume);
|
||||
}
|
||||
|
||||
static String formatMarketPrice(double price) {
|
||||
NUMBER_FORMAT.setMinimumFractionDigits(4);
|
||||
return NUMBER_FORMAT.format(price);
|
||||
}
|
||||
|
||||
static String formatOfferPrice(long price) {
|
||||
NUMBER_FORMAT.setMaximumFractionDigits(4);
|
||||
NUMBER_FORMAT.setMinimumFractionDigits(4);
|
||||
|
@ -21,36 +21,37 @@ package bisq.cli;
|
||||
* Currently supported api methods.
|
||||
*/
|
||||
public enum Method {
|
||||
createoffer,
|
||||
canceloffer,
|
||||
getoffer,
|
||||
getmyoffer,
|
||||
getoffers,
|
||||
getmyoffers,
|
||||
takeoffer,
|
||||
gettrade,
|
||||
confirmpaymentstarted,
|
||||
confirmpaymentreceived,
|
||||
keepfunds,
|
||||
withdrawfunds,
|
||||
getpaymentmethods,
|
||||
getpaymentacctform,
|
||||
confirmpaymentstarted,
|
||||
createoffer,
|
||||
createpaymentacct,
|
||||
getpaymentaccts,
|
||||
getversion,
|
||||
getbalance,
|
||||
getaddressbalance,
|
||||
getbalance,
|
||||
getbtcprice,
|
||||
getfundingaddresses,
|
||||
getmyoffer,
|
||||
getmyoffers,
|
||||
getoffer,
|
||||
getoffers,
|
||||
getpaymentacctform,
|
||||
getpaymentaccts,
|
||||
getpaymentmethods,
|
||||
gettrade,
|
||||
gettransaction,
|
||||
gettxfeerate,
|
||||
getunusedbsqaddress,
|
||||
getversion,
|
||||
keepfunds,
|
||||
lockwallet,
|
||||
registerdisputeagent,
|
||||
removewalletpassword,
|
||||
sendbsq,
|
||||
sendbtc,
|
||||
gettxfeerate,
|
||||
settxfeerate,
|
||||
unsettxfeerate,
|
||||
gettransaction,
|
||||
lockwallet,
|
||||
unlockwallet,
|
||||
removewalletpassword,
|
||||
setwalletpassword,
|
||||
registerdisputeagent
|
||||
takeoffer,
|
||||
unlockwallet,
|
||||
unsettxfeerate,
|
||||
withdrawfunds
|
||||
}
|
||||
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.cli.opts;
|
||||
|
||||
|
||||
import joptsimple.OptionSpec;
|
||||
|
||||
import static bisq.cli.opts.OptLabel.OPT_CURRENCY_CODE;
|
||||
import static joptsimple.internal.Strings.EMPTY;
|
||||
|
||||
public class GetBTCMarketPriceOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
||||
|
||||
final OptionSpec<String> currencyCodeOpt = parser.accepts(OPT_CURRENCY_CODE, "currency-code")
|
||||
.withRequiredArg()
|
||||
.defaultsTo(EMPTY);
|
||||
|
||||
public GetBTCMarketPriceOptionParser(String[] args) {
|
||||
super(args);
|
||||
}
|
||||
|
||||
public GetBTCMarketPriceOptionParser parse() {
|
||||
super.parse();
|
||||
|
||||
// Short circuit opt validation if user just wants help.
|
||||
if (options.has(helpOpt))
|
||||
return this;
|
||||
|
||||
if (!options.has(currencyCodeOpt))
|
||||
throw new IllegalArgumentException("no currency code specified");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getCurrencyCode() {
|
||||
return options.valueOf(currencyCodeOpt);
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ import static joptsimple.internal.Strings.EMPTY;
|
||||
|
||||
public class WithdrawFundsOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
||||
|
||||
final OptionSpec<String> tradeIdOpt = parser.accepts(OPT_TRADE_ID, "id of trade to get")
|
||||
final OptionSpec<String> tradeIdOpt = parser.accepts(OPT_TRADE_ID, "id of trade")
|
||||
.withRequiredArg()
|
||||
.defaultsTo(EMPTY);
|
||||
|
||||
|
@ -73,7 +73,8 @@ public class CoreApi {
|
||||
@Inject
|
||||
public CoreApi(Config config,
|
||||
CoreDisputeAgentsService coreDisputeAgentsService,
|
||||
CoreHelpService coreHelpService, CoreOffersService coreOffersService,
|
||||
CoreHelpService coreHelpService,
|
||||
CoreOffersService coreOffersService,
|
||||
CorePaymentAccountsService paymentAccountsService,
|
||||
CorePriceService corePriceService,
|
||||
CoreTradesService coreTradesService,
|
||||
@ -212,8 +213,8 @@ public class CoreApi {
|
||||
// Prices
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public double getMarketPrice(String currencyCode) {
|
||||
return corePriceService.getMarketPrice(currencyCode);
|
||||
public void getMarketPrice(String currencyCode, Consumer<Double> resultHandler) {
|
||||
corePriceService.getMarketPrice(currencyCode, resultHandler);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -17,17 +17,18 @@
|
||||
|
||||
package bisq.core.api;
|
||||
|
||||
import bisq.core.provider.price.MarketPrice;
|
||||
import bisq.core.provider.price.PriceFeedService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static bisq.common.util.MathUtils.roundDouble;
|
||||
import static bisq.core.locale.CurrencyUtil.isFiatCurrency;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
@ -40,15 +41,29 @@ class CorePriceService {
|
||||
this.priceFeedService = priceFeedService;
|
||||
}
|
||||
|
||||
public double getMarketPrice(String currencyCode) {
|
||||
public void getMarketPrice(String currencyCode, Consumer<Double> resultHandler) {
|
||||
String upperCaseCurrencyCode = currencyCode.toUpperCase();
|
||||
|
||||
if (!isFiatCurrency(upperCaseCurrencyCode))
|
||||
throw new IllegalStateException(format("%s is not a valid currency code", upperCaseCurrencyCode));
|
||||
|
||||
if (!priceFeedService.hasPrices())
|
||||
throw new IllegalStateException("price feed service has no prices");
|
||||
|
||||
MarketPrice marketPrice = priceFeedService.getMarketPrice(currencyCode.toUpperCase());
|
||||
if (requireNonNull(marketPrice).isPriceAvailable()) {
|
||||
return roundDouble(marketPrice.getPrice(), 4);
|
||||
try {
|
||||
priceFeedService.setCurrencyCode(upperCaseCurrencyCode);
|
||||
} catch (Throwable throwable) {
|
||||
log.warn("Could not set currency code in PriceFeedService", throwable);
|
||||
}
|
||||
|
||||
priceFeedService.requestPriceFeed(price -> {
|
||||
if (price > 0) {
|
||||
log.info("{} price feed request returned {}", upperCaseCurrencyCode, price);
|
||||
resultHandler.accept(roundDouble(price, 4));
|
||||
} else {
|
||||
throw new IllegalStateException(format("'%s' price is not available", currencyCode));
|
||||
}
|
||||
throw new IllegalStateException(format("%s price is not available", upperCaseCurrencyCode));
|
||||
}
|
||||
},
|
||||
(errorMessage, throwable) -> log.warn(errorMessage, throwable));
|
||||
}
|
||||
}
|
||||
|
@ -129,26 +129,6 @@ public class CreateOfferService {
|
||||
minAmount.value,
|
||||
buyerSecurityDepositAsDouble);
|
||||
|
||||
// Log an approximate api CLI 'createoffer' dev/test param list.
|
||||
log.info("cli's createoffer positional option names: paymentAccountId direction currencyCode amount minAmount"
|
||||
+ " useMarketBasedPrice fixedPrice|marketPriceMargin buyerSecurityDeposit");
|
||||
log.info("cli's createoffer positional option values: {} " +
|
||||
"{} " +
|
||||
"{} " +
|
||||
"{} " +
|
||||
"{} " +
|
||||
"{} " +
|
||||
"{} " +
|
||||
"{}",
|
||||
paymentAccount.getId(),
|
||||
direction.name(),
|
||||
currencyCode,
|
||||
amount.value,
|
||||
minAmount.value,
|
||||
useMarketBasedPrice,
|
||||
(useMarketBasedPrice ? marketPriceMargin : price.getValue()),
|
||||
buyerSecurityDepositAsDouble);
|
||||
|
||||
long creationTime = new Date().getTime();
|
||||
NodeAddress makerAddress = p2PService.getAddress();
|
||||
boolean useMarketBasedPriceValue = useMarketBasedPrice &&
|
||||
|
26
core/src/main/resources/help/canceloffer-help.txt
Normal file
26
core/src/main/resources/help/canceloffer-help.txt
Normal file
@ -0,0 +1,26 @@
|
||||
canceloffer
|
||||
|
||||
NAME
|
||||
----
|
||||
canceloffer - cancel an existing offer to buy or sell BTC
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
canceloffer
|
||||
--offer-id=<offer-id>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Cancel an existing offer. The offer will be removed from other Bisq users' offer views,
|
||||
and paid transaction fees will be forfeited.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--offer-id
|
||||
The ID of the buy or sell offer to cancel.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
To cancel an offer with ID 83e8b2e2-51b6-4f39-a748-3ebd29c22aea:
|
||||
$ ./bisq-cli --password=xyz --port=9998 canceloffer -offer-id=83e8b2e2-51b6-4f39-a748-3ebd29c22aea
|
||||
|
27
core/src/main/resources/help/confirmpaymentreceived-help.txt
Normal file
27
core/src/main/resources/help/confirmpaymentreceived-help.txt
Normal file
@ -0,0 +1,27 @@
|
||||
confirmpaymentreceived
|
||||
|
||||
NAME
|
||||
----
|
||||
confirmpaymentreceived - confirm payment has been received
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
confirmpaymentreceived
|
||||
--trade-id=<trade-id>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
After the seller receives payment from the BTC buyer, confirmpaymentreceived notifies
|
||||
the buyer the payment has arrived. The seller can release locked BTC only after the
|
||||
this confirmation message has been sent.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--trade-id
|
||||
The ID of the trade (the full offer-id).
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
A BTC seller has taken an offer with ID 83e8b2e2-51b6-4f39-a748-3ebd29c22aea, and has recently
|
||||
received the required fiat payment from the buyer's fiat account:
|
||||
$ ./bisq-cli --password=xyz --port=9998 confirmpaymentreceived -trade-id=83e8b2e2-51b6-4f39-a748-3ebd29c22aea
|
26
core/src/main/resources/help/confirmpaymentstarted-help.txt
Normal file
26
core/src/main/resources/help/confirmpaymentstarted-help.txt
Normal file
@ -0,0 +1,26 @@
|
||||
confirmpaymentstarted
|
||||
|
||||
NAME
|
||||
----
|
||||
confirmpaymentstarted - confirm payment has been sent
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
confirmpaymentstarted
|
||||
--trade-id=<trade-id>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
After the buyer initiates payment to the BTC seller, confirmpaymentstarted notifies
|
||||
the seller to begin watching for a funds deposit in her payment account.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--trade-id
|
||||
The ID of the trade (the full offer-id).
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
A BTC buyer has taken an offer with ID 83e8b2e2-51b6-4f39-a748-3ebd29c22aea, and has recently
|
||||
initiated the required fiat payment to the seller's fiat account:
|
||||
$ ./bisq-cli --password=xyz --port=9998 confirmpaymentstarted -trade-id=83e8b2e2-51b6-4f39-a748-3ebd29c22aea
|
46
core/src/main/resources/help/createpaymentacct-help.txt
Normal file
46
core/src/main/resources/help/createpaymentacct-help.txt
Normal file
@ -0,0 +1,46 @@
|
||||
createpaymentacct
|
||||
|
||||
NAME
|
||||
----
|
||||
createpaymentacct - create a payment account
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
createpaymentacct
|
||||
--payment-account-form=<path>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Create a Bisq trading account with a payment account form.
|
||||
|
||||
The details of the payment account are defined in a manually edited json file generated
|
||||
by a getpaymentacctform command, e.g.,
|
||||
|
||||
{
|
||||
"_COMMENTS_": [
|
||||
"Do not manually edit the paymentMethodId field.",
|
||||
"Edit the salt field only if you are recreating a payment account on a new installation and wish to preserve the account age."
|
||||
],
|
||||
"paymentMethodId": "SEPA",
|
||||
"accountName": "your accountname",
|
||||
"bic": "your bic",
|
||||
"country": "your country",
|
||||
"holderName": "your holdername",
|
||||
"iban": "your iban",
|
||||
"salt": ""
|
||||
}
|
||||
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
To create a new SEPA payment account, find the payment-method-id for the getpaymentacctform command:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getpaymentmethods
|
||||
|
||||
Get a new, blank SEPA payment account form:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getpaymentacctform --payment-method-id=SEPA
|
||||
|
||||
The previous command created a json file named sepa_1610817857085.json. The timestamp
|
||||
in the file name is to ensure each generated file is uniquely named (you can rename the file).
|
||||
|
||||
Manually edit the json file, and pass the file's path to the createpaymentacct command:
|
||||
$ ./bisq-cli --password=xyz --port=9998 createpaymentacct --payment-account-form=sepa_1610817857085.json
|
23
core/src/main/resources/help/getaddressbalance-help.txt
Normal file
23
core/src/main/resources/help/getaddressbalance-help.txt
Normal file
@ -0,0 +1,23 @@
|
||||
getaddressbalance
|
||||
|
||||
NAME
|
||||
----
|
||||
getaddressbalance - get btc address balance
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
getaddressbalance
|
||||
--address=<btc-address>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Returns the balance of a BTC address in the Bisq server's wallet.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--address=<btc-address>
|
||||
The BTC address.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
$ ./bisq-cli --password=xyz --port=9998 getaddressbalance --address=bcrt1qygvsqmyt8jyhtp7l3zwqm7s7v3nar6vkc2luz3
|
30
core/src/main/resources/help/getbalance-help.txt
Normal file
30
core/src/main/resources/help/getbalance-help.txt
Normal file
@ -0,0 +1,30 @@
|
||||
getbalance
|
||||
|
||||
NAME
|
||||
----
|
||||
getbalance - get wallet balance(s)
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
getbalance
|
||||
[--currency-code=<bsq|btc>]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Returns full balance information for Bisq BSQ and/or BTC wallets.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--currency-code=<bsq|btc>
|
||||
The three letter Bisq wallet crypto currency code.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
Show full BSQ and BTC wallet balance information:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getbalance
|
||||
|
||||
Show full BSQ wallet balance information:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getbalance --currency-code=bsq
|
||||
|
||||
Show full BTC wallet balance information:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getbalance --currency-code=btc
|
30
core/src/main/resources/help/getbtcprice-help.txt
Normal file
30
core/src/main/resources/help/getbtcprice-help.txt
Normal file
@ -0,0 +1,30 @@
|
||||
getbtcprice
|
||||
|
||||
NAME
|
||||
----
|
||||
getbtcprice - get current btc market price
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
getbtcprice
|
||||
--currency-code=<eur|usd>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Returns the current market BTC price for the given currency-code.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
--currency-code
|
||||
The three letter code for the fiat currency code, e.g., EUR, USD, BRL, ...
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
Get the current BTC market price in Euros:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getbtcprice --currency-code=eur
|
||||
|
||||
Get the current BTC market price in Brazilian Reais:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getbtcprice --currency-code=brl
|
||||
|
||||
|
25
core/src/main/resources/help/getmyoffer-help.txt
Normal file
25
core/src/main/resources/help/getmyoffer-help.txt
Normal file
@ -0,0 +1,25 @@
|
||||
getmyoffer
|
||||
|
||||
NAME
|
||||
----
|
||||
getmyoffer - get your offer to buy or sell BTC
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
getmyoffer
|
||||
--offer-id=<offer-id>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
List one of your existing offers' details.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--offer-id
|
||||
The ID of your buy or sell offer.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
To view your offer with ID 83e8b2e2-51b6-4f39-a748-3ebd29c22aea:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getmyoffer -offer-id=83e8b2e2-51b6-4f39-a748-3ebd29c22aea
|
||||
|
33
core/src/main/resources/help/getmyoffers-help.txt
Normal file
33
core/src/main/resources/help/getmyoffers-help.txt
Normal file
@ -0,0 +1,33 @@
|
||||
getmyoffers
|
||||
|
||||
NAME
|
||||
----
|
||||
getmyoffers - get your own buy or sell BTC offers for a fiat currency
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
getmyoffers
|
||||
--direction=<buy|sell>
|
||||
--currency-code=<eur|usd>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
List your existing offers for a direction (SELL|BUY) and currency (EUR|GBP|USD|BRL|...).
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--direction
|
||||
The direction of the offer (BUY or SELL).
|
||||
|
||||
--currency-code
|
||||
The three letter code for the fiat used to buy or sell BTC, e.g., EUR, USD, BRL, ...
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
List all of your existing BUY offers for BRL:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getmyoffers --direction=buy --currency-code=brl
|
||||
|
||||
List all of your existing SELL offers for EUR:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getmyoffers --direction=sell --currency-code=eur
|
||||
|
||||
|
26
core/src/main/resources/help/getoffer-help.txt
Normal file
26
core/src/main/resources/help/getoffer-help.txt
Normal file
@ -0,0 +1,26 @@
|
||||
getoffer
|
||||
|
||||
NAME
|
||||
----
|
||||
getoffer - get an offer to buy or sell BTC
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
getoffer
|
||||
--offer-id=<offer-id>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
List an existing offer's details. The offer must not be one of your own.
|
||||
The offer must be available to take with one of your matching payment accounts.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--offer-id
|
||||
The ID of the buy or sell offer to view.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
To view an offer with ID 83e8b2e2-51b6-4f39-a748-3ebd29c22aea:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getoffer -offer-id=83e8b2e2-51b6-4f39-a748-3ebd29c22aea
|
||||
|
39
core/src/main/resources/help/getoffers-help.txt
Normal file
39
core/src/main/resources/help/getoffers-help.txt
Normal file
@ -0,0 +1,39 @@
|
||||
getoffers
|
||||
|
||||
NAME
|
||||
----
|
||||
getoffers - get available buy or sell BTC offers for a fiat currency
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
getoffers
|
||||
--direction=<buy|sell>
|
||||
--currency-code=<eur|usd>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
List existing offers for a direction (SELL|BUY) and currency (EUR|GBP|USD|BRL|...).
|
||||
All of the listed offers will be available for the taking because you have a
|
||||
matching payment account, and none of the offers listed will be one of yours.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--direction
|
||||
The direction of the offer (BUY or SELL).
|
||||
|
||||
--currency-code
|
||||
The three letter code for the fiat used to buy or sell BTC, e.g., EUR, USD, BRL, ...
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
You have one Brazilian Real payment account with a face-to-face payment method type.
|
||||
To view available offers to BUY BTC with BRL, created by other users with the same
|
||||
face-to-fact account type:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getoffers --direction=buy --currency-code=brl
|
||||
|
||||
You have several EUR payment accounts, each with a different payment method type.
|
||||
To view available offers to SELL BTC with EUR, created by other users having at
|
||||
least one payment account that matches any of your own:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getoffers --direction=sell --currency-code=eur
|
||||
|
||||
|
44
core/src/main/resources/help/getpaymentacctform-help.txt
Normal file
44
core/src/main/resources/help/getpaymentacctform-help.txt
Normal file
@ -0,0 +1,44 @@
|
||||
getpaymentacctform
|
||||
|
||||
NAME
|
||||
----
|
||||
getpaymentacctform - get a blank payment account form for a payment method
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
getpaymentacctform
|
||||
--payment-method-id=<payment-method-id>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Returns a new, blank payment account form as a json file, e.g.,
|
||||
|
||||
{
|
||||
"_COMMENTS_": [
|
||||
"Do not manually edit the paymentMethodId field.",
|
||||
"Edit the salt field only if you are recreating a payment account on a new installation and wish to preserve the account age."
|
||||
],
|
||||
"paymentMethodId": "CLEAR_X_CHANGE",
|
||||
"accountName": "your accountname",
|
||||
"emailOrMobileNr": "your emailormobilenr",
|
||||
"holderName": "your holdername",
|
||||
"salt": ""
|
||||
}
|
||||
|
||||
This form is manually edited, and used as a parameter to the createpaymentacct command,
|
||||
which creates the new payment account.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
To create a new CLEAR_X_CHANGE (Zelle) payment account, find the payment-method-id for
|
||||
the getpaymentacctform command:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getpaymentmethods
|
||||
|
||||
Get a new, blank CLEAR_X_CHANGE (Zelle) payment account form:
|
||||
$ ./bisq-cli --password=xyz --port=9998 getpaymentacctform --payment-method-id=CLEAR_X_CHANGE_ID
|
||||
|
||||
The previous command created a json file named clear_x_change_1610818248040.json. The timestamp
|
||||
in the file name is to ensure each generated file is uniquely named (you can rename the file).
|
||||
|
||||
Manually edit the json file, and pass the file's path to the createpaymentacct command:
|
||||
$ ./bisq-cli --password=xyz --port=9998 createpaymentacct --payment-account-form=clear_x_change_1610818248040.json
|
32
core/src/main/resources/help/gettrade-help.txt
Normal file
32
core/src/main/resources/help/gettrade-help.txt
Normal file
@ -0,0 +1,32 @@
|
||||
gettrade
|
||||
|
||||
NAME
|
||||
----
|
||||
gettrade - get a buy or sell BTC trade
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
gettrade
|
||||
--trade-id=<trade-id>
|
||||
[--show-contract=<true|false>]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
List details of a trade with the given trade-id. If the trade has not yet been completed,
|
||||
the details can inform each side of the trade of the current phase of the trade protocol.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--trade-id
|
||||
The ID of the trade (the full offer-id).
|
||||
|
||||
--show-contract
|
||||
Optionally display the trade's full contract details in json format. The default = false.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
To see the summary of a trade with ID 83e8b2e2-51b6-4f39-a748-3ebd29c22aea:
|
||||
$ ./bisq-cli --password=xyz --port=9998 gettrade -trade-id=83e8b2e2-51b6-4f39-a748-3ebd29c22aea
|
||||
|
||||
To see the full contract for a trade with ID 83e8b2e2-51b6-4f39-a748-3ebd29c22aea:
|
||||
$ ./bisq-cli --password=xyz --port=9998 gettrade -trade-id=83e8b2e2-51b6-4f39-a748-3ebd29c22aea --show-contract=true
|
27
core/src/main/resources/help/gettransaction-help.txt
Normal file
27
core/src/main/resources/help/gettransaction-help.txt
Normal file
@ -0,0 +1,27 @@
|
||||
gettransaction
|
||||
|
||||
NAME
|
||||
----
|
||||
gettransaction - get transaction summary
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
gettransaction
|
||||
--transaction-id=<transaction-id>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Returns a very brief summary of a BTC transaction created by the Bisq server.
|
||||
|
||||
To see full transaction details, use a bitcoin-core client or an online block explorer.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--transaction-id
|
||||
The ID of the BTC transaction.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
To see the summary of a transaction with ID 282dc2a5755219a49ee9f6d46a31a2cbaec6624beba96548180eccb1f004cdd8:
|
||||
$ ./bisq-cli --password=xyz --port=9998 gettransaction \
|
||||
-transaction-id=282dc2a5755219a49ee9f6d46a31a2cbaec6624beba96548180eccb1f004cdd8
|
31
core/src/main/resources/help/keepfunds-help.txt
Normal file
31
core/src/main/resources/help/keepfunds-help.txt
Normal file
@ -0,0 +1,31 @@
|
||||
keepfunds
|
||||
|
||||
NAME
|
||||
----
|
||||
keepfunds - keep BTC received during a trade in Bisq wallet
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
keepfunds
|
||||
--trade-id=<trade-id>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
A BTC buyer completes the final step in the trade protocol by keeping received BTC in his
|
||||
Bisq wallet. This step may not seem necessary from the buyer's perspective, but it is
|
||||
necessary for correct transition of a trade's state to CLOSED, within the Bisq server.
|
||||
|
||||
The alternative way to close out the trade is to send the received BTC to an external
|
||||
BTC wallet, using the withdrawfunds command.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--trade-id
|
||||
The ID of the trade (the full offer-id).
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
A BTC seller has informed the buyer that fiat payment has been received for trade with ID
|
||||
83e8b2e2-51b6-4f39-a748-3ebd29c22aea, and locked BTC has been released to the buyer.
|
||||
The BTC buyer closes out the trade by keeping the received BTC in her Bisq wallet:
|
||||
$ ./bisq-cli --password=xyz --port=9998 keepfunds -trade-id=83e8b2e2-51b6-4f39-a748-3ebd29c22aea
|
@ -14,4 +14,5 @@ Locks an unlocked wallet before an unlockwallet timeout expires.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
Immediately lock an encrypted wallet set to automatically lock in the future:
|
||||
$ ./bisq-cli --password=xyz --port=9998 lockwallet
|
||||
|
19
core/src/main/resources/help/removewalletpassword-help.txt
Normal file
19
core/src/main/resources/help/removewalletpassword-help.txt
Normal file
@ -0,0 +1,19 @@
|
||||
removewalletpassword
|
||||
|
||||
NAME
|
||||
----
|
||||
removewalletpassword - remove a Bisq wallet's encryption password
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
removewalletpassword
|
||||
--wallet-password=<wallet-password>
|
||||
--timeout=<seconds>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Remove an encryption password from an encrypted Bisq wallet.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
$ ./bisq-cli --password=xyz --port=9998 removewalletpassword --wallet-password=mypassword
|
38
core/src/main/resources/help/sendbsq-help.txt
Normal file
38
core/src/main/resources/help/sendbsq-help.txt
Normal file
@ -0,0 +1,38 @@
|
||||
sendbsq
|
||||
|
||||
NAME
|
||||
----
|
||||
sendbsq - send BSQ to an external wallet
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
sendbsq
|
||||
--address=<btc-address>
|
||||
--amount=<btc-amount>
|
||||
[--tx-fee-rate=<sats/byte>]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Send BSQ from your Bisq wallet to an external BSQ address.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--address
|
||||
The destination BSQ address for the send transaction.
|
||||
|
||||
--amount
|
||||
The amount of BSQ to send.
|
||||
|
||||
--tx-fee-rate
|
||||
An optional transaction fee rate (sats/byte) for the transaction. The user is
|
||||
responsible for choosing a fee rate that will be accepted by the network in a
|
||||
reasonable amount of time, and the fee rate must be greater than 1 (sats/byte).
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
Send 500 BSQ to address Bn3PCQgRwhkrGnaMp1RYwt9tFwL51YELqne with a default transaction fee rate:
|
||||
$ ./bisq-cli --password=xyz --port=9998 sendbsq --address=Bn3PCQgRwhkrGnaMp1RYwt9tFwL51YELqne --amount=500.00
|
||||
|
||||
Send 3000 BSQ to address Bn3PCQgRwhkrGnaMp1RYwt9tFwL51YELqne with transaction fee rate of 40 sats/byte:
|
||||
$ ./bisq-cli --password=xyz --port=9998 sendbsq --address=Bn3PCQgRwhkrGnaMp1RYwt9tFwL51YELqne --amount=3000.00 \
|
||||
--tx-fee-rate=40
|
51
core/src/main/resources/help/sendbtc-help.txt
Normal file
51
core/src/main/resources/help/sendbtc-help.txt
Normal file
@ -0,0 +1,51 @@
|
||||
sendbtc
|
||||
|
||||
NAME
|
||||
----
|
||||
sendbtc - send BTC to an external wallet
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
sendbtc
|
||||
--address=<btc-address>
|
||||
--amount=<btc-amount>
|
||||
[--tx-fee-rate=<sats/byte>]
|
||||
[--memo=<"memo">]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Send BTC from your Bisq wallet to an external BTC address.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--address
|
||||
The destination BTC address for the send transaction.
|
||||
|
||||
--amount
|
||||
The amount of BTC to send.
|
||||
|
||||
--tx-fee-rate
|
||||
An optional transaction fee rate (sats/byte) for the transaction. The user is
|
||||
responsible for choosing a fee rate that will be accepted by the network in a
|
||||
reasonable amount of time, and the fee rate must be greater than 1 (sats/byte).
|
||||
|
||||
--memo
|
||||
An optional memo to be saved with the send btc transaction.
|
||||
A multi word memo must be enclosed in double quotes.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
Send 0.10 BTC to address bcrt1qygvsqmyt8jyhtp7l3zwqm7s7v3nar6vkc2luz3 with a default
|
||||
transaction fee rate:
|
||||
$ ./bisq-cli --password=xyz --port=9998 sendbtc --address=bcrt1qygvsqmyt8jyhtp7l3zwqm7s7v3nar6vkc2luz3 --amount=0.10
|
||||
|
||||
Send 0.05 BTC to address bcrt1qygvsqmyt8jyhtp7l3zwqm7s7v3nar6vkc2luz3 with a transaction
|
||||
fee rate of 10 sats/byte:
|
||||
$ ./bisq-cli --password=xyz --port=9998 sendbtc --address=bcrt1qygvsqmyt8jyhtp7l3zwqm7s7v3nar6vkc2luz3 --amount=0.05 \
|
||||
--tx-fee-rate=10
|
||||
|
||||
Send 0.005 BTC to address bcrt1qygvsqmyt8jyhtp7l3zwqm7s7v3nar6vkc2luz3 with a transaction
|
||||
fee rate of 40 sats/byte, and save a memo with the send transaction:
|
||||
$ ./bisq-cli --password=xyz --port=9998 sendbtc --address=bcrt1qygvsqmyt8jyhtp7l3zwqm7s7v3nar6vkc2luz3 --amount=0.005 \
|
||||
--tx-fee-rate=40
|
||||
--memo="note to self"
|
19
core/src/main/resources/help/settxfeerate-help.txt
Normal file
19
core/src/main/resources/help/settxfeerate-help.txt
Normal file
@ -0,0 +1,19 @@
|
||||
settxfeerate
|
||||
|
||||
NAME
|
||||
----
|
||||
settxfeerate - set custom transaction fee rate preference
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
settxfeerate
|
||||
--tx-fee-rate=<sats/byte>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Sets the user's custom transaction fee rate preference.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
Set custom transaction fee rate to 25 sats/byte:
|
||||
$ ./bisq-cli --password=xyz --port=9998 settxfeerate --tx-fee-rate=25
|
25
core/src/main/resources/help/setwalletpassword-help.txt
Normal file
25
core/src/main/resources/help/setwalletpassword-help.txt
Normal file
@ -0,0 +1,25 @@
|
||||
setwalletpassword
|
||||
|
||||
NAME
|
||||
----
|
||||
setwalletpassword - set Bisq wallet password
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
setwalletpassword
|
||||
--wallet-password=<wallet-password>
|
||||
--new-wallet-password=<new-wallet-password>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Encrypts a Bisq wallet with a password. If the optional new wallet password option is
|
||||
present, a new wallet password replaces the existing password
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
Encrypt an unencrypted Bisq wallet with a password:
|
||||
$ ./bisq-cli --password=xyz --port=9998 setwalletpassword --wallet-password=mypassword
|
||||
|
||||
Set a new password on a Bisq wallet that is already encrypted:
|
||||
$ ./bisq-cli --password=xyz --port=9998 setwalletpassword --wallet-password=myoldpassword \
|
||||
--new-wallet-password=mynewpassword
|
21
core/src/main/resources/help/unlockwallet-help.txt
Normal file
21
core/src/main/resources/help/unlockwallet-help.txt
Normal file
@ -0,0 +1,21 @@
|
||||
unlockwallet
|
||||
|
||||
NAME
|
||||
----
|
||||
unlockwallet - unlock an encrypted Bisq wallet
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
unlockwallet
|
||||
--wallet-password=<wallet-password>
|
||||
--timeout=<seconds>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Unlocks an encrypted Bisq wallet for a specified number of seconds.
|
||||
The timeout can be manually overridden with the lockwallet command.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
Unlock a wallet encrypted with the wallet-password "mypassword" for 30 seconds:
|
||||
$ ./bisq-cli --password=xyz --port=9998 unlockwallet --wallet-password=mypassword --timeout=30
|
@ -14,4 +14,5 @@ Unsets (removes) the transaction fee rate user preference.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
Remove the user's custom transaction fee rate preference:
|
||||
$ ./bisq-cli --password=xyz --port=9998 unsettxfeerate
|
||||
|
50
core/src/main/resources/help/withdrawfunds-help.txt
Normal file
50
core/src/main/resources/help/withdrawfunds-help.txt
Normal file
@ -0,0 +1,50 @@
|
||||
withdrawfunds
|
||||
|
||||
NAME
|
||||
----
|
||||
withdrawfunds - send BTC received during a trade to an external BTC wallet
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
withdrawfunds
|
||||
--trade-id=<trade-id>
|
||||
--address=<btc-address>
|
||||
[--memo=<"memo">]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
A BTC buyer completes the final step in the trade protocol by sending received BTC to
|
||||
an external BTC wallet.
|
||||
|
||||
The alternative way to close out the trade is to keep the received BTC in the Bisq wallet,
|
||||
using the keepfunds command.
|
||||
|
||||
The buyer needs to complete the trade protocol using the keepfunds or withdrawfunds or command.
|
||||
This step may not seem necessary from the buyer's perspective, but it is necessary for correct
|
||||
transition of a trade's state to CLOSED, within the Bisq server.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--trade-id
|
||||
The ID of the trade (the full offer-id).
|
||||
|
||||
--address
|
||||
The destination btc address for the send btc transaction.
|
||||
|
||||
--memo
|
||||
An optional memo to be saved with the send btc transaction.
|
||||
A multi word memo must be enclosed in double quotes.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
A BTC seller has informed the buyer that fiat payment has been received for trade with ID
|
||||
83e8b2e2-51b6-4f39-a748-3ebd29c22aea, and locked BTC has been released to the buyer.
|
||||
The BTC buyer closes out the trade by sending the received BTC to an external BTC wallet:
|
||||
$ ./bisq-cli --password=xyz --port=9998 withdrawfunds -trade-id=83e8b2e2-51b6-4f39-a748-3ebd29c22aea \
|
||||
--address=2N5J6MyjAsWnashimGiNwoRzUXThsQzRmbv (bitcoin regtest address)
|
||||
|
||||
|
||||
A seller sends a trade's BTC proceeds to an external wallet, and includes an optional memo:
|
||||
$ ./bisq-cli --password=xyz --port=9998 withdrawfunds -trade-id=83e8b2e2-51b6-4f39-a748-3ebd29c22aea \
|
||||
--address=2N5J6MyjAsWnashimGiNwoRzUXThsQzRmbv
|
||||
--memo="note to self"
|
@ -45,10 +45,12 @@ class GrpcPriceService extends PriceGrpc.PriceImplBase {
|
||||
public void getMarketPrice(MarketPriceRequest req,
|
||||
StreamObserver<MarketPriceReply> responseObserver) {
|
||||
try {
|
||||
double price = coreApi.getMarketPrice(req.getCurrencyCode());
|
||||
coreApi.getMarketPrice(req.getCurrencyCode(),
|
||||
price -> {
|
||||
var reply = MarketPriceReply.newBuilder().setPrice(price).build();
|
||||
responseObserver.onNext(reply);
|
||||
responseObserver.onCompleted();
|
||||
});
|
||||
} catch (Throwable cause) {
|
||||
exceptionHandler.handleException(cause, responseObserver);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user