diff --git a/apitest/scripts/limit-order-simulation.sh b/apitest/scripts/limit-order-simulation.sh index 253deec1a8a..33312ae73bc 100755 --- a/apitest/scripts/limit-order-simulation.sh +++ b/apitest/scripts/limit-order-simulation.sh @@ -34,57 +34,58 @@ # # `$ apitest/scripts/limit-order-simulation.sh -l 40000 -d sell -c fr -m 0.00 -a 0.125` +APP_BASE_NAME=$(basename "$0") APP_HOME=$(pwd -P) -APITEST_SCRIPTS_HOME="${APP_HOME}/apitest/scripts" +APITEST_SCRIPTS_HOME="$APP_HOME/apitest/scripts" -source "${APITEST_SCRIPTS_HOME}/trade-simulation-env.sh" -source "${APITEST_SCRIPTS_HOME}/trade-simulation-utils.sh" +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:" +printdate "Started $APP_BASE_NAME with parameters:" printscriptparams printbreak editpaymentaccountform "$COUNTRY_CODE" exitoncommandalert $? -cat "${APITEST_SCRIPTS_HOME}/${F2F_ACCT_FORM}" +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}") +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}") +echo "$CMD_OUTPUT" +ALICE_ACCT_ID=$(getnewpaymentacctid "$CMD_OUTPUT") exitoncommandalert $? -CURRENCY_CODE=$(getnewpaymentacctcurrency "${CMD_OUTPUT}") +CURRENCY_CODE=$(getnewpaymentacctcurrency "$CMD_OUTPUT") exitoncommandalert $? -printdate "ALICE F2F payment-account-id = ${ALICE_ACCT_ID}, currency-code = ${CURRENCY_CODE}." +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}") +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}") +echo "$CMD_OUTPUT" +BOB_ACCT_ID=$(getnewpaymentacctid "$CMD_OUTPUT") exitoncommandalert $? -CURRENCY_CODE=$(getnewpaymentacctcurrency "${CMD_OUTPUT}") +CURRENCY_CODE=$(getnewpaymentacctcurrency "$CMD_OUTPUT") exitoncommandalert $? -printdate "BOB F2F payment-account-id = ${BOB_ACCT_ID}, currency-code = ${CURRENCY_CODE}." +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}." + 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}." + printdate "Create a SELL / $CURRENCY_CODE offer when the market price rises to or above $LIMIT_PRICE $CURRENCY_CODE." fi DONE=0 @@ -112,48 +113,47 @@ while : ; do 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}" +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}" + 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}") +printdate "ALICE CLI: $CMD" +OFFER_ID=$(createoffer "$CMD") exitoncommandalert $? -printdate "ALICE: Created offer with id: ${OFFER_ID}." +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}" +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}" +echo "$OFFER" printbreak -sleeptraced 7 +sleeptraced 4 # 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}" +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}" +echo "$OFFERS" exit 0 diff --git a/apitest/scripts/rolling-offer-simulation.sh b/apitest/scripts/rolling-offer-simulation.sh new file mode 100755 index 00000000000..5ab1eecc88b --- /dev/null +++ b/apitest/scripts/rolling-offer-simulation.sh @@ -0,0 +1,119 @@ +#! /bin/bash + +# Demonstrates a way to always keep one offer in the market, using the API CLI with a local regtest bitcoin node. +# Alice creates an offer, waits for Bob to take it, and completes the trade protocol with him. Then Alice +# creates a new offer... +# +# Stop the script by entering ^C. +# +# 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/rolling-offer-simulation.sh -d buy -c us -m 2.00 -a 0.125` +# +# Script options: -d -c (-m || -f ) -a +# +# Example: +# +# Create a buy/usd offer to sell 0.1 btc at 2% above market price, using a US face to face payment account: +# +# `$ apitest/scripts/rolling-offer-simulation.sh -d sell -c us -m 2.00 -a 0.1` + + +APP_BASE_NAME=$(basename "$0") +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 +parseopts "$@" + +printdate "Started $APP_BASE_NAME with parameters:" +printscriptparams +printbreak + +registerdisputeagents + +showcreatepaymentacctsteps "Alice" "$ALICE_PORT" + +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" +printbreak +export ALICE_ACCT_ID=$(getnewpaymentacctid "$CMD_OUTPUT") +export CURRENCY_CODE=$(getnewpaymentacctcurrency "$CMD_OUTPUT") +printdate "Alice's F2F payment-account-id: $ALICE_ACCT_ID, currency-code: $CURRENCY_CODE" +exitoncommandalert $? +printbreak + +printdate "Bob creates his F2F 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") +echo "$CMD_OUTPUT" +printbreak +export BOB_ACCT_ID=$(getnewpaymentacctid "$CMD_OUTPUT") +export CURRENCY_CODE=$(getnewpaymentacctcurrency "$CMD_OUTPUT") +printdate "Bob's F2F payment-account-id: $BOB_ACCT_ID, currency-code: $CURRENCY_CODE" +exitoncommandalert $? +printbreak + +while : ; do + printdate "ALICE $ALICE_ROLE: Creating $DIRECTION $CURRENCY_CODE offer with payment acct $ALICE_ACCT_ID." + CURRENT_PRICE=$(getcurrentprice "$ALICE_PORT" "$CURRENCY_CODE") + exitoncommandalert $? + printdate "Current Market Price: $CURRENT_PRICE" + CMD=$(gencreateoffercommand "$ALICE_PORT" "$ALICE_ACCT_ID") + 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 3 + + # Generate some btc blocks. + printdate "Generating btc blocks after publishing Alice's offer." + genbtcblocks 3 2 + printbreak + + RANDOM_WAIT=$(echo $[$RANDOM % 10 + 1]) + printdate "Bob will take Alice's offer in $RANDOM_WAIT seconds..." + sleeptraced "$RANDOM_WAIT" + + executetrade + exitoncommandalert $? + printbreak +done + +exit 0 diff --git a/apitest/scripts/trade-simulation-env.sh b/apitest/scripts/trade-simulation-env.sh index 64be81029a8..78d9d6dee10 100755 --- a/apitest/scripts/trade-simulation-env.sh +++ b/apitest/scripts/trade-simulation-env.sh @@ -22,14 +22,14 @@ checksetup() { --registration-key=6ac43ea1df2a290c1c8391736aa42e4339c5cb4f110ff0257a13b63211977b7a" exit 1; } - printdate "Checking ${APP_HOME} for some expected directories and files." - if [ -d "${APP_HOME}/apitest" ]; then + 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 + 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." @@ -181,12 +181,12 @@ parselimitorderopts() { 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}") + if [[ $APP_HOME == *"+"* ]]; then + ESCAPED_APP_HOME=$(escapepluschar "$APP_HOME") else - ESCAPED_APP_HOME="${APP_HOME}" + ESCAPED_APP_HOME="$APP_HOME" fi - if pgrep -f "bitcoind -datadir=${ESCAPED_APP_HOME}/apitest/build/resources/main/Bitcoin-regtest" > /dev/null ; then + 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." @@ -196,24 +196,24 @@ checkbitcoindrunning() { printscriptparams() { if [ -n "${LIMIT_PRICE+1}" ]; then - echo " LIMIT_PRICE = ${LIMIT_PRICE}" + 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}" + 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}" + echo " BOB_ROLE = $BOB_ROLE" fi if [ -n "${ALICE_ROLE+1}" ]; then - echo " ALICE_ROLE = ${ALICE_ROLE}" + echo " ALICE_ROLE = $ALICE_ROLE" fi if [ -n "${WAIT+1}" ]; then - echo " WAIT = ${WAIT}" + echo " WAIT = $WAIT" fi } diff --git a/apitest/scripts/trade-simulation-utils.sh b/apitest/scripts/trade-simulation-utils.sh index d41ef2b80d2..eb1d14e65e1 100755 --- a/apitest/scripts/trade-simulation-utils.sh +++ b/apitest/scripts/trade-simulation-utils.sh @@ -2,7 +2,7 @@ # This file must be sourced by the main driver. -source "${APITEST_SCRIPTS_HOME}/trade-simulation-env.sh" +source "$APITEST_SCRIPTS_HOME/trade-simulation-env.sh" printdate() { echo "[$(date)] $@" @@ -46,10 +46,10 @@ exitoncommandalert() { 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}" + 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}" + 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. @@ -59,7 +59,7 @@ registerdisputeagents() { getbtcoreaddress() { CMD="bitcoin-cli -regtest -rpcport=19443 -rpcuser=apitest -rpcpassword=apitest getnewaddress" NEW_ADDRESS=$($CMD) - echo "${NEW_ADDRESS}" + echo "$NEW_ADDRESS" } genbtcblocks() { @@ -74,7 +74,7 @@ genbtcblocks() { for i in $(seq -f "%02g" 1 "$NUM_BLOCKS") do NEW_BLOCK_HASH=$(genbtcblock "$CMD") - printdate "Block Hash #$i:${NEW_BLOCK_HASH}" + printdate "Block Hash #$i:$NEW_BLOCK_HASH" sleep "$SECONDS_BETWEEN_BLOCKS" done } @@ -88,12 +88,12 @@ genbtcblock() { escapepluschar() { STRING="$1" NEW_STRING=$(echo "${STRING//+/\\+}") - echo "${NEW_STRING}" + echo "$NEW_STRING" } printbalances() { PORT="$1" - printcmd "${CLI_BASE} --port=${PORT} getbalance" + printcmd "$CLI_BASE --port=$PORT getbalance" $CLI_BASE --port="$PORT" getbalance } @@ -102,54 +102,99 @@ getpaymentaccountmethods() { CMD_OUTPUT=$($CMD) commandalert $? "Could not get payment method ids." printdate "Payment Method IDs:" - echo "${CMD_OUTPUT}" + echo "$CMD_OUTPUT" } getpaymentaccountform() { CMD="$1" CMD_OUTPUT=$($CMD) commandalert $? "Could not get new payment account form." - echo "${CMD_OUTPUT}" + echo "$CMD_OUTPUT" } editpaymentaccountform() { COUNTRY_CODE="$1" - CMD="python3 ${APITEST_SCRIPTS_HOME}/editf2faccountform.py $COUNTRY_CODE" + 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}." + 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') + 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}" + echo "$ACCT_ID" } getnewpaymentacctcurrency() { CREATE_PAYMENT_ACCT_OUTPUT="$1" - PAYMENT_ACCT_DETAIL=$(echo -e "${CREATE_PAYMENT_ACCT_OUTPUT}" | sed -n '3p') + 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}" + echo "$CURRENCY_CODE" } createpaymentacct() { CMD="$1" CMD_OUTPUT=$($CMD) commandalert $? "Could not create new payment account." - echo "${CMD_OUTPUT}" + echo "$CMD_OUTPUT" } getpaymentaccounts() { PORT="$1" - printcmd "${CLI_BASE} --port=${PORT} getpaymentaccts" + printcmd "$CLI_BASE --port=$PORT getpaymentaccts" CMD="$CLI_BASE --port=$PORT getpaymentaccts" CMD_OUTPUT=$($CMD) commandalert $? "Could not get payment accounts." - echo "${CMD_OUTPUT}" + echo "$CMD_OUTPUT" +} + +showcreatepaymentacctsteps() { + USER="$1" + PORT="$2" + printdate "$USER looks for the ID of the face to face payment account method (Bob will use same payment method)." + CMD="$CLI_BASE --port=$PORT getpaymentmethods" + printdate "$USER CLI: $CMD" + PAYMENT_ACCT_METHODS=$(getpaymentaccountmethods "$CMD") + echo "$PAYMENT_ACCT_METHODS" + printbreak + + printdate "$USER uses the F2F payment method id to create a face to face payment account in country $COUNTRY_CODE." + CMD="$CLI_BASE --port=$PORT getpaymentacctform --payment-method-id=F2F" + printdate "$USER CLI: $CMD" + getpaymentaccountform "$CMD" + printbreak + + printdate "$USER edits the $COUNTRY_CODE payment account form, and (optionally) renames it as $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 +} + +gencreateoffercommand() { + PORT="$1" + ACCT_ID="$2" + CMD="$CLI_BASE --port=$PORT createoffer" + CMD+=" --payment-account=$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=15.0" + CMD+=" --fee-currency=BSQ" + echo "$CMD" } createoffer() { @@ -160,9 +205,388 @@ createoffer() { # 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}" + OFFER_DETAIL=$(echo -e "$OFFER_DESC" | sed -n '2p') + NEW_OFFER_ID=$(echo -e "$OFFER_DETAIL" | awk '{print $NF}') + echo "$NEW_OFFER_ID" +} + +getfirstofferid() { + PORT="$1" + CMD="$CLI_BASE --port=$PORT getoffers --direction=$DIRECTION --currency-code=$CURRENCY_CODE" + CMD_OUTPUT=$($CMD) + commandalert $? "Could not get current $DIRECTION / $CURRENCY_CODE offers." + FIRST_OFFER_DETAIL=$(echo -e "$CMD_OUTPUT" | sed -n '2p') + FIRST_OFFER_ID=$(echo -e "$FIRST_OFFER_DETAIL" | awk '{print $NF}') + commandalert $? "Could parse the offer-id from the first listed offer." + echo "$FIRST_OFFER_ID" +} + +gettrade() { + GET_TRADE_CMD="$1" + TRADE_DESC=$($GET_TRADE_CMD) + commandalert $? "Could not get trade." + echo "$TRADE_DESC" +} + +gettradedetail() { + TRADE_DESC="$1" + # Get 2nd line of gettrade cmd output, and squeeze multi space delimiters into one space. + TRADE_DETAIL=$(echo "$TRADE_DESC" | sed -n '2p' | tr -s ' ') + commandalert $? "Could not get trade detail (line 2 of gettrade output)." + echo "$TRADE_DETAIL" +} + +istradedepositpublished() { + TRADE_DETAIL="$1" + MAKER_OR_TAKER="$2" + if [ "$MAKER_OR_TAKER" = "MAKER" ] + then + ANSWER=$(echo "$TRADE_DETAIL" | awk '{print $9}') + else + ANSWER=$(echo "$TRADE_DETAIL" | awk '{print $10}') + fi + commandalert $? "Could not parse istradedepositpublished from trade detail." + echo "$ANSWER" +} + +istradedepositconfirmed() { + TRADE_DETAIL="$1" + MAKER_OR_TAKER="$2" + if [ "$MAKER_OR_TAKER" = "MAKER" ] + then + ANSWER=$(echo "$TRADE_DETAIL" | awk '{print $10}') + else + ANSWER=$(echo "$TRADE_DETAIL" | awk '{print $11}') + fi + commandalert $? "Could not parse istradedepositconfirmed from trade detail." + echo "$ANSWER" +} + +istradepaymentsent() { + TRADE_DETAIL="$1" + MAKER_OR_TAKER="$2" + if [ "$MAKER_OR_TAKER" = "MAKER" ] + then + ANSWER=$(echo "$TRADE_DETAIL" | awk '{print $11}') + else + ANSWER=$(echo "$TRADE_DETAIL" | awk '{print $12}') + fi + commandalert $? "Could not parse istradepaymentsent from trade detail." + echo "$ANSWER" +} + +istradepaymentreceived() { + TRADE_DETAIL="$1" + MAKER_OR_TAKER="$2" + if [ "$MAKER_OR_TAKER" = "MAKER" ] + then + ANSWER=$(echo "$TRADE_DETAIL" | awk '{print $12}') + else + ANSWER=$(echo "$TRADE_DETAIL" | awk '{print $13}') + fi + commandalert $? "Could not parse istradepaymentreceived from trade detail." + echo "$ANSWER" +} + +istradepayoutpublished() { + TRADE_DETAIL="$1" + MAKER_OR_TAKER="$2" + if [ "$MAKER_OR_TAKER" = "MAKER" ] + then + ANSWER=$(echo "$TRADE_DETAIL" | awk '{print $13}') + else + ANSWER=$(echo "$TRADE_DETAIL" | awk '{print $14}') + fi + commandalert $? "Could not parse istradepayoutpublished from trade detail." + echo "$ANSWER" +} + +waitfortradedepositpublished() { + # Loops until Bob's trade deposit is published. (Bob is always the trade taker.) + OFFER_ID="$1" + DONE=0 + while : ; do + if [ "$DONE" -ne 0 ]; then + break + fi + + printdate "BOB $BOB_ROLE: Looking at his trade with id $OFFER_ID." + CMD="$CLI_BASE --port=$BOB_PORT gettrade --trade-id=$OFFER_ID" + printdate "BOB CLI: $CMD" + GETTRADE_CMD_OUTPUT=$(gettrade "$CMD") + exitoncommandalert $? + echo "$GETTRADE_CMD_OUTPUT" + printbreak + + TRADE_DETAIL=$(gettradedetail "$GETTRADE_CMD_OUTPUT") + exitoncommandalert $? + + IS_TRADE_DEPOSIT_PUBLISHED=$(istradedepositpublished "$TRADE_DETAIL" "TAKER") + exitoncommandalert $? + + printdate "BOB $BOB_ROLE: Has taker's trade deposit been published? $IS_TRADE_DEPOSIT_PUBLISHED" + if [ "$IS_TRADE_DEPOSIT_PUBLISHED" = "YES" ] + then + DONE=1 + else + RANDOM_WAIT=$(echo $[$RANDOM % 3 + 1]) + sleeptraced "$RANDOM_WAIT" + fi + printbreak + done +} + +waitfortradedepositconfirmed() { + # Loops until Bob's trade deposit is confirmed. (Bob is always the trade taker.) + OFFER_ID="$1" + DONE=0 + while : ; do + if [ "$DONE" -ne 0 ]; then + break + fi + + printdate "BOB $BOB_ROLE: Looking at his trade with id $OFFER_ID." + CMD="$CLI_BASE --port=$BOB_PORT gettrade --trade-id=$OFFER_ID" + printdate "BOB CLI: $CMD" + GETTRADE_CMD_OUTPUT=$(gettrade "$CMD") + exitoncommandalert $? + echo "$GETTRADE_CMD_OUTPUT" + printbreak + + TRADE_DETAIL=$(gettradedetail "$GETTRADE_CMD_OUTPUT") + exitoncommandalert $? + + IS_TRADE_DEPOSIT_CONFIRMED=$(istradedepositconfirmed "$TRADE_DETAIL" "TAKER") + exitoncommandalert $? + printdate "BOB $BOB_ROLE: Has taker's trade deposit been confirmed? $IS_TRADE_DEPOSIT_CONFIRMED" + printbreak + + if [ "$IS_TRADE_DEPOSIT_CONFIRMED" = "YES" ] + then + DONE=1 + else + printdate "Generating btc block while Bob waits for trade deposit to be confirmed." + genbtcblocks 1 0 + + RANDOM_WAIT=$(echo $[$RANDOM % 3 + 1]) + sleeptraced "$RANDOM_WAIT" + fi + done +} + +waitfortradepaymentsent() { + # Loops until buyer's trade payment has been sent. + PORT="$1" + SELLER="$2" + OFFER_ID="$3" + MAKER_OR_TAKER="$4" + DONE=0 + while : ; do + if [ "$DONE" -ne 0 ]; then + break + fi + + printdate "$SELLER: Looking at trade with id $OFFER_ID." + CMD="$CLI_BASE --port=$PORT gettrade --trade-id=$OFFER_ID" + printdate "$SELLER CLI: $CMD" + GETTRADE_CMD_OUTPUT=$(gettrade "$CMD") + exitoncommandalert $? + echo "$GETTRADE_CMD_OUTPUT" + printbreak + + TRADE_DETAIL=$(gettradedetail "$GETTRADE_CMD_OUTPUT") + exitoncommandalert $? + + IS_TRADE_PAYMENT_SENT=$(istradepaymentsent "$TRADE_DETAIL" "$MAKER_OR_TAKER") + exitoncommandalert $? + printdate "$SELLER: Has buyer's fiat payment been initiated? $IS_TRADE_PAYMENT_SENT" + if [ "$IS_TRADE_PAYMENT_SENT" = "YES" ] + then + DONE=1 + else + RANDOM_WAIT=$(echo $[$RANDOM % 3 + 1]) + sleeptraced "$RANDOM_WAIT" + fi + printbreak + done +} + +waitfortradepaymentreceived() { + # Loops until buyer's trade payment has been received. + PORT="$1" + SELLER="$2" + OFFER_ID="$3" + MAKER_OR_TAKER="$4" + DONE=0 + while : ; do + if [ "$DONE" -ne 0 ]; then + break + fi + + printdate "$SELLER: Looking at trade with id $OFFER_ID." + CMD="$CLI_BASE --port=$PORT gettrade --trade-id=$OFFER_ID" + printdate "$SELLER CLI: $CMD" + GETTRADE_CMD_OUTPUT=$(gettrade "$CMD") + exitoncommandalert $? + echo "$GETTRADE_CMD_OUTPUT" + printbreak + + TRADE_DETAIL=$(gettradedetail "$GETTRADE_CMD_OUTPUT") + exitoncommandalert $? + + # When the seller receives a 'payment sent' message, it is assumed funds (fiat) have already been deposited. + # In a real trade, there is usually a delay between receipt of a 'payment sent' message, and the funds deposit, + # but we do not need to simulate that in this regtest script. + IS_TRADE_PAYMENT_SENT=$(istradepaymentreceived "$TRADE_DETAIL" "$MAKER_OR_TAKER") + exitoncommandalert $? + printdate "$SELLER: Has buyer's payment been transferred to seller's fiat account? $IS_TRADE_PAYMENT_SENT" + if [ "$IS_TRADE_PAYMENT_SENT" = "YES" ] + then + DONE=1 + else + RANDOM_WAIT=$(echo $[$RANDOM % 3 + 1]) + sleeptraced "$RANDOM_WAIT" + fi + printbreak + done +} + +delayconfirmpaymentstarted() { + # Confirm payment started after a random delay. This should be run in the background + # while the payee polls the trade status, waiting for the message before confirming + # payment has been received. + PAYER="$1" + PORT="$2" + OFFER_ID="$3" + RANDOM_WAIT=$(echo $[$RANDOM % 5 + 1]) + printdate "$PAYER: Sending fiat payment sent message to seller in $RANDOM_WAIT seconds..." + sleeptraced "$RANDOM_WAIT" + CMD="$CLI_BASE --port=$PORT confirmpaymentstarted --trade-id=$OFFER_ID" + printdate "$PAYER_CLI: $CMD" + SENT_MSG=$($CMD) + commandalert $? "Could not send confirmpaymentstarted message." + # Print the confirmpaymentstarted command's console output. + printdate "$SENT_MSG" + printbreak +} + +delayconfirmpaymentreceived() { + # Confirm payment received after a random delay. This should be run in the background + # while the payer polls the trade status, waiting for the confirmation from the seller + # that funds have been received. + PAYEE="$1" + PORT="$2" + OFFER_ID="$3" + RANDOM_WAIT=$(echo $[$RANDOM % 5 + 1]) + printdate "$PAYEE: Sending fiat payment sent message to seller in $RANDOM_WAIT seconds..." + sleeptraced "$RANDOM_WAIT" + CMD="$CLI_BASE --port=$PORT confirmpaymentreceived --trade-id=$OFFER_ID" + printdate "$PAYEE_CLI: $CMD" + RCVD_MSG=$($CMD) + commandalert $? "Could not send confirmpaymentstarted message." + # Print the confirmpaymentstarted command's console output. + printdate "$RCVD_MSG" + printbreak +} + +# This is a large function that should be broken up if it ever makes sense to not treat a trade +# execution simulation as an atomic operation. But we are not testing api methods here, just +# demonstrating how to use them to get through the trade protocol. It should work for any trade +# between Bob & Alice, as long as Alice is maker, Bob is taker, and the offer to be taken is the +# first displayed in Bob's getoffers command output. +executetrade() { + # Bob list available offers. + printdate "BOB $BOB_ROLE: 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" + printbreak + + OFFER_ID=$(getfirstofferid "$BOB_PORT") + exitoncommandalert $? + printdate "First offer found: $OFFER_ID" + + # Take Alice's offer. + 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." + # Print the takeoffer command's console output. + printdate "$TRADE" + printbreak + + waitfortradedepositpublished "$OFFER_ID" + waitfortradedepositconfirmed "$OFFER_ID" + + # 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 + + # Asynchronously send a confirm payment started message after a random delay. + delayconfirmpaymentstarted "$PAYER" "$PAYER_PORT" "$OFFER_ID" & + + if [ "$DIRECTION" = "BUY" ] + then + # Bob waits for payment, polling status in taker specific trade detail. + waitfortradepaymentsent "$PAYEE_PORT" "$PAYEE" "$OFFER_ID" "TAKER" + else + # Alice waits for payment, polling status in maker specific trade detail. + waitfortradepaymentsent "$PAYEE_PORT" "$PAYEE" "$OFFER_ID" "MAKER" + fi + + + # Asynchronously send a confirm payment received message after a random delay. + delayconfirmpaymentreceived "$PAYEE" "$PAYEE_PORT" "$OFFER_ID" & + + if [ "$DIRECTION" = "BUY" ] + then + # Alice waits for payment rcvd confirm from Bob, polling status in maker specific trade detail. + waitfortradepaymentreceived "$PAYER_PORT" "$PAYER" "$OFFER_ID" "MAKER" + else + # Bob waits for payment rcvd confirm from Alice, polling status in taker specific trade detail. + waitfortradepaymentreceived "$PAYER_PORT" "$PAYER" "$OFFER_ID" "TAKER" + fi + + # Generate some btc blocks + printdate "Generating btc blocks after fiat transfer." + genbtcblocks 2 2 + printbreak + + # 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." + # Print the keepfunds command's console output. + printdate "$KEEP_FUNDS_MSG" + sleeptraced 3 + printbreak + + printdate "Trade $OFFER_ID complete." } getcurrentprice() { diff --git a/apitest/scripts/trade-simulation.sh b/apitest/scripts/trade-simulation.sh index 3928cbf4471..f37e2a6c4af 100755 --- a/apitest/scripts/trade-simulation.sh +++ b/apitest/scripts/trade-simulation.sh @@ -41,191 +41,77 @@ export APP_BASE_NAME=$(basename "$0") export APP_HOME=$(pwd -P) -export APITEST_SCRIPTS_HOME="${APP_HOME}/apitest/scripts" +export APITEST_SCRIPTS_HOME="$APP_HOME/apitest/scripts" -source "${APITEST_SCRIPTS_HOME}/trade-simulation-env.sh" -source "${APITEST_SCRIPTS_HOME}/trade-simulation-utils.sh" +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:" +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 +# Demonstrate how to create a country based, face to face account. +showcreatepaymentacctsteps "Alice" "$ALICE_PORT" -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" +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" 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" +export ALICE_ACCT_ID=$(getnewpaymentacctid "$CMD_OUTPUT") +export CURRENCY_CODE=$(getnewpaymentacctcurrency "$CMD_OUTPUT") +printdate "Alice's F2F payment-account-id: $ALICE_ACCT_ID, currency-code: $CURRENCY_CODE" +exitoncommandalert $? 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}." +printdate "Bob creates his F2F 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") +echo "$CMD_OUTPUT" 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}." +export BOB_ACCT_ID=$(getnewpaymentacctid "$CMD_OUTPUT") +export CURRENCY_CODE=$(getnewpaymentacctcurrency "$CMD_OUTPUT") +printdate "Bob's F2F payment-account-id: $BOB_ACCT_ID, currency-code: $CURRENCY_CODE" +exitoncommandalert $? 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") +# Alice creates an offer. +printdate "ALICE $ALICE_ROLE: Creating $DIRECTION $CURRENCY_CODE offer with payment acct $ALICE_ACCT_ID." +CURRENT_PRICE=$(getcurrentprice "$ALICE_PORT" "$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}") +CMD=$(gencreateoffercommand "$ALICE_PORT" "$ALICE_ACCT_ID") +printdate "ALICE CLI: $CMD" +OFFER_ID=$(createoffer "$CMD") exitoncommandalert $? -printdate "ALICE ${ALICE_ROLE}: Created offer with id: ${OFFER_ID}." +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}" +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}" +echo "$OFFER" printbreak -sleeptraced 7 +sleeptraced 3 # Generate some btc blocks. printdate "Generating btc blocks after publishing Alice's offer." -genbtcblocks 3 5 +genbtcblocks 3 1 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) +# Go through the trade protocol. +executetrade 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.