Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API XMR/BTC trading pair support (#6) #5893

Merged
merged 19 commits into from
Dec 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d57d6e9
Use calculated offer maker fee, do not re-calculate it
ghubstan Dec 1, 2021
e3c4089
Use offer instance to determine ownership, not it's id
ghubstan Dec 1, 2021
33d976c
Calculate offer.makerFee if offer is bsq-swap
ghubstan Dec 1, 2021
095a495
Add more readable toString method to MutableOfferPayloadFields
ghubstan Dec 2, 2021
b85459d
Refactor api.core side editoffer validation & fix bug
ghubstan Dec 2, 2021
ce8b6df
Adjust API CorePaymentAccountsService for creating XMR accts
ghubstan Dec 2, 2021
742a6f4
Allow mkt price lookup for any altcoin from API
ghubstan Dec 2, 2021
54f815e
Adjust API cli-side CryptoCurrencyUtil & OffersServiceRequest for XMR…
ghubstan Dec 2, 2021
03b5791
Make altcoin offer sorting method names more generic
ghubstan Dec 2, 2021
a45c5fa
Adjust CLI opts parsers & opt parsing test for XMR support
ghubstan Dec 2, 2021
743ef93
Test API XMR support
ghubstan Dec 2, 2021
65fb8e8
Add CliMain.main(args) tests
ghubstan Dec 2, 2021
f867f6b
Add new regtest apitest/scripts/trade-xmr-simulation.sh
ghubstan Dec 2, 2021
e2647af
Add a few more checks on editedOffer.getUseMarketBasedPrice()
ghubstan Dec 2, 2021
104f11a
Do not run 2x from gradle terminal cmd
ghubstan Dec 2, 2021
0f32fe2
Merge branch '5-api-bsqswap-simulation-n-docs-update' into 6-api-xmr-…
ghubstan Dec 3, 2021
5f7fd62
Merge branch 'master' into 6-api-xmr-trading
ghubstan Dec 3, 2021
98b41cb
Use string in BigDecimal ctor, and make codacy happy too
ghubstan Dec 3, 2021
705e34e
Merge branch 'master' into 6-api-xmr-trading
ghubstan Dec 15, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions apitest/scripts/trade-simulation-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,51 @@ parsebsqswaporderopts() {
export CURRENCY_CODE="BSQ"
}

parsexmrscriptopts() {
usage() {
echo "Usage: $0 [-d buy|sell] [-f <fixed-price> || -m <margin-from-price>] [-a <amount in btc>]" 1>&2
exit 1;
}

local OPTIND o d f m a
while getopts "d:f:m:a:" o; do
case "${o}" in
d) d=$(echo "${OPTARG}" | tr '[:lower:]' '[:upper:]')
((d == "BUY" || d == "SELL")) || usage
export DIRECTION=${d}
;;
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 "${a}" ]; then
usage
fi

if [ -z "${f}" ] && [ -z "${m}" ]; then
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
}

checkbitcoindrunning() {
# There may be a '+' char in the path and we have to escape it for pgrep.
if [[ $APP_HOME == *"+"* ]]; then
Expand Down
10 changes: 5 additions & 5 deletions apitest/scripts/trade-simulation-utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ waitfortradepaymentsent() {

IS_TRADE_PAYMENT_SENT=$(istradepaymentsent "$TRADE_DETAIL")
exitoncommandalert $?
printdate "$SELLER: Has buyer's fiat payment been initiated? $IS_TRADE_PAYMENT_SENT"
printdate "$SELLER: Has buyer's payment been initiated? $IS_TRADE_PAYMENT_SENT"
if [ "$IS_TRADE_PAYMENT_SENT" = "YES" ]
then
DONE=1
Expand Down Expand Up @@ -407,7 +407,7 @@ waitfortradepaymentreceived() {
# but we do not need to simulate that in this regtest script.
IS_TRADE_PAYMENT_SENT=$(istradepaymentreceived "$TRADE_DETAIL")
exitoncommandalert $?
printdate "$SELLER: Has buyer's payment been transferred to seller's fiat account? $IS_TRADE_PAYMENT_SENT"
printdate "$SELLER: Has buyer's payment been transferred to seller's account? $IS_TRADE_PAYMENT_SENT"
if [ "$IS_TRADE_PAYMENT_SENT" = "YES" ]
then
DONE=1
Expand All @@ -427,7 +427,7 @@ delayconfirmpaymentstarted() {
PORT="$2"
OFFER_ID="$3"
RANDOM_WAIT=$(echo $[$RANDOM % 5 + 1])
printdate "$PAYER: Sending fiat payment sent message to seller in $RANDOM_WAIT seconds..."
printdate "$PAYER: Sending '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"
Expand All @@ -446,7 +446,7 @@ delayconfirmpaymentreceived() {
PORT="$2"
OFFER_ID="$3"
RANDOM_WAIT=$(echo $[$RANDOM % 5 + 1])
printdate "$PAYEE: Sending fiat payment sent message to seller in $RANDOM_WAIT seconds..."
printdate "$PAYEE: Sending '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"
Expand Down Expand Up @@ -531,7 +531,7 @@ executetrade() {
fi

# Generate some btc blocks
printdate "Generating btc blocks after fiat transfer."
printdate "Generating btc blocks after payment."
genbtcblocks 2 2
printbreak

Expand Down
122 changes: 122 additions & 0 deletions apitest/scripts/trade-xmr-simulation.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#! /bin/bash

# Runs xmr <-> btc trading scenarios using the API CLI with a local regtest bitcoin node.
#
# Prerequisites:
#
# - Linux or OSX with bash, Java 11-15 (JDK language compatibility 11), and bitcoin-core (v0.19 - v22).
#
# - 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`
#
# Usage:
#
# This script must be run from the root of the project, e.g.:
#
# `$ apitest/scripts/trade-xmr-simulation.sh -d buy -f 0.05 -a 0.125`
#
# Script options: -d <direction> -m <mkt-price-margin(%)> -f <fixed-price> -a <amount(btc)>
#
# Examples:
#
# Create a buy/xmr offer to buy 0.125 btc at an xmr fixed-price of 0.05 btc, using an xmr payment account:
#
# `$ apitest/scripts/trade-xmr-simulation.sh -d buy -f 0.05 -a 0.125`
#
# Create a sell/xmr offer to sell 0.125 btc at at an xmr mkt-price-margin of 0%, using using an xmr payment account:
#
# `$ apitest/scripts/trade-xmr-simulation.sh -d sell -m 0.00 -a 0.125`

export APP_BASE_NAME=$(basename "$0")
export APP_HOME=$(pwd -P)
export APITEST_SCRIPTS_HOME="$APP_HOME/apitest/scripts"
export CURRENCY_CODE="XMR"
export ALICE_XMR_ADDRESS="44i8xZbd8ecaD6nQQrHjr1BwTp6QfGL22iWqHZKmU4QYSyr1F64XAxM4HgvQHxbny7ehfxemaA9LPDLz2wY3fxhB1bbMEco"
export BOB_XMR_ADDRESS="48xdBkXaCosPxcWwXRZdSGc33M9tYu6k9ga56dqkNrgsjQuJX16xW2qTyWTZstJpXXj87dj5p4H3y1xAfoVjAysoAYrXh2N"

source "$APITEST_SCRIPTS_HOME/trade-simulation-env.sh"
source "$APITEST_SCRIPTS_HOME/trade-simulation-utils.sh"

checksetup
parsexmrscriptopts "$@"

printdate "Started $APP_BASE_NAME with parameters:"
printscriptparams
printbreak

registerdisputeagents

# Demonstrate how to create an XMR altcoin payment account.

printdate "Create Alice's XMR Trading Payment Account."
# Note: Having problems passing a double quoted --account-name param to function.
CMD="$CLI_BASE --port=$ALICE_PORT createcryptopaymentacct --account-name=Alice_XMR_Account"
CMD+=" --currency-code=XMR --address=$ALICE_XMR_ADDRESS --trade-instant=false"
printdate "ALICE CLI: $CMD"
CMD_OUTPUT=$(createpaymentacct "$CMD")
echo "$CMD_OUTPUT"
printbreak
export ALICE_ACCT_ID=$(getnewpaymentacctid "$CMD_OUTPUT")
printdate "Alice's XMR payment-account-id: $ALICE_ACCT_ID"
exitoncommandalert $?
printbreak

printdate "Create Bob's XMR Trading Payment Account."
# Note: Having problems passing a double quoted --account-name param to function.
CMD="$CLI_BASE --port=$BOB_PORT createcryptopaymentacct --account-name=Bob_XMR_Account"
CMD+=" --currency-code=XMR --address=$BOB_XMR_ADDRESS --trade-instant=false"
printdate "BOB CLI: $CMD"
CMD_OUTPUT=$(createpaymentacct "$CMD")
echo "$CMD_OUTPUT"
printbreak
export BOB_ACCT_ID=$(getnewpaymentacctid "$CMD_OUTPUT")
printdate "Bob's XMR payment-account-id: $BOB_ACCT_ID"
exitoncommandalert $?
printbreak

# Alice creates an offer.
printdate "ALICE $ALICE_ROLE: Creating $DIRECTION $CURRENCY_CODE offer with payment acct $ALICE_ACCT_ID."
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 1
printbreak

# Go through the trade protocol.
executetrade
exitoncommandalert $?
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
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

import static bisq.apitest.Scaffold.BitcoinCoreApp.bitcoind;
import static bisq.apitest.config.ApiTestConfig.BSQ;
import static bisq.apitest.config.ApiTestConfig.XMR;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.apitest.config.BisqAppConfig.arbdaemon;
import static bisq.apitest.config.BisqAppConfig.bobdaemon;
Expand Down Expand Up @@ -65,6 +66,9 @@ public abstract class AbstractOfferTest extends MethodTest {
protected static PaymentAccount alicesLegacyBsqAcct;
protected static PaymentAccount bobsLegacyBsqAcct;

protected static PaymentAccount alicesXmrAcct;
protected static PaymentAccount bobsXmrAcct;

@BeforeAll
public static void setUp() {
startSupportingApps(true,
Expand Down Expand Up @@ -96,11 +100,16 @@ public static void setUp() {
return priceAsBigDecimal.multiply(factor).longValue();
};

protected final BiFunction<Double, Double, Long> calcPriceAsLong = (base, delta) -> {
protected final BiFunction<Double, Double, Long> calcFiatTriggerPriceAsLong = (base, delta) -> {
var priceAsDouble = new BigDecimal(base).add(new BigDecimal(delta)).doubleValue();
return Double.valueOf(exactMultiply(priceAsDouble, 10_000)).longValue();
};

protected final BiFunction<Double, Double, Long> calcAltcoinTriggerPriceAsLong = (base, delta) -> {
var priceAsDouble = new BigDecimal(base).add(new BigDecimal(delta)).doubleValue();
return Double.valueOf(exactMultiply(priceAsDouble, 100_000_000)).longValue();
};

protected final BiFunction<Double, Double, String> calcPriceAsString = (base, delta) -> {
var priceAsBigDecimal = new BigDecimal(Double.toString(base))
.add(new BigDecimal(Double.toString(delta)));
Expand All @@ -113,6 +122,7 @@ public static void setUp() {
protected final Function<List<OfferInfo>, String> toOffersTable = (offers) ->
new TableBuilder(OFFER_TBL, offers).build().toString();

@SuppressWarnings("ConstantConditions")
public static void initSwapPaymentAccounts() {
// A bot may not know what the default 'BSQ Swap' account name is,
// but API test cases do: the value of the i18n property 'BSQ_SWAP'.
Expand All @@ -132,6 +142,20 @@ public static void createLegacyBsqPaymentAccounts() {
false);
}

@SuppressWarnings("ConstantConditions")
public static void createXmrPaymentAccounts() {
alicesXmrAcct = aliceClient.createCryptoCurrencyPaymentAccount("Alice's XMR Account",
XMR,
"44G4jWmSvTEfifSUZzTDnJVLPvYATmq9XhhtDqUof1BGCLceG82EQsVYG9Q9GN4bJcjbAJEc1JD1m5G7iK4UPZqACubV4Mq",
false);
log.debug("Alices XMR Account: {}", alicesXmrAcct);
bobsXmrAcct = bobClient.createCryptoCurrencyPaymentAccount("Bob's XMR Account",
XMR,
"4BDRhdSBKZqAXs3PuNTbMtaXBNqFj5idC2yMVnQj8Rm61AyKY8AxLTt9vGRJ8pwcG4EtpyD8YpGqdZWCZ2VZj6yVBN2RVKs",
false);
log.debug("Bob's XMR Account: {}", bobsXmrAcct);
}

@AfterAll
public static void tearDown() {
tearDownScaffold();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ public void testCreateSellBTCFor5To10KBSQOffer() {
@Test
@Order(5)
public void testGetAllMyBsqOffers() {
List<OfferInfo> offers = aliceClient.getMyBsqOffersSortedByDate();
List<OfferInfo> offers = aliceClient.getMyCryptoCurrencyOffersSortedByDate(BSQ);
log.debug("ALL ALICE'S BSQ OFFERS:\n{}", toOffersTable.apply(offers));
assertEquals(4, offers.size());
log.debug("ALICE'S BALANCES\n{}", formatBalancesTbls(aliceClient.getBalances()));
Expand All @@ -254,7 +254,7 @@ public void testGetAllMyBsqOffers() {
@Test
@Order(6)
public void testGetAvailableBsqOffers() {
List<OfferInfo> offers = bobClient.getBsqOffersSortedByDate();
List<OfferInfo> offers = bobClient.getCryptoCurrencyOffersSortedByDate(BSQ);
log.debug("ALL BOB'S AVAILABLE BSQ OFFERS:\n{}", toOffersTable.apply(offers));
assertEquals(4, offers.size());
log.debug("BOB'S BALANCES\n{}", formatBalancesTbls(bobClient.getBalances()));
Expand Down
Loading