mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 15:00:30 +01:00
Merge pull request #5876 from ghubstan/5-api-bsqswap-simulation-n-docs-update
API BSQ swap simulation script and doc updates #5
This commit is contained in:
commit
cf81fd451c
62 changed files with 2447 additions and 1605 deletions
|
@ -17,9 +17,9 @@ option adjustments to compensate.
|
||||||
|
|
||||||
**Shell**: Bash
|
**Shell**: Bash
|
||||||
|
|
||||||
**Java SDK**: Version 10, 11, 12 or 15
|
**Java SDK**: Version 11 - 15 (src and class generation version 11)
|
||||||
|
|
||||||
**Bitcoin-Core**: Version 0.19, 0.20, or 0.21
|
**Bitcoin-Core**: Version 0.19 - 22
|
||||||
|
|
||||||
**Git Client**
|
**Git Client**
|
||||||
|
|
||||||
|
@ -372,6 +372,22 @@ The `trade-simulation.sh` script options that would generate the previous `creat
|
||||||
$ apitest/scripts/trade-simulation.sh -d sell -c jp -m 0.5 -a 0.125
|
$ apitest/scripts/trade-simulation.sh -d sell -c jp -m 0.5 -a 0.125
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The `createoffer` command can also be used to create BSQ swap offers, where trade execution is performed immediately
|
||||||
|
after a BSQ swap offer is taken. To swap 0.5 BTC for BSQ at a price of 0.00005 BSQ per 1 BTC:
|
||||||
|
```
|
||||||
|
$ ./bisq-cli --password=xyz --port=9998 createoffer \
|
||||||
|
--swap=true \
|
||||||
|
--direction=BUY \
|
||||||
|
--amount=0.5 \
|
||||||
|
--currency-code=BSQ \
|
||||||
|
--fixed-price=0.00005
|
||||||
|
```
|
||||||
|
|
||||||
|
The `bsqswap-simulation.sh` script options that would generate the previous `createoffer` example is:
|
||||||
|
```
|
||||||
|
$ apitest/scripts/bsqswap-simulation.sh -d buy -a 0.5 -f 0.00005
|
||||||
|
```
|
||||||
|
|
||||||
### Browsing Your Own Offers
|
### Browsing Your Own Offers
|
||||||
|
|
||||||
There are different commands to browse available offers you can take, and offers you created.
|
There are different commands to browse available offers you can take, and offers you created.
|
||||||
|
@ -530,7 +546,7 @@ A CLI user browses available offers with the getoffers command. For example, th
|
||||||
$ ./bisq-cli --password=xyz --port=9998 getoffers --direction=SELL --currency-code=EUR
|
$ ./bisq-cli --password=xyz --port=9998 getoffers --direction=SELL --currency-code=EUR
|
||||||
```
|
```
|
||||||
|
|
||||||
And takes one of the available offers with an EUR payment account ( id `fe20cdbd-22be-4b8a-a4b6-d2608ff09d6e`)
|
Then takes one of the available offers with an EUR payment account ( id `fe20cdbd-22be-4b8a-a4b6-d2608ff09d6e`)
|
||||||
with the `takeoffer` command:
|
with the `takeoffer` command:
|
||||||
```
|
```
|
||||||
$ ./bisq-cli --password=xyz --port=9998 takeoffer \
|
$ ./bisq-cli --password=xyz --port=9998 takeoffer \
|
||||||
|
@ -538,8 +554,10 @@ $ ./bisq-cli --password=xyz --port=9998 takeoffer \
|
||||||
--payment-account=fe20cdbd-22be-4b8a-a4b6-d2608ff09d6e \
|
--payment-account=fe20cdbd-22be-4b8a-a4b6-d2608ff09d6e \
|
||||||
--fee-currency=btc
|
--fee-currency=btc
|
||||||
```
|
```
|
||||||
The taken offer will be used to create a trade contract. The next section describes how to use the Api to execute
|
Depending on the offer type, the taken offer will be used to (1) create a trade contract, or (2) execute a BSQ swap.
|
||||||
the trade.
|
|
||||||
|
The next section describes how to use the Api to execute a trade. The following <b>Completing a BSQ Swap Trade</b>
|
||||||
|
section explains how to use the `takeoffer` command to complete a BSQ swap.
|
||||||
|
|
||||||
### Completing Trade Protocol
|
### Completing Trade Protocol
|
||||||
|
|
||||||
|
@ -598,6 +616,14 @@ $ ./bisq-cli --password=xyz --port=9998 keepfunds --trade-id=<trade-id>
|
||||||
$ ./bisq-cli --password=xyz --port=9999 withdrawfunds --trade-id=<trade-id> --address=<btc-address> [--memo=<"memo">]
|
$ ./bisq-cli --password=xyz --port=9999 withdrawfunds --trade-id=<trade-id> --address=<btc-address> [--memo=<"memo">]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Completing a BSQ Swap Trade
|
||||||
|
|
||||||
|
The `takeoffer` command will immediately perform the BSQ swap, assuming both sides' wallets have sufficient BTC and
|
||||||
|
BSQ to cover the trade amount, and maker or taker fee. It takes one argument: `--offer-id=<offer-id>`:
|
||||||
|
```
|
||||||
|
$ ./bisq-cli --password=xyz --port=9998 takeoffer --offer-id=Xge8b2e2-51b6-3TOOB-z748-3ebd29c2kj99
|
||||||
|
```
|
||||||
|
|
||||||
## Shutting Down Test Harness
|
## Shutting Down Test Harness
|
||||||
|
|
||||||
The test harness should cleanly shutdown all the background apps in proper order after entering ^C.
|
The test harness should cleanly shutdown all the background apps in proper order after entering ^C.
|
||||||
|
|
|
@ -4,7 +4,7 @@ The Java based API runs on Linux and OSX.
|
||||||
|
|
||||||
## Mainnet
|
## Mainnet
|
||||||
|
|
||||||
To build from the source, clone the github repository found at `https://github.com/bisq-network/bisq`,
|
To build from the source, clone the GitHub repository found at `https://github.com/bisq-network/bisq`,
|
||||||
and build with gradle:
|
and build with gradle:
|
||||||
|
|
||||||
$ ./gradlew clean build
|
$ ./gradlew clean build
|
||||||
|
|
79
apitest/scripts/bsqswap-simulation-utils.sh
Executable file
79
apitest/scripts/bsqswap-simulation-utils.sh
Executable file
|
@ -0,0 +1,79 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
# This file must be sourced by the driver script.
|
||||||
|
|
||||||
|
source "$APITEST_SCRIPTS_HOME/trade-simulation-env.sh"
|
||||||
|
source "$APITEST_SCRIPTS_HOME/trade-simulation-utils.sh"
|
||||||
|
|
||||||
|
gencreatebsqswapoffercommand() {
|
||||||
|
PORT="$1"
|
||||||
|
CMD="$CLI_BASE --port=$PORT createoffer"
|
||||||
|
CMD+=" --swap=true"
|
||||||
|
CMD+=" --direction=$DIRECTION"
|
||||||
|
CMD+=" --amount=$AMOUNT"
|
||||||
|
CMD+=" --fixed-price=$FIXED_PRICE"
|
||||||
|
CMD+=" --currency-code=$CURRENCY_CODE"
|
||||||
|
echo "$CMD"
|
||||||
|
}
|
||||||
|
|
||||||
|
createbsqswapoffer() {
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
executebsqswap() {
|
||||||
|
# Bob list available BSQ offers. (If a v1 BSQ offer is picked this simulation will break.)
|
||||||
|
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"
|
||||||
|
printbreak
|
||||||
|
|
||||||
|
OFFER_ID=$(getfirstofferid "$BOB_PORT")
|
||||||
|
exitoncommandalert $?
|
||||||
|
printdate "First BSQ offer found: $OFFER_ID"
|
||||||
|
|
||||||
|
# Take Alice's BSQ swap offer.
|
||||||
|
CMD="$CLI_BASE --port=$BOB_PORT takeoffer --offer-id=$OFFER_ID"
|
||||||
|
printdate "BOB CLI: $CMD"
|
||||||
|
TRADE=$($CMD)
|
||||||
|
commandalert $? "Could not take BSQ swap offer."
|
||||||
|
# Print the takeoffer command's console output.
|
||||||
|
printdate "$TRADE"
|
||||||
|
printbreak
|
||||||
|
|
||||||
|
# Generate 1 btc block
|
||||||
|
printdate "Generating 1 btc block after BSQ swap execution."
|
||||||
|
genbtcblocks 1 2
|
||||||
|
printbreak
|
||||||
|
|
||||||
|
printdate "BSQ swap trade $OFFER_ID complete."
|
||||||
|
printbreak
|
||||||
|
|
||||||
|
printdate "Alice looking at her trade with id $OFFER_ID."
|
||||||
|
CMD="$CLI_BASE --port=$ALICE_PORT gettrade --trade-id=$OFFER_ID"
|
||||||
|
printdate "ALICE CLI: $CMD"
|
||||||
|
GETTRADE_CMD_OUTPUT=$(gettrade "$CMD")
|
||||||
|
exitoncommandalert $?
|
||||||
|
echo "$GETTRADE_CMD_OUTPUT"
|
||||||
|
printbreak
|
||||||
|
|
||||||
|
printdate "Bob 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
|
||||||
|
}
|
||||||
|
|
90
apitest/scripts/bsqswap-simulation.sh
Executable file
90
apitest/scripts/bsqswap-simulation.sh
Executable file
|
@ -0,0 +1,90 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
# Demonstrates a bsq <-> btc swap trade 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/bsqswap-simulation.sh -d buy -f 0.00005 -a 0.125`
|
||||||
|
#
|
||||||
|
# Script options: -d <direction> -c <country-code> -f <fixed-price> -a <amount(btc)>
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
#
|
||||||
|
# Create and take a bsq swap offer to buy 0.05 btc at a fixed-price of 0.00005 bsq (per 1 btc):
|
||||||
|
#
|
||||||
|
# `$ apitest/scripts/bsqswap-simulation.sh -d buy -a 0.05 -f 0.00005`
|
||||||
|
#
|
||||||
|
# Create and take a bsq swap offer to buy 1 btc at a fixed-price of 0.00005 bsq (per 1 btc):
|
||||||
|
#
|
||||||
|
# `$ apitest/scripts/bsqswap-simulation.sh -d buy -a 1 -f 0.0005`
|
||||||
|
|
||||||
|
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"
|
||||||
|
source "$APITEST_SCRIPTS_HOME/bsqswap-simulation-utils.sh"
|
||||||
|
|
||||||
|
checksetup
|
||||||
|
parsebsqswaporderopts "$@"
|
||||||
|
|
||||||
|
printdate "Started $APP_BASE_NAME with parameters:"
|
||||||
|
printbsqswapscriptparams
|
||||||
|
printbreak
|
||||||
|
|
||||||
|
# Alice creates a bsq swap offer.
|
||||||
|
printdate "Alice creating BSQ swap offer: $DIRECTION $AMOUNT BTC for BSQ at fixed price of $FIXED_PRICE BTC per 1 BSQ."
|
||||||
|
CMD=$(gencreatebsqswapoffercommand "$ALICE_PORT" "$ALICE_ACCT_ID")
|
||||||
|
printdate "ALICE CLI: $CMD"
|
||||||
|
OFFER_ID=$(createbsqswapoffer "$CMD")
|
||||||
|
exitoncommandalert $?
|
||||||
|
printdate "Alice created bsq swap offer with id: $OFFER_ID."
|
||||||
|
printbreak
|
||||||
|
sleeptraced 2
|
||||||
|
|
||||||
|
# Show Alice's new bsq swap 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 2
|
||||||
|
|
||||||
|
# Generate 1 btc block.
|
||||||
|
printdate "Generating 1 btc block after publishing Alice's offer."
|
||||||
|
genbtcblocks 1 1
|
||||||
|
printbreak
|
||||||
|
|
||||||
|
# Execute the BSQ swap.
|
||||||
|
executebsqswap
|
||||||
|
exitoncommandalert $?
|
||||||
|
printbreak
|
||||||
|
|
||||||
|
# Get balances after trade completion.
|
||||||
|
printdate "Bob & Alice's balances after BSQ swap trade."
|
||||||
|
printdate "ALICE CLI:"
|
||||||
|
printbalances "$ALICE_PORT"
|
||||||
|
printbreak
|
||||||
|
printdate "BOB CLI:"
|
||||||
|
printbalances "$BOB_PORT"
|
||||||
|
printbreak
|
||||||
|
|
||||||
|
exit 0
|
|
@ -6,7 +6,7 @@
|
||||||
#
|
#
|
||||||
# Prerequisites:
|
# Prerequisites:
|
||||||
#
|
#
|
||||||
# - Linux or OSX with bash, Java 10, or Java 11-12 (JDK language compatibility 10), and bitcoin-core (v0.19, v0.20, v0.21).
|
# - 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.
|
# - Bisq must be fully built with apitest dao setup files installed.
|
||||||
# Build command: `./gradlew clean build :apitest:installDaoSetup`
|
# Build command: `./gradlew clean build :apitest:installDaoSetup`
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# Prerequisites:
|
# Prerequisites:
|
||||||
#
|
#
|
||||||
# - Linux or OSX with bash, Java 10, or Java 11-12 (JDK language compatibility 10), and bitcoin-core (v0.19, v0.20, v0.21).
|
# - 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.
|
# - Bisq must be fully built with apitest dao setup files installed.
|
||||||
# Build command: `./gradlew clean build :apitest:installDaoSetup`
|
# Build command: `./gradlew clean build :apitest:installDaoSetup`
|
||||||
|
|
|
@ -179,6 +179,41 @@ parselimitorderopts() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parsebsqswaporderopts() {
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $0 [-d buy|sell] [-f <fixed-price>] [-a <amount in btc>]" 1>&2
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
local OPTIND o d f a
|
||||||
|
while getopts "d:f: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}
|
||||||
|
;;
|
||||||
|
a) a=${OPTARG}
|
||||||
|
export AMOUNT=${a}
|
||||||
|
;;
|
||||||
|
*) usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
if [ -z "${d}" ] || [ -z "${a}" ]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${f}" ] ; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
export CURRENCY_CODE="BSQ"
|
||||||
|
}
|
||||||
|
|
||||||
checkbitcoindrunning() {
|
checkbitcoindrunning() {
|
||||||
# There may be a '+' char in the path and we have to escape it for pgrep.
|
# There may be a '+' char in the path and we have to escape it for pgrep.
|
||||||
if [[ $APP_HOME == *"+"* ]]; then
|
if [[ $APP_HOME == *"+"* ]]; then
|
||||||
|
@ -310,3 +345,9 @@ printscriptparams() {
|
||||||
echo " WAIT = $WAIT"
|
echo " WAIT = $WAIT"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printbsqswapscriptparams() {
|
||||||
|
echo " DIRECTION = $DIRECTION"
|
||||||
|
echo " FIXED_PRICE = $FIXED_PRICE"
|
||||||
|
echo " AMOUNT = $AMOUNT"
|
||||||
|
}
|
||||||
|
|
|
@ -457,11 +457,10 @@ delayconfirmpaymentreceived() {
|
||||||
printbreak
|
printbreak
|
||||||
}
|
}
|
||||||
|
|
||||||
# This is a large function that should be broken up if it ever makes sense to not treat a trade
|
# This is a large function that might be split into smaller functions. But we are not testing
|
||||||
# execution simulation as an bsq swap operation. But we are not testing api methods here, just
|
# api methods here, just demonstrating how to use them to get through the V1 trade protocol with
|
||||||
# demonstrating how to use them to get through the trade protocol. It should work for any trade
|
# the CLI. It should work for any trade between Bob & Alice, as long as Alice is maker, Bob is
|
||||||
# between Bob & Alice, as long as Alice is maker, Bob is taker, and the offer to be taken is the
|
# taker, and the offer to be taken is the first displayed in Bob's getoffers command output.
|
||||||
# first displayed in Bob's getoffers command output.
|
|
||||||
executetrade() {
|
executetrade() {
|
||||||
# Bob list available offers.
|
# Bob list available offers.
|
||||||
printdate "BOB $BOB_ROLE: Looking at $DIRECTION $CURRENCY_CODE offers."
|
printdate "BOB $BOB_ROLE: Looking at $DIRECTION $CURRENCY_CODE offers."
|
||||||
|
@ -477,7 +476,7 @@ executetrade() {
|
||||||
printdate "First offer found: $OFFER_ID"
|
printdate "First offer found: $OFFER_ID"
|
||||||
|
|
||||||
# Take Alice's offer.
|
# Take Alice's offer.
|
||||||
CMD="$CLI_BASE --port=$BOB_PORT takeoffer --offer-id=$OFFER_ID --payment-account=$BOB_ACCT_ID --fee-currency=bsq"
|
CMD="$CLI_BASE --port=$BOB_PORT takeoffer --offer-id=$OFFER_ID --payment-account=$BOB_ACCT_ID --fee-currency=BSQ"
|
||||||
printdate "BOB CLI: $CMD"
|
printdate "BOB CLI: $CMD"
|
||||||
TRADE=$($CMD)
|
TRADE=$($CMD)
|
||||||
commandalert $? "Could not take offer."
|
commandalert $? "Could not take offer."
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
|
|
||||||
# Runs fiat <-> btc trading scenarios using the API CLI with a local regtest bitcoin node.
|
# Demonstrates a fiat <-> btc trade 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
|
# 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.
|
# trade, and the maker's face to face payment account's currency code is used when creating the offer.
|
||||||
#
|
#
|
||||||
# Prerequisites:
|
# Prerequisites:
|
||||||
#
|
#
|
||||||
# - Linux or OSX with bash, Java 10, or Java 11-12 (JDK language compatibility 10), and bitcoin-core (v0.19, v0.20, or v0.21).
|
# - 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.
|
# - Bisq must be fully built with apitest dao setup files installed.
|
||||||
# Build command: `./gradlew clean build :apitest:installDaoSetup`
|
# Build command: `./gradlew clean build :apitest:installDaoSetup`
|
||||||
|
@ -26,15 +26,16 @@
|
||||||
#
|
#
|
||||||
# `$ apitest/scripts/trade-simulation.sh -d buy -c fr -m 3.00 -a 0.125`
|
# `$ 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)>
|
# Script options: -d <direction> -c <country-code> -m <mkt-price-margin(%)> -f <fixed-price> -a <amount(btc)>
|
||||||
#
|
#
|
||||||
# Examples:
|
# 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:
|
# Create and take 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`
|
# `$ 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
|
# Create and take 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:
|
# payment account:
|
||||||
#
|
#
|
||||||
# `$ apitest/scripts/trade-simulation.sh -d sell -c fr -f 38000 -a 0.125`
|
# `$ apitest/scripts/trade-simulation.sh -d sell -c fr -f 38000 -a 0.125`
|
||||||
|
@ -53,8 +54,6 @@ printdate "Started $APP_BASE_NAME with parameters:"
|
||||||
printscriptparams
|
printscriptparams
|
||||||
printbreak
|
printbreak
|
||||||
|
|
||||||
registerdisputeagents
|
|
||||||
|
|
||||||
# Demonstrate how to create a country based, face to face account.
|
# Demonstrate how to create a country based, face to face account.
|
||||||
showcreatepaymentacctsteps "Alice" "$ALICE_PORT"
|
showcreatepaymentacctsteps "Alice" "$ALICE_PORT"
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ import bisq.apitest.config.ApiTestConfig;
|
||||||
*
|
*
|
||||||
* All method, scenario and end-to-end tests are found in the test sources folder.
|
* All method, scenario and end-to-end tests are found in the test sources folder.
|
||||||
*
|
*
|
||||||
* Requires bitcoind v0.19, v0.20, or v0.21.
|
* Requires bitcoind v0.19 - v22.
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ApiTestMain {
|
public class ApiTestMain {
|
||||||
|
|
|
@ -108,7 +108,7 @@ abstract class AbstractLinuxProcess implements LinuxProcess {
|
||||||
File bitcoindExecutable = Paths.get(config.bitcoinPath, "bitcoind").toFile();
|
File bitcoindExecutable = Paths.get(config.bitcoinPath, "bitcoind").toFile();
|
||||||
if (!bitcoindExecutable.exists() || !bitcoindExecutable.canExecute())
|
if (!bitcoindExecutable.exists() || !bitcoindExecutable.canExecute())
|
||||||
throw new IllegalStateException(format("'%s' cannot be found or executed.%n"
|
throw new IllegalStateException(format("'%s' cannot be found or executed.%n"
|
||||||
+ "A bitcoin-core v0.19, v0.20, or v0.21 installation is required," +
|
+ "A bitcoin-core v0.19 - v22 installation is required," +
|
||||||
" and the 'bitcoinPath' must be configured in 'apitest.properties'",
|
" and the 'bitcoinPath' must be configured in 'apitest.properties'",
|
||||||
bitcoindExecutable.getAbsolutePath()));
|
bitcoindExecutable.getAbsolutePath()));
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package bisq.apitest.method.offer;
|
package bisq.apitest.method.offer;
|
||||||
|
|
||||||
import bisq.proto.grpc.BsqSwapOfferInfo;
|
|
||||||
import bisq.proto.grpc.OfferInfo;
|
import bisq.proto.grpc.OfferInfo;
|
||||||
|
|
||||||
import protobuf.PaymentAccount;
|
import protobuf.PaymentAccount;
|
||||||
|
@ -42,10 +41,12 @@ import static bisq.apitest.config.BisqAppConfig.bobdaemon;
|
||||||
import static bisq.apitest.config.BisqAppConfig.seednode;
|
import static bisq.apitest.config.BisqAppConfig.seednode;
|
||||||
import static bisq.cli.table.builder.TableType.OFFER_TBL;
|
import static bisq.cli.table.builder.TableType.OFFER_TBL;
|
||||||
import static bisq.common.util.MathUtils.exactMultiply;
|
import static bisq.common.util.MathUtils.exactMultiply;
|
||||||
|
import static java.lang.System.out;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import bisq.apitest.method.MethodTest;
|
import bisq.apitest.method.MethodTest;
|
||||||
|
import bisq.cli.CliMain;
|
||||||
import bisq.cli.table.builder.TableBuilder;
|
import bisq.cli.table.builder.TableBuilder;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -112,11 +113,6 @@ public abstract class AbstractOfferTest extends MethodTest {
|
||||||
protected final Function<List<OfferInfo>, String> toOffersTable = (offers) ->
|
protected final Function<List<OfferInfo>, String> toOffersTable = (offers) ->
|
||||||
new TableBuilder(OFFER_TBL, offers).build().toString();
|
new TableBuilder(OFFER_TBL, offers).build().toString();
|
||||||
|
|
||||||
// TODO
|
|
||||||
protected final Function<BsqSwapOfferInfo, String> toBsqSwapOfferTable = (offer) ->
|
|
||||||
new TableBuilder(OFFER_TBL, offer).build().toString();
|
|
||||||
|
|
||||||
|
|
||||||
public static void initSwapPaymentAccounts() {
|
public static void initSwapPaymentAccounts() {
|
||||||
// A bot may not know what the default 'BSQ Swap' account name is,
|
// 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'.
|
// but API test cases do: the value of the i18n property 'BSQ_SWAP'.
|
||||||
|
@ -140,4 +136,11 @@ public abstract class AbstractOfferTest extends MethodTest {
|
||||||
public static void tearDown() {
|
public static void tearDown() {
|
||||||
tearDownScaffold();
|
tearDownScaffold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static void runCliGetOffer(String offerId) {
|
||||||
|
out.println("Alice's CLI 'getmyoffer' response:");
|
||||||
|
CliMain.main(new String[]{"--password=xyz", "--port=9998", "getmyoffer", "--offer-id=" + offerId});
|
||||||
|
out.println("Bob's CLI 'getoffer' response:");
|
||||||
|
CliMain.main(new String[]{"--password=xyz", "--port=9999", "getoffer", "--offer-id=" + offerId});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
package bisq.apitest.method.offer;
|
package bisq.apitest.method.offer;
|
||||||
|
|
||||||
import bisq.proto.grpc.BsqSwapOfferInfo;
|
import bisq.proto.grpc.OfferInfo;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@ -112,8 +112,7 @@ public class BsqSwapOfferTest extends AbstractOfferTest {
|
||||||
var bsqSwapOffer = aliceClient.createBsqSwapOffer(BUY.name(),
|
var bsqSwapOffer = aliceClient.createBsqSwapOffer(BUY.name(),
|
||||||
1_000_000L,
|
1_000_000L,
|
||||||
1_000_000L,
|
1_000_000L,
|
||||||
"0.00005",
|
"0.00005");
|
||||||
alicesBsqSwapAcct.getId());
|
|
||||||
log.debug("BsqSwap Sell BSQ (Buy BTC) OFFER:\n{}", bsqSwapOffer);
|
log.debug("BsqSwap Sell BSQ (Buy BTC) OFFER:\n{}", bsqSwapOffer);
|
||||||
var newOfferId = bsqSwapOffer.getId();
|
var newOfferId = bsqSwapOffer.getId();
|
||||||
assertNotEquals("", newOfferId);
|
assertNotEquals("", newOfferId);
|
||||||
|
@ -121,7 +120,6 @@ public class BsqSwapOfferTest extends AbstractOfferTest {
|
||||||
assertEquals(5_000, bsqSwapOffer.getPrice());
|
assertEquals(5_000, bsqSwapOffer.getPrice());
|
||||||
assertEquals(1_000_000L, bsqSwapOffer.getAmount());
|
assertEquals(1_000_000L, bsqSwapOffer.getAmount());
|
||||||
assertEquals(1_000_000L, bsqSwapOffer.getMinAmount());
|
assertEquals(1_000_000L, bsqSwapOffer.getMinAmount());
|
||||||
// assertEquals(alicesBsqAcct.getId(), atomicOffer.getMakerPaymentAccountId());
|
|
||||||
assertEquals(BSQ, bsqSwapOffer.getBaseCurrencyCode());
|
assertEquals(BSQ, bsqSwapOffer.getBaseCurrencyCode());
|
||||||
assertEquals(BTC, bsqSwapOffer.getCounterCurrencyCode());
|
assertEquals(BTC, bsqSwapOffer.getCounterCurrencyCode());
|
||||||
|
|
||||||
|
@ -129,13 +127,13 @@ public class BsqSwapOfferTest extends AbstractOfferTest {
|
||||||
testGetBsqSwapOffer(bsqSwapOffer);
|
testGetBsqSwapOffer(bsqSwapOffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testGetMyBsqSwapOffer(BsqSwapOfferInfo bsqSwapOfferInfo) {
|
private void testGetMyBsqSwapOffer(OfferInfo bsqSwapOffer) {
|
||||||
int numFetchAttempts = 0;
|
int numFetchAttempts = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
numFetchAttempts++;
|
numFetchAttempts++;
|
||||||
var fetchedBsqSwapOffer = aliceClient.getMyBsqSwapOffer(bsqSwapOfferInfo.getId());
|
var fetchedBsqSwapOffer = aliceClient.getMyOffer(bsqSwapOffer.getId());
|
||||||
assertEquals(bsqSwapOfferInfo.getId(), fetchedBsqSwapOffer.getId());
|
assertEquals(bsqSwapOffer.getId(), fetchedBsqSwapOffer.getId());
|
||||||
log.debug("Alice found her (my) new bsq swap offer on attempt # {}.", numFetchAttempts);
|
log.debug("Alice found her (my) new bsq swap offer on attempt # {}.", numFetchAttempts);
|
||||||
break;
|
break;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
@ -149,13 +147,13 @@ public class BsqSwapOfferTest extends AbstractOfferTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testGetBsqSwapOffer(BsqSwapOfferInfo bsqSwapOfferInfo) {
|
private void testGetBsqSwapOffer(OfferInfo bsqSwapOffer) {
|
||||||
int numFetchAttempts = 0;
|
int numFetchAttempts = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
numFetchAttempts++;
|
numFetchAttempts++;
|
||||||
var fetchedBsqSwapOffer = bobClient.getBsqSwapOffer(bsqSwapOfferInfo.getId());
|
var fetchedBsqSwapOffer = bobClient.getOffer(bsqSwapOffer.getId());
|
||||||
assertEquals(bsqSwapOfferInfo.getId(), fetchedBsqSwapOffer.getId());
|
assertEquals(bsqSwapOffer.getId(), fetchedBsqSwapOffer.getId());
|
||||||
log.debug("Bob found new available bsq swap offer on attempt # {}.", numFetchAttempts);
|
log.debug("Bob found new available bsq swap offer on attempt # {}.", numFetchAttempts);
|
||||||
break;
|
break;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
|
|
@ -38,15 +38,13 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
|
||||||
import static bisq.apitest.config.ApiTestConfig.BSQ;
|
import static bisq.apitest.config.ApiTestConfig.BSQ;
|
||||||
|
import static bisq.apitest.config.ApiTestConfig.BTC;
|
||||||
import static bisq.apitest.config.ApiTestConfig.EUR;
|
import static bisq.apitest.config.ApiTestConfig.EUR;
|
||||||
import static bisq.apitest.config.ApiTestConfig.USD;
|
import static bisq.apitest.config.ApiTestConfig.USD;
|
||||||
import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent;
|
import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent;
|
||||||
import static bisq.proto.grpc.EditOfferRequest.EditType.*;
|
import static bisq.proto.grpc.EditOfferRequest.EditType.*;
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static protobuf.OfferDirection.BUY;
|
import static protobuf.OfferDirection.BUY;
|
||||||
import static protobuf.OfferDirection.SELL;
|
import static protobuf.OfferDirection.SELL;
|
||||||
|
|
||||||
|
@ -70,22 +68,22 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
0.0,
|
0.0,
|
||||||
NO_TRIGGER_PRICE);
|
NO_TRIGGER_PRICE);
|
||||||
log.debug("ORIGINAL EUR OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original EUR offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
assertFalse(originalOffer.getIsActivated()); // Not activated until prep is done.
|
assertFalse(originalOffer.getIsActivated()); // Not activated until prep is done.
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
originalOffer = aliceClient.getMyOffer(originalOffer.getId());
|
originalOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
assertTrue(originalOffer.getIsActivated());
|
assertTrue(originalOffer.getIsActivated());
|
||||||
// Disable offer
|
// Disable offer
|
||||||
aliceClient.editOfferActivationState(originalOffer.getId(), DEACTIVATE_OFFER);
|
aliceClient.editOfferActivationState(originalOffer.getId(), DEACTIVATE_OFFER);
|
||||||
genBtcBlocksThenWait(1, 1500); // Wait for offer book removal.
|
genBtcBlocksThenWait(1, 1500); // Wait for offer book removal.
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED EUR OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited EUR offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
assertFalse(editedOffer.getIsActivated());
|
assertFalse(editedOffer.getIsActivated());
|
||||||
// Re-enable offer
|
// Re-enable offer
|
||||||
aliceClient.editOfferActivationState(editedOffer.getId(), ACTIVATE_OFFER);
|
aliceClient.editOfferActivationState(editedOffer.getId(), ACTIVATE_OFFER);
|
||||||
genBtcBlocksThenWait(1, 1500); // Wait for offer book re-entry.
|
genBtcBlocksThenWait(1, 1500); // Wait for offer book re-entry.
|
||||||
editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED EUR OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited EUR offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
assertTrue(editedOffer.getIsActivated());
|
assertTrue(editedOffer.getIsActivated());
|
||||||
|
|
||||||
doSanityCheck(originalOffer, editedOffer);
|
doSanityCheck(originalOffer, editedOffer);
|
||||||
|
@ -100,8 +98,8 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
0.0,
|
0.0,
|
||||||
NO_TRIGGER_PRICE);
|
NO_TRIGGER_PRICE);
|
||||||
log.debug("ORIGINAL EUR OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original EUR offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
originalOffer = aliceClient.getMyOffer(originalOffer.getId());
|
originalOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
assertEquals(0 /*no trigger price*/, originalOffer.getTriggerPrice());
|
assertEquals(0 /*no trigger price*/, originalOffer.getTriggerPrice());
|
||||||
|
|
||||||
|
@ -111,9 +109,9 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
var newTriggerPriceAsLong = calcPriceAsLong.apply(mktPrice, delta);
|
var newTriggerPriceAsLong = calcPriceAsLong.apply(mktPrice, delta);
|
||||||
|
|
||||||
aliceClient.editOfferTriggerPrice(originalOffer.getId(), newTriggerPriceAsLong);
|
aliceClient.editOfferTriggerPrice(originalOffer.getId(), newTriggerPriceAsLong);
|
||||||
sleep(2500); // Wait for offer book re-entry.
|
sleep(2_500); // Wait for offer book re-entry.
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED EUR OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited EUR offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
assertEquals(newTriggerPriceAsLong, editedOffer.getTriggerPrice());
|
assertEquals(newTriggerPriceAsLong, editedOffer.getTriggerPrice());
|
||||||
assertTrue(editedOffer.getUseMarketBasedPrice());
|
assertTrue(editedOffer.getUseMarketBasedPrice());
|
||||||
|
|
||||||
|
@ -124,13 +122,13 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
@Order(3)
|
@Order(3)
|
||||||
public void testSetTriggerPriceToNegativeValueShouldThrowException() {
|
public void testSetTriggerPriceToNegativeValueShouldThrowException() {
|
||||||
PaymentAccount paymentAcct = getOrCreatePaymentAccount("FI");
|
PaymentAccount paymentAcct = getOrCreatePaymentAccount("FI");
|
||||||
final OfferInfo originalOffer = createMktPricedOfferForEdit(SELL.name(),
|
var originalOffer = createMktPricedOfferForEdit(SELL.name(),
|
||||||
EUR,
|
EUR,
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
0.0,
|
0.0,
|
||||||
NO_TRIGGER_PRICE);
|
NO_TRIGGER_PRICE);
|
||||||
log.debug("ORIGINAL EUR OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original EUR offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
// Edit the offer's trigger price, set to -1, check error.
|
// Edit the offer's trigger price, set to -1, check error.
|
||||||
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
|
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
|
||||||
aliceClient.editOfferTriggerPrice(originalOffer.getId(), -1L));
|
aliceClient.editOfferTriggerPrice(originalOffer.getId(), -1L));
|
||||||
|
@ -145,19 +143,19 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
public void testEditMktPriceMargin() {
|
public void testEditMktPriceMargin() {
|
||||||
PaymentAccount paymentAcct = getOrCreatePaymentAccount("US");
|
PaymentAccount paymentAcct = getOrCreatePaymentAccount("US");
|
||||||
var originalMktPriceMargin = new BigDecimal("0.1").doubleValue();
|
var originalMktPriceMargin = new BigDecimal("0.1").doubleValue();
|
||||||
OfferInfo originalOffer = createMktPricedOfferForEdit(SELL.name(),
|
var originalOffer = createMktPricedOfferForEdit(SELL.name(),
|
||||||
USD,
|
USD,
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
originalMktPriceMargin,
|
originalMktPriceMargin,
|
||||||
NO_TRIGGER_PRICE);
|
NO_TRIGGER_PRICE);
|
||||||
log.debug("ORIGINAL USD OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin());
|
assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin());
|
||||||
// Edit the offer's price margin, nothing else.
|
// Edit the offer's price margin, nothing else.
|
||||||
var newMktPriceMargin = new BigDecimal("0.5").doubleValue();
|
var newMktPriceMargin = new BigDecimal("0.5").doubleValue();
|
||||||
aliceClient.editOfferPriceMargin(originalOffer.getId(), newMktPriceMargin);
|
aliceClient.editOfferPriceMargin(originalOffer.getId(), newMktPriceMargin);
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED USD OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited USD offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin());
|
assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin());
|
||||||
|
|
||||||
doSanityCheck(originalOffer, editedOffer);
|
doSanityCheck(originalOffer, editedOffer);
|
||||||
|
@ -169,19 +167,19 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
PaymentAccount paymentAcct = getOrCreatePaymentAccount("RU");
|
PaymentAccount paymentAcct = getOrCreatePaymentAccount("RU");
|
||||||
double mktPriceAsDouble = aliceClient.getBtcPrice(RUBLE);
|
double mktPriceAsDouble = aliceClient.getBtcPrice(RUBLE);
|
||||||
String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 200_000.0000);
|
String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 200_000.0000);
|
||||||
OfferInfo originalOffer = createFixedPricedOfferForEdit(BUY.name(),
|
var originalOffer = createFixedPricedOfferForEdit(BUY.name(),
|
||||||
RUBLE,
|
RUBLE,
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
fixedPriceAsString);
|
fixedPriceAsString);
|
||||||
log.debug("ORIGINAL RUB OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original RUB offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
// Edit the offer's fixed price, nothing else.
|
// Edit the offer's fixed price, nothing else.
|
||||||
String editedFixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 100_000.0000);
|
String editedFixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 100_000.0000);
|
||||||
aliceClient.editOfferFixedPrice(originalOffer.getId(), editedFixedPriceAsString);
|
aliceClient.editOfferFixedPrice(originalOffer.getId(), editedFixedPriceAsString);
|
||||||
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
||||||
genBtcBlocksThenWait(1, 2500);
|
genBtcBlocksThenWait(1, 2_500);
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED RUB OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited RUB offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
var expectedNewFixedPrice = scaledUpFiatOfferPrice.apply(new BigDecimal(editedFixedPriceAsString));
|
var expectedNewFixedPrice = scaledUpFiatOfferPrice.apply(new BigDecimal(editedFixedPriceAsString));
|
||||||
assertEquals(expectedNewFixedPrice, editedOffer.getPrice());
|
assertEquals(expectedNewFixedPrice, editedOffer.getPrice());
|
||||||
assertFalse(editedOffer.getUseMarketBasedPrice());
|
assertFalse(editedOffer.getUseMarketBasedPrice());
|
||||||
|
@ -195,12 +193,12 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
PaymentAccount paymentAcct = getOrCreatePaymentAccount("RU");
|
PaymentAccount paymentAcct = getOrCreatePaymentAccount("RU");
|
||||||
double mktPriceAsDouble = aliceClient.getBtcPrice(RUBLE);
|
double mktPriceAsDouble = aliceClient.getBtcPrice(RUBLE);
|
||||||
String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 200_000.0000);
|
String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 200_000.0000);
|
||||||
OfferInfo originalOffer = createFixedPricedOfferForEdit(BUY.name(),
|
var originalOffer = createFixedPricedOfferForEdit(BUY.name(),
|
||||||
RUBLE,
|
RUBLE,
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
fixedPriceAsString);
|
fixedPriceAsString);
|
||||||
log.debug("ORIGINAL RUB OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original RUB offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
// Edit the offer's fixed price and deactivate it.
|
// Edit the offer's fixed price and deactivate it.
|
||||||
String editedFixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 100_000.0000);
|
String editedFixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 100_000.0000);
|
||||||
aliceClient.editOffer(originalOffer.getId(),
|
aliceClient.editOffer(originalOffer.getId(),
|
||||||
|
@ -211,9 +209,9 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
DEACTIVATE_OFFER,
|
DEACTIVATE_OFFER,
|
||||||
FIXED_PRICE_AND_ACTIVATION_STATE);
|
FIXED_PRICE_AND_ACTIVATION_STATE);
|
||||||
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
||||||
genBtcBlocksThenWait(1, 2500);
|
genBtcBlocksThenWait(1, 2_500);
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED RUB OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited RUB offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
var expectedNewFixedPrice = scaledUpFiatOfferPrice.apply(new BigDecimal(editedFixedPriceAsString));
|
var expectedNewFixedPrice = scaledUpFiatOfferPrice.apply(new BigDecimal(editedFixedPriceAsString));
|
||||||
assertEquals(expectedNewFixedPrice, editedOffer.getPrice());
|
assertEquals(expectedNewFixedPrice, editedOffer.getPrice());
|
||||||
assertFalse(editedOffer.getIsActivated());
|
assertFalse(editedOffer.getIsActivated());
|
||||||
|
@ -232,8 +230,8 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
originalMktPriceMargin,
|
originalMktPriceMargin,
|
||||||
0);
|
0);
|
||||||
log.debug("ORIGINAL USD OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
originalOffer = aliceClient.getMyOffer(originalOffer.getId());
|
originalOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin());
|
assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin());
|
||||||
|
|
||||||
|
@ -247,9 +245,9 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
DEACTIVATE_OFFER,
|
DEACTIVATE_OFFER,
|
||||||
MKT_PRICE_MARGIN_AND_ACTIVATION_STATE);
|
MKT_PRICE_MARGIN_AND_ACTIVATION_STATE);
|
||||||
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
||||||
genBtcBlocksThenWait(1, 2500);
|
genBtcBlocksThenWait(1, 2_500);
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED USD OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited USD offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin());
|
assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin());
|
||||||
assertEquals(0, editedOffer.getTriggerPrice());
|
assertEquals(0, editedOffer.getTriggerPrice());
|
||||||
assertFalse(editedOffer.getIsActivated());
|
assertFalse(editedOffer.getIsActivated());
|
||||||
|
@ -261,18 +259,16 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
@Order(8)
|
@Order(8)
|
||||||
public void testEditMktPriceMarginAndTriggerPriceAndDeactivation() {
|
public void testEditMktPriceMarginAndTriggerPriceAndDeactivation() {
|
||||||
PaymentAccount paymentAcct = getOrCreatePaymentAccount("US");
|
PaymentAccount paymentAcct = getOrCreatePaymentAccount("US");
|
||||||
|
|
||||||
var originalMktPriceMargin = new BigDecimal("0.0").doubleValue();
|
var originalMktPriceMargin = new BigDecimal("0.0").doubleValue();
|
||||||
var mktPriceAsDouble = aliceClient.getBtcPrice(USD);
|
var mktPriceAsDouble = aliceClient.getBtcPrice(USD);
|
||||||
var originalTriggerPriceAsLong = calcPriceAsLong.apply(mktPriceAsDouble, -5_000.0000);
|
var originalTriggerPriceAsLong = calcPriceAsLong.apply(mktPriceAsDouble, -5_000.0000);
|
||||||
|
|
||||||
OfferInfo originalOffer = createMktPricedOfferForEdit(SELL.name(),
|
OfferInfo originalOffer = createMktPricedOfferForEdit(SELL.name(),
|
||||||
USD,
|
USD,
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
originalMktPriceMargin,
|
originalMktPriceMargin,
|
||||||
originalTriggerPriceAsLong);
|
originalTriggerPriceAsLong);
|
||||||
log.debug("ORIGINAL USD OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
originalOffer = aliceClient.getMyOffer(originalOffer.getId());
|
originalOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin());
|
assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin());
|
||||||
assertEquals(originalTriggerPriceAsLong, originalOffer.getTriggerPrice());
|
assertEquals(originalTriggerPriceAsLong, originalOffer.getTriggerPrice());
|
||||||
|
@ -288,9 +284,9 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
DEACTIVATE_OFFER,
|
DEACTIVATE_OFFER,
|
||||||
MKT_PRICE_MARGIN_AND_TRIGGER_PRICE_AND_ACTIVATION_STATE);
|
MKT_PRICE_MARGIN_AND_TRIGGER_PRICE_AND_ACTIVATION_STATE);
|
||||||
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
||||||
genBtcBlocksThenWait(1, 2500);
|
genBtcBlocksThenWait(1, 2_500);
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED USD OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited USD offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin());
|
assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin());
|
||||||
assertEquals(newTriggerPriceAsLong, editedOffer.getTriggerPrice());
|
assertEquals(newTriggerPriceAsLong, editedOffer.getTriggerPrice());
|
||||||
assertFalse(editedOffer.getIsActivated());
|
assertFalse(editedOffer.getIsActivated());
|
||||||
|
@ -303,13 +299,13 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
public void testEditingFixedPriceInMktPriceMarginBasedOfferShouldThrowException() {
|
public void testEditingFixedPriceInMktPriceMarginBasedOfferShouldThrowException() {
|
||||||
PaymentAccount paymentAcct = getOrCreatePaymentAccount("US");
|
PaymentAccount paymentAcct = getOrCreatePaymentAccount("US");
|
||||||
var originalMktPriceMargin = new BigDecimal("0.0").doubleValue();
|
var originalMktPriceMargin = new BigDecimal("0.0").doubleValue();
|
||||||
final OfferInfo originalOffer = createMktPricedOfferForEdit(SELL.name(),
|
var originalOffer = createMktPricedOfferForEdit(SELL.name(),
|
||||||
USD,
|
USD,
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
originalMktPriceMargin,
|
originalMktPriceMargin,
|
||||||
NO_TRIGGER_PRICE);
|
NO_TRIGGER_PRICE);
|
||||||
log.debug("ORIGINAL USD OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
// Try to edit both the fixed price and mkt price margin.
|
// Try to edit both the fixed price and mkt price margin.
|
||||||
var newMktPriceMargin = new BigDecimal("0.25").doubleValue();
|
var newMktPriceMargin = new BigDecimal("0.25").doubleValue();
|
||||||
var newFixedPrice = "50000.0000";
|
var newFixedPrice = "50000.0000";
|
||||||
|
@ -335,12 +331,12 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
PaymentAccount paymentAcct = getOrCreatePaymentAccount("RU");
|
PaymentAccount paymentAcct = getOrCreatePaymentAccount("RU");
|
||||||
double mktPriceAsDouble = aliceClient.getBtcPrice(RUBLE);
|
double mktPriceAsDouble = aliceClient.getBtcPrice(RUBLE);
|
||||||
String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 200_000.0000);
|
String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 200_000.0000);
|
||||||
OfferInfo originalOffer = createFixedPricedOfferForEdit(BUY.name(),
|
var originalOffer = createFixedPricedOfferForEdit(BUY.name(),
|
||||||
RUBLE,
|
RUBLE,
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
fixedPriceAsString);
|
fixedPriceAsString);
|
||||||
log.debug("ORIGINAL RUB OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original RUB offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
long newTriggerPrice = 1000000L;
|
long newTriggerPrice = 1000000L;
|
||||||
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
|
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
|
||||||
aliceClient.editOfferTriggerPrice(originalOffer.getId(), newTriggerPrice));
|
aliceClient.editOfferTriggerPrice(originalOffer.getId(), newTriggerPrice));
|
||||||
|
@ -358,12 +354,12 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
PaymentAccount paymentAcct = getOrCreatePaymentAccount("MX");
|
PaymentAccount paymentAcct = getOrCreatePaymentAccount("MX");
|
||||||
double mktPriceAsDouble = aliceClient.getBtcPrice("MXN");
|
double mktPriceAsDouble = aliceClient.getBtcPrice("MXN");
|
||||||
String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 0.00);
|
String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 0.00);
|
||||||
OfferInfo originalOffer = createFixedPricedOfferForEdit(BUY.name(),
|
var originalOffer = createFixedPricedOfferForEdit(BUY.name(),
|
||||||
"MXN",
|
"MXN",
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
fixedPriceAsString);
|
fixedPriceAsString);
|
||||||
log.debug("ORIGINAL MXN OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original MXN offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
|
|
||||||
// Change the offer to mkt price based and set a trigger price.
|
// Change the offer to mkt price based and set a trigger price.
|
||||||
var newMktPriceMargin = new BigDecimal("0.05").doubleValue();
|
var newMktPriceMargin = new BigDecimal("0.05").doubleValue();
|
||||||
|
@ -377,9 +373,9 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
ACTIVATE_OFFER,
|
ACTIVATE_OFFER,
|
||||||
MKT_PRICE_MARGIN_AND_TRIGGER_PRICE);
|
MKT_PRICE_MARGIN_AND_TRIGGER_PRICE);
|
||||||
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
||||||
genBtcBlocksThenWait(1, 2500);
|
genBtcBlocksThenWait(1, 2_500);
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED MXN OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited MXN offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
assertTrue(editedOffer.getUseMarketBasedPrice());
|
assertTrue(editedOffer.getUseMarketBasedPrice());
|
||||||
assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin());
|
assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin());
|
||||||
assertEquals(newTriggerPriceAsLong, editedOffer.getTriggerPrice());
|
assertEquals(newTriggerPriceAsLong, editedOffer.getTriggerPrice());
|
||||||
|
@ -396,13 +392,13 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
var originalMktPriceMargin = new BigDecimal("0.25").doubleValue();
|
var originalMktPriceMargin = new BigDecimal("0.25").doubleValue();
|
||||||
var delta = 1_000.0000; // trigger price on sell offer is 1K below mkt price
|
var delta = 1_000.0000; // trigger price on sell offer is 1K below mkt price
|
||||||
var originalTriggerPriceAsLong = calcPriceAsLong.apply(mktPriceAsDouble, delta);
|
var originalTriggerPriceAsLong = calcPriceAsLong.apply(mktPriceAsDouble, delta);
|
||||||
final OfferInfo originalOffer = createMktPricedOfferForEdit(SELL.name(),
|
var originalOffer = createMktPricedOfferForEdit(SELL.name(),
|
||||||
"GBP",
|
"GBP",
|
||||||
paymentAcct.getId(),
|
paymentAcct.getId(),
|
||||||
originalMktPriceMargin,
|
originalMktPriceMargin,
|
||||||
originalTriggerPriceAsLong);
|
originalTriggerPriceAsLong);
|
||||||
log.debug("ORIGINAL GBP OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original GBP offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
|
|
||||||
String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 0.00);
|
String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 0.00);
|
||||||
aliceClient.editOffer(originalOffer.getId(),
|
aliceClient.editOffer(originalOffer.getId(),
|
||||||
|
@ -413,9 +409,9 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
DEACTIVATE_OFFER,
|
DEACTIVATE_OFFER,
|
||||||
FIXED_PRICE_AND_ACTIVATION_STATE);
|
FIXED_PRICE_AND_ACTIVATION_STATE);
|
||||||
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
// Wait for edited offer to be removed from offer-book, edited, and re-published.
|
||||||
genBtcBlocksThenWait(1, 2500);
|
genBtcBlocksThenWait(1, 2_500);
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED GBP OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited GBP offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
assertEquals(scaledUpFiatOfferPrice.apply(new BigDecimal(fixedPriceAsString)), editedOffer.getPrice());
|
assertEquals(scaledUpFiatOfferPrice.apply(new BigDecimal(fixedPriceAsString)), editedOffer.getPrice());
|
||||||
assertFalse(editedOffer.getUseMarketBasedPrice());
|
assertFalse(editedOffer.getUseMarketBasedPrice());
|
||||||
assertEquals(0.00, editedOffer.getMarketPriceMargin());
|
assertEquals(0.00, editedOffer.getMarketPriceMargin());
|
||||||
|
@ -426,7 +422,7 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
@Test
|
@Test
|
||||||
@Order(13)
|
@Order(13)
|
||||||
public void testChangeFixedPricedBsqOfferToPriceMarginBasedOfferShouldThrowException() {
|
public void testChangeFixedPricedBsqOfferToPriceMarginBasedOfferShouldThrowException() {
|
||||||
OfferInfo originalOffer = aliceClient.createFixedPricedOffer(BUY.name(),
|
var originalOffer = aliceClient.createFixedPricedOffer(BUY.name(),
|
||||||
BSQ,
|
BSQ,
|
||||||
100_000_000L,
|
100_000_000L,
|
||||||
100_000_000L,
|
100_000_000L,
|
||||||
|
@ -434,8 +430,8 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
getDefaultBuyerSecurityDepositAsPercent(),
|
getDefaultBuyerSecurityDepositAsPercent(),
|
||||||
alicesLegacyBsqAcct.getId(),
|
alicesLegacyBsqAcct.getId(),
|
||||||
BSQ);
|
BSQ);
|
||||||
log.debug("ORIGINAL BSQ OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
|
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
|
||||||
aliceClient.editOffer(originalOffer.getId(),
|
aliceClient.editOffer(originalOffer.getId(),
|
||||||
"0.00",
|
"0.00",
|
||||||
|
@ -453,7 +449,7 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
@Test
|
@Test
|
||||||
@Order(14)
|
@Order(14)
|
||||||
public void testEditTriggerPriceOnFixedPriceBsqOfferShouldThrowException() {
|
public void testEditTriggerPriceOnFixedPriceBsqOfferShouldThrowException() {
|
||||||
OfferInfo originalOffer = aliceClient.createFixedPricedOffer(BUY.name(),
|
var originalOffer = aliceClient.createFixedPricedOffer(BUY.name(),
|
||||||
BSQ,
|
BSQ,
|
||||||
100_000_000L,
|
100_000_000L,
|
||||||
100_000_000L,
|
100_000_000L,
|
||||||
|
@ -461,8 +457,8 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
getDefaultBuyerSecurityDepositAsPercent(),
|
getDefaultBuyerSecurityDepositAsPercent(),
|
||||||
alicesLegacyBsqAcct.getId(),
|
alicesLegacyBsqAcct.getId(),
|
||||||
BSQ);
|
BSQ);
|
||||||
log.debug("ORIGINAL BSQ OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
var newTriggerPriceAsLong = calcPriceAsLong.apply(0.00005, 0.00);
|
var newTriggerPriceAsLong = calcPriceAsLong.apply(0.00005, 0.00);
|
||||||
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
|
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
|
||||||
aliceClient.editOffer(originalOffer.getId(),
|
aliceClient.editOffer(originalOffer.getId(),
|
||||||
|
@ -482,7 +478,7 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
@Order(15)
|
@Order(15)
|
||||||
public void testEditFixedPriceOnBsqOffer() {
|
public void testEditFixedPriceOnBsqOffer() {
|
||||||
String fixedPriceAsString = "0.00005"; // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ
|
String fixedPriceAsString = "0.00005"; // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ
|
||||||
final OfferInfo originalOffer = aliceClient.createFixedPricedOffer(BUY.name(),
|
var originalOffer = aliceClient.createFixedPricedOffer(BUY.name(),
|
||||||
BSQ,
|
BSQ,
|
||||||
100_000_000L,
|
100_000_000L,
|
||||||
100_000_000L,
|
100_000_000L,
|
||||||
|
@ -490,8 +486,8 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
getDefaultBuyerSecurityDepositAsPercent(),
|
getDefaultBuyerSecurityDepositAsPercent(),
|
||||||
alicesLegacyBsqAcct.getId(),
|
alicesLegacyBsqAcct.getId(),
|
||||||
BSQ);
|
BSQ);
|
||||||
log.debug("ORIGINAL BSQ OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
String newFixedPriceAsString = "0.00003111";
|
String newFixedPriceAsString = "0.00003111";
|
||||||
aliceClient.editOffer(originalOffer.getId(),
|
aliceClient.editOffer(originalOffer.getId(),
|
||||||
newFixedPriceAsString,
|
newFixedPriceAsString,
|
||||||
|
@ -501,9 +497,9 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
ACTIVATE_OFFER,
|
ACTIVATE_OFFER,
|
||||||
FIXED_PRICE_ONLY);
|
FIXED_PRICE_ONLY);
|
||||||
// Wait for edited offer to be edited and removed from offer-book.
|
// Wait for edited offer to be edited and removed from offer-book.
|
||||||
genBtcBlocksThenWait(1, 2500);
|
genBtcBlocksThenWait(1, 2_500);
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED BSQ OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited BSQ offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
assertEquals(scaledUpAltcoinOfferPrice.apply(newFixedPriceAsString), editedOffer.getPrice());
|
assertEquals(scaledUpAltcoinOfferPrice.apply(newFixedPriceAsString), editedOffer.getPrice());
|
||||||
assertTrue(editedOffer.getIsActivated());
|
assertTrue(editedOffer.getIsActivated());
|
||||||
assertFalse(editedOffer.getUseMarketBasedPrice());
|
assertFalse(editedOffer.getUseMarketBasedPrice());
|
||||||
|
@ -515,7 +511,7 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
@Order(16)
|
@Order(16)
|
||||||
public void testDisableBsqOffer() {
|
public void testDisableBsqOffer() {
|
||||||
String fixedPriceAsString = "0.00005"; // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ
|
String fixedPriceAsString = "0.00005"; // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ
|
||||||
final OfferInfo originalOffer = aliceClient.createFixedPricedOffer(BUY.name(),
|
var originalOffer = aliceClient.createFixedPricedOffer(BUY.name(),
|
||||||
BSQ,
|
BSQ,
|
||||||
100_000_000L,
|
100_000_000L,
|
||||||
100_000_000L,
|
100_000_000L,
|
||||||
|
@ -523,8 +519,8 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
getDefaultBuyerSecurityDepositAsPercent(),
|
getDefaultBuyerSecurityDepositAsPercent(),
|
||||||
alicesLegacyBsqAcct.getId(),
|
alicesLegacyBsqAcct.getId(),
|
||||||
BSQ);
|
BSQ);
|
||||||
log.debug("ORIGINAL BSQ OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
aliceClient.editOffer(originalOffer.getId(),
|
aliceClient.editOffer(originalOffer.getId(),
|
||||||
fixedPriceAsString,
|
fixedPriceAsString,
|
||||||
false,
|
false,
|
||||||
|
@ -533,9 +529,9 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
DEACTIVATE_OFFER,
|
DEACTIVATE_OFFER,
|
||||||
ACTIVATION_STATE_ONLY);
|
ACTIVATION_STATE_ONLY);
|
||||||
// Wait for edited offer to be removed from offer-book.
|
// Wait for edited offer to be removed from offer-book.
|
||||||
genBtcBlocksThenWait(1, 2500);
|
genBtcBlocksThenWait(1, 2_500);
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED BSQ OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited BSQ offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
assertFalse(editedOffer.getIsActivated());
|
assertFalse(editedOffer.getIsActivated());
|
||||||
assertEquals(scaledUpAltcoinOfferPrice.apply(fixedPriceAsString), editedOffer.getPrice());
|
assertEquals(scaledUpAltcoinOfferPrice.apply(fixedPriceAsString), editedOffer.getPrice());
|
||||||
assertFalse(editedOffer.getUseMarketBasedPrice());
|
assertFalse(editedOffer.getUseMarketBasedPrice());
|
||||||
|
@ -547,7 +543,7 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
@Order(17)
|
@Order(17)
|
||||||
public void testEditFixedPriceAndDisableBsqOffer() {
|
public void testEditFixedPriceAndDisableBsqOffer() {
|
||||||
String fixedPriceAsString = "0.00005"; // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ
|
String fixedPriceAsString = "0.00005"; // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ
|
||||||
final OfferInfo originalOffer = aliceClient.createFixedPricedOffer(BUY.name(),
|
var originalOffer = aliceClient.createFixedPricedOffer(BUY.name(),
|
||||||
BSQ,
|
BSQ,
|
||||||
100_000_000L,
|
100_000_000L,
|
||||||
100_000_000L,
|
100_000_000L,
|
||||||
|
@ -555,8 +551,8 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
getDefaultBuyerSecurityDepositAsPercent(),
|
getDefaultBuyerSecurityDepositAsPercent(),
|
||||||
alicesLegacyBsqAcct.getId(),
|
alicesLegacyBsqAcct.getId(),
|
||||||
BSQ);
|
BSQ);
|
||||||
log.debug("ORIGINAL BSQ OFFER:\n{}", toOfferTable.apply(originalOffer));
|
log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
genBtcBlocksThenWait(1, 2500); // Wait for offer book entry.
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
String newFixedPriceAsString = "0.000045";
|
String newFixedPriceAsString = "0.000045";
|
||||||
aliceClient.editOffer(originalOffer.getId(),
|
aliceClient.editOffer(originalOffer.getId(),
|
||||||
newFixedPriceAsString,
|
newFixedPriceAsString,
|
||||||
|
@ -566,9 +562,9 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
DEACTIVATE_OFFER,
|
DEACTIVATE_OFFER,
|
||||||
FIXED_PRICE_AND_ACTIVATION_STATE);
|
FIXED_PRICE_AND_ACTIVATION_STATE);
|
||||||
// Wait for edited offer to be edited and removed from offer-book.
|
// Wait for edited offer to be edited and removed from offer-book.
|
||||||
genBtcBlocksThenWait(1, 2500);
|
genBtcBlocksThenWait(1, 2_500);
|
||||||
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
OfferInfo editedOffer = aliceClient.getMyOffer(originalOffer.getId());
|
||||||
log.debug("EDITED BSQ OFFER:\n{}", toOfferTable.apply(editedOffer));
|
log.debug("Edited BSQ offer:\n{}", toOfferTable.apply(editedOffer));
|
||||||
assertFalse(editedOffer.getIsActivated());
|
assertFalse(editedOffer.getIsActivated());
|
||||||
assertEquals(scaledUpAltcoinOfferPrice.apply(newFixedPriceAsString), editedOffer.getPrice());
|
assertEquals(scaledUpAltcoinOfferPrice.apply(newFixedPriceAsString), editedOffer.getPrice());
|
||||||
assertFalse(editedOffer.getUseMarketBasedPrice());
|
assertFalse(editedOffer.getUseMarketBasedPrice());
|
||||||
|
@ -576,6 +572,39 @@ public class EditOfferTest extends AbstractOfferTest {
|
||||||
assertEquals(0, editedOffer.getTriggerPrice());
|
assertEquals(0, editedOffer.getTriggerPrice());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(18)
|
||||||
|
public void testEditBsqSwapOfferShouldThrowException() {
|
||||||
|
var originalOffer = aliceClient.createBsqSwapOffer(SELL.name(),
|
||||||
|
1_250_000L,
|
||||||
|
750_000L,
|
||||||
|
"0.00005");
|
||||||
|
log.debug("BsqSwap Buy BSQ (Buy BTC) offer:\n{}", originalOffer);
|
||||||
|
var newOfferId = originalOffer.getId();
|
||||||
|
assertNotEquals("", newOfferId);
|
||||||
|
assertEquals(SELL.name(), originalOffer.getDirection());
|
||||||
|
assertEquals(5_000, originalOffer.getPrice());
|
||||||
|
assertEquals(1_250_000L, originalOffer.getAmount());
|
||||||
|
assertEquals(750_000L, originalOffer.getMinAmount());
|
||||||
|
assertEquals(BSQ, originalOffer.getBaseCurrencyCode());
|
||||||
|
assertEquals(BTC, originalOffer.getCounterCurrencyCode());
|
||||||
|
|
||||||
|
log.debug("Original BsqSwap offer:\n{}", toOfferTable.apply(originalOffer));
|
||||||
|
genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry.
|
||||||
|
var newFixedPrice = "0.000055";
|
||||||
|
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
|
||||||
|
aliceClient.editOffer(originalOffer.getId(),
|
||||||
|
newFixedPrice,
|
||||||
|
false,
|
||||||
|
0.0,
|
||||||
|
0,
|
||||||
|
ACTIVATE_OFFER,
|
||||||
|
TRIGGER_PRICE_ONLY));
|
||||||
|
String expectedExceptionMessage = format("UNKNOWN: cannot edit bsq swap offer with id '%s'",
|
||||||
|
originalOffer.getId());
|
||||||
|
assertEquals(expectedExceptionMessage, exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
private OfferInfo createMktPricedOfferForEdit(String direction,
|
private OfferInfo createMktPricedOfferForEdit(String direction,
|
||||||
String currencyCode,
|
String currencyCode,
|
||||||
String paymentAccountId,
|
String paymentAccountId,
|
||||||
|
|
|
@ -21,11 +21,13 @@ import static bisq.core.trade.model.bisq_v1.Trade.State.BUYER_SAW_ARRIVED_FIAT_P
|
||||||
import static bisq.core.trade.model.bisq_v1.Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN;
|
import static bisq.core.trade.model.bisq_v1.Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN;
|
||||||
import static bisq.core.trade.model.bisq_v1.Trade.State.SELLER_RECEIVED_FIAT_PAYMENT_INITIATED_MSG;
|
import static bisq.core.trade.model.bisq_v1.Trade.State.SELLER_RECEIVED_FIAT_PAYMENT_INITIATED_MSG;
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
|
import static java.lang.System.out;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import bisq.apitest.method.offer.AbstractOfferTest;
|
import bisq.apitest.method.offer.AbstractOfferTest;
|
||||||
|
import bisq.cli.CliMain;
|
||||||
import bisq.cli.GrpcClient;
|
import bisq.cli.GrpcClient;
|
||||||
import bisq.cli.table.builder.TableBuilder;
|
import bisq.cli.table.builder.TableBuilder;
|
||||||
|
|
||||||
|
@ -37,7 +39,9 @@ public class AbstractTradeTest extends AbstractOfferTest {
|
||||||
protected static String tradeId;
|
protected static String tradeId;
|
||||||
|
|
||||||
protected final Supplier<Integer> maxTradeStateAndPhaseChecks = () -> isLongRunningTest ? 10 : 2;
|
protected final Supplier<Integer> maxTradeStateAndPhaseChecks = () -> isLongRunningTest ? 10 : 2;
|
||||||
private final Function<GrpcClient, String> toUserName = (client) -> client.equals(aliceClient) ? "Alice" : "Bob";
|
protected final Function<TradeInfo, String> toTradeDetailTable = (trade) ->
|
||||||
|
new TableBuilder(TRADE_DETAIL_TBL, trade).build().toString();
|
||||||
|
protected final Function<GrpcClient, String> toUserName = (client) -> client.equals(aliceClient) ? "Alice" : "Bob";
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void initStaticFixtures() {
|
public static void initStaticFixtures() {
|
||||||
|
@ -241,4 +245,11 @@ public class AbstractTradeTest extends AbstractOfferTest {
|
||||||
new TableBuilder(TRADE_DETAIL_TBL, trade).build()));
|
new TableBuilder(TRADE_DETAIL_TBL, trade).build()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static void runCliGetTrade(String tradeId) {
|
||||||
|
out.println("Alice's CLI 'gettrade' response:");
|
||||||
|
CliMain.main(new String[]{"--password=xyz", "--port=9998", "gettrade", "--trade-id=" + tradeId});
|
||||||
|
out.println("Bob's CLI 'gettrade' response:");
|
||||||
|
CliMain.main(new String[]{"--password=xyz", "--port=9999", "gettrade", "--trade-id=" + tradeId});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
package bisq.apitest.method.trade;
|
package bisq.apitest.method.trade;
|
||||||
|
|
||||||
import bisq.proto.grpc.BsqSwapOfferInfo;
|
import bisq.proto.grpc.OfferInfo;
|
||||||
import bisq.proto.grpc.BsqSwapTradeInfo;
|
import bisq.proto.grpc.TradeInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -36,9 +36,11 @@ import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
|
||||||
import static bisq.apitest.config.ApiTestConfig.BSQ;
|
import static bisq.apitest.config.ApiTestConfig.BSQ;
|
||||||
import static bisq.apitest.config.ApiTestConfig.BTC;
|
import static bisq.apitest.config.ApiTestConfig.BTC;
|
||||||
|
import static bisq.proto.grpc.GetOfferCategoryReply.OfferCategory.BSQ_SWAP;
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
import static protobuf.BsqSwapTrade.State.COMPLETED;
|
import static protobuf.BsqSwapTrade.State.COMPLETED;
|
||||||
import static protobuf.BsqSwapTrade.State.PREPARATION;
|
import static protobuf.BsqSwapTrade.State.PREPARATION;
|
||||||
|
@ -47,13 +49,12 @@ import static protobuf.OfferDirection.BUY;
|
||||||
|
|
||||||
|
|
||||||
import bisq.apitest.method.offer.AbstractOfferTest;
|
import bisq.apitest.method.offer.AbstractOfferTest;
|
||||||
|
import bisq.cli.GrpcClient;
|
||||||
|
|
||||||
@Disabled
|
@Disabled
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
public class BsqSwapTradeTest extends AbstractOfferTest {
|
public class BsqSwapTradeTest extends AbstractTradeTest {
|
||||||
|
|
||||||
private static final String BISQ_FEE_CURRENCY_CODE = BSQ;
|
|
||||||
|
|
||||||
// Long-running swap trade tests might want to check node logs for exceptions.
|
// Long-running swap trade tests might want to check node logs for exceptions.
|
||||||
@Setter
|
@Setter
|
||||||
|
@ -66,7 +67,7 @@ public class BsqSwapTradeTest extends AbstractOfferTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void generateBtcBlock() {
|
public void generateBtcBlock() {
|
||||||
genBtcBlocksThenWait(1, 2000);
|
genBtcBlocksThenWait(1, 2_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -81,54 +82,91 @@ public class BsqSwapTradeTest extends AbstractOfferTest {
|
||||||
@Test
|
@Test
|
||||||
@Order(2)
|
@Order(2)
|
||||||
public void testAliceCreateBsqSwapBuyOffer() {
|
public void testAliceCreateBsqSwapBuyOffer() {
|
||||||
var bsqSwapOffer = aliceClient.createBsqSwapOffer(BUY.name(),
|
var mySwapOffer = aliceClient.createBsqSwapOffer(BUY.name(),
|
||||||
|
1_000_000L, // 0.01 BTC
|
||||||
1_000_000L,
|
1_000_000L,
|
||||||
1_000_000L,
|
"0.00005");
|
||||||
"0.00005",
|
log.debug("Pending BsqSwap Sell BSQ (Buy BTC) OFFER:\n{}", toOfferTable.apply(mySwapOffer));
|
||||||
alicesBsqSwapAcct.getId());
|
var newOfferId = mySwapOffer.getId();
|
||||||
log.debug("BsqSwap Sell BSQ (Buy BTC) OFFER:\n{}", bsqSwapOffer);
|
|
||||||
var newOfferId = bsqSwapOffer.getId();
|
|
||||||
assertNotEquals("", newOfferId);
|
assertNotEquals("", newOfferId);
|
||||||
assertEquals(BUY.name(), bsqSwapOffer.getDirection());
|
assertEquals(BUY.name(), mySwapOffer.getDirection());
|
||||||
assertEquals(5_000, bsqSwapOffer.getPrice());
|
assertEquals(5_000, mySwapOffer.getPrice());
|
||||||
assertEquals(1_000_000L, bsqSwapOffer.getAmount());
|
assertEquals(1_000_000L, mySwapOffer.getAmount());
|
||||||
assertEquals(1_000_000L, bsqSwapOffer.getMinAmount());
|
assertEquals(1_000_000L, mySwapOffer.getMinAmount());
|
||||||
// assertEquals(alicesBsqAcct.getId(), atomicOffer.getMakerPaymentAccountId());
|
assertEquals(BSQ, mySwapOffer.getBaseCurrencyCode());
|
||||||
assertEquals(BSQ, bsqSwapOffer.getBaseCurrencyCode());
|
assertEquals(BTC, mySwapOffer.getCounterCurrencyCode());
|
||||||
assertEquals(BTC, bsqSwapOffer.getCounterCurrencyCode());
|
|
||||||
|
genBtcBlocksThenWait(1, 2_500);
|
||||||
|
|
||||||
|
mySwapOffer = aliceClient.getMyOffer(newOfferId);
|
||||||
|
log.debug("My fetched BsqSwap Sell BSQ (Buy BTC) OFFER:\n{}", toOfferTable.apply(mySwapOffer));
|
||||||
|
assertNotEquals(0, mySwapOffer.getMakerFee());
|
||||||
|
|
||||||
|
runCliGetOffer(newOfferId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(3)
|
@Order(3)
|
||||||
public void testBobTakesBsqSwapOffer() {
|
public void testBobTakesBsqSwapOffer() {
|
||||||
var bsqSwapOffer = getAvailableBsqSwapOffer();
|
var availableSwapOffer = getAvailableBsqSwapOffer(bobClient);
|
||||||
var bsqSwapTradeInfo = bobClient.takeBsqSwapOffer(bsqSwapOffer.getId(),
|
|
||||||
bobsBsqSwapAcct.getId(),
|
// Before sending a TakeOfferRequest, the CLI needs to know what kind of Offer
|
||||||
BISQ_FEE_CURRENCY_CODE);
|
// it is taking (v1 or BsqSwap). Only BSQ swap offers can be taken with a
|
||||||
log.debug("Trade at t1: {}", bsqSwapTradeInfo);
|
// single offerId parameter. Taking v1 offers requires an additional
|
||||||
assertEquals(PREPARATION.name(), bsqSwapTradeInfo.getState());
|
// paymentAccountId param. The test case knows what kind of offer is being taken,
|
||||||
|
// but we test the gRPC GetOfferCategory service here.
|
||||||
|
var availableOfferCategory = bobClient.getAvailableOfferCategory(availableSwapOffer.getId());
|
||||||
|
assertTrue(availableOfferCategory.equals(BSQ_SWAP));
|
||||||
|
|
||||||
|
sleep(30_000);
|
||||||
|
|
||||||
|
var swapTrade = bobClient.takeBsqSwapOffer(availableSwapOffer.getId());
|
||||||
|
tradeId = swapTrade.getTradeId(); // Cache the tradeId for following test case(s).
|
||||||
|
log.debug("BsqSwap Trade at PREPARATION:\n{}", toTradeDetailTable.apply(swapTrade));
|
||||||
|
assertEquals(PREPARATION.name(), swapTrade.getState());
|
||||||
genBtcBlocksThenWait(1, 3_000);
|
genBtcBlocksThenWait(1, 3_000);
|
||||||
|
|
||||||
bsqSwapTradeInfo = getBsqSwapTrade(bsqSwapTradeInfo.getTradeId());
|
swapTrade = getBsqSwapTrade(bobClient, tradeId);
|
||||||
log.debug("Trade at t2: {}", bsqSwapTradeInfo);
|
log.debug("BsqSwap Trade at COMPLETION:\n{}", toTradeDetailTable.apply(swapTrade));
|
||||||
assertEquals(COMPLETED.name(), bsqSwapTradeInfo.getState());
|
assertEquals(COMPLETED.name(), swapTrade.getState());
|
||||||
|
|
||||||
|
runCliGetTrade(tradeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(4)
|
@Order(4)
|
||||||
|
public void testCompletedSwapTxConfirmations() {
|
||||||
|
sleep(2_000); // Wait for TX confirmation to happen on node.
|
||||||
|
|
||||||
|
var alicesTrade = getBsqSwapTrade(aliceClient, tradeId);
|
||||||
|
log.debug("Alice's BsqSwap Trade at COMPLETION:\n{}", toTradeDetailTable.apply(alicesTrade));
|
||||||
|
assertEquals(1, alicesTrade.getBsqSwapTradeInfo().getNumConfirmations());
|
||||||
|
|
||||||
|
var bobsTrade = getBsqSwapTrade(bobClient, tradeId);
|
||||||
|
log.debug("Bob's BsqSwap Trade at COMPLETION:\n{}", toTradeDetailTable.apply(bobsTrade));
|
||||||
|
assertEquals(1, bobsTrade.getBsqSwapTradeInfo().getNumConfirmations());
|
||||||
|
|
||||||
|
genBtcBlocksThenWait(1, 2_000);
|
||||||
|
|
||||||
|
bobsTrade = getBsqSwapTrade(bobClient, tradeId);
|
||||||
|
log.debug("Bob's BsqSwap Trade at COMPLETION:\n{}", toTradeDetailTable.apply(bobsTrade));
|
||||||
|
assertEquals(2, bobsTrade.getBsqSwapTradeInfo().getNumConfirmations());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(5)
|
||||||
public void testGetBalancesAfterTrade() {
|
public void testGetBalancesAfterTrade() {
|
||||||
sleep(2_500); // Give wallet time to finish processing TX.
|
|
||||||
var alicesBalances = aliceClient.getBalances();
|
var alicesBalances = aliceClient.getBalances();
|
||||||
log.debug("Alice's After Trade Balance:\n{}", formatBalancesTbls(alicesBalances));
|
log.debug("Alice's After Trade Balance:\n{}", formatBalancesTbls(alicesBalances));
|
||||||
var bobsBalances = bobClient.getBalances();
|
var bobsBalances = bobClient.getBalances();
|
||||||
log.debug("Bob's After Trade Balance:\n{}", formatBalancesTbls(bobsBalances));
|
log.debug("Bob's After Trade Balance:\n{}", formatBalancesTbls(bobsBalances));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BsqSwapOfferInfo getAvailableBsqSwapOffer() {
|
private OfferInfo getAvailableBsqSwapOffer(GrpcClient client) {
|
||||||
List<BsqSwapOfferInfo> bsqSwapOffers = new ArrayList<>();
|
List<OfferInfo> bsqSwapOffers = new ArrayList<>();
|
||||||
int numFetchAttempts = 0;
|
int numFetchAttempts = 0;
|
||||||
while (bsqSwapOffers.size() == 0) {
|
while (bsqSwapOffers.size() == 0) {
|
||||||
bsqSwapOffers.addAll(bobClient.getBsqSwapOffers(BUY.name(), BSQ));
|
bsqSwapOffers.addAll(client.getBsqSwapOffers(BUY.name()));
|
||||||
numFetchAttempts++;
|
numFetchAttempts++;
|
||||||
if (bsqSwapOffers.size() == 0) {
|
if (bsqSwapOffers.size() == 0) {
|
||||||
log.warn("No available bsq swap offers found after {} fetch attempts.", numFetchAttempts);
|
log.warn("No available bsq swap offers found after {} fetch attempts.", numFetchAttempts);
|
||||||
|
@ -138,7 +176,7 @@ public class BsqSwapTradeTest extends AbstractOfferTest {
|
||||||
}
|
}
|
||||||
fail(format("Bob gave up on fetching available bsq swap offers after %d attempts.", numFetchAttempts));
|
fail(format("Bob gave up on fetching available bsq swap offers after %d attempts.", numFetchAttempts));
|
||||||
}
|
}
|
||||||
sleep(1000);
|
sleep(1_000);
|
||||||
} else {
|
} else {
|
||||||
assertEquals(1, bsqSwapOffers.size());
|
assertEquals(1, bsqSwapOffers.size());
|
||||||
log.debug("Bob found new available bsq swap offer on attempt # {}.", numFetchAttempts);
|
log.debug("Bob found new available bsq swap offer on attempt # {}.", numFetchAttempts);
|
||||||
|
@ -150,12 +188,12 @@ public class BsqSwapTradeTest extends AbstractOfferTest {
|
||||||
return bsqSwapOffer;
|
return bsqSwapOffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BsqSwapTradeInfo getBsqSwapTrade(String tradeId) {
|
private TradeInfo getBsqSwapTrade(GrpcClient client, String tradeId) {
|
||||||
int numFetchAttempts = 0;
|
int numFetchAttempts = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
numFetchAttempts++;
|
numFetchAttempts++;
|
||||||
return bobClient.getBsqSwapTrade(tradeId);
|
return client.getTrade(tradeId);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.warn(ex.getMessage());
|
log.warn(ex.getMessage());
|
||||||
if (numFetchAttempts > 9) {
|
if (numFetchAttempts > 9) {
|
||||||
|
@ -164,7 +202,7 @@ public class BsqSwapTradeTest extends AbstractOfferTest {
|
||||||
}
|
}
|
||||||
fail(format("Could not find new bsq swap trade after %d attempts.", numFetchAttempts));
|
fail(format("Could not find new bsq swap trade after %d attempts.", numFetchAttempts));
|
||||||
} else {
|
} else {
|
||||||
sleep(1000);
|
sleep(1_000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,9 @@ public class TradeTest extends AbstractTradeTest {
|
||||||
@Order(6)
|
@Order(6)
|
||||||
public void testBsqSwapTradeTest(final TestInfo testInfo) {
|
public void testBsqSwapTradeTest(final TestInfo testInfo) {
|
||||||
BsqSwapTradeTest test = new BsqSwapTradeTest();
|
BsqSwapTradeTest test = new BsqSwapTradeTest();
|
||||||
|
test.testGetBalancesBeforeTrade();
|
||||||
test.testAliceCreateBsqSwapBuyOffer();
|
test.testAliceCreateBsqSwapBuyOffer();
|
||||||
test.testBobTakesBsqSwapOffer();
|
test.testBobTakesBsqSwapOffer();
|
||||||
|
test.testGetBalancesAfterTrade();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package bisq.cli;
|
package bisq.cli;
|
||||||
|
|
||||||
import bisq.proto.grpc.OfferInfo;
|
import bisq.proto.grpc.OfferInfo;
|
||||||
|
import bisq.proto.grpc.TradeInfo;
|
||||||
|
|
||||||
import io.grpc.StatusRuntimeException;
|
import io.grpc.StatusRuntimeException;
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ import static bisq.cli.CurrencyFormat.*;
|
||||||
import static bisq.cli.Method.*;
|
import static bisq.cli.Method.*;
|
||||||
import static bisq.cli.opts.OptLabel.*;
|
import static bisq.cli.opts.OptLabel.*;
|
||||||
import static bisq.cli.table.builder.TableType.*;
|
import static bisq.cli.table.builder.TableType.*;
|
||||||
|
import static bisq.proto.grpc.GetOfferCategoryReply.OfferCategory.BSQ_SWAP;
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
import static java.lang.System.err;
|
import static java.lang.System.err;
|
||||||
import static java.lang.System.exit;
|
import static java.lang.System.exit;
|
||||||
|
@ -62,11 +64,11 @@ import bisq.cli.opts.EditOfferOptionParser;
|
||||||
import bisq.cli.opts.GetAddressBalanceOptionParser;
|
import bisq.cli.opts.GetAddressBalanceOptionParser;
|
||||||
import bisq.cli.opts.GetBTCMarketPriceOptionParser;
|
import bisq.cli.opts.GetBTCMarketPriceOptionParser;
|
||||||
import bisq.cli.opts.GetBalanceOptionParser;
|
import bisq.cli.opts.GetBalanceOptionParser;
|
||||||
import bisq.cli.opts.GetOfferOptionParser;
|
|
||||||
import bisq.cli.opts.GetOffersOptionParser;
|
import bisq.cli.opts.GetOffersOptionParser;
|
||||||
import bisq.cli.opts.GetPaymentAcctFormOptionParser;
|
import bisq.cli.opts.GetPaymentAcctFormOptionParser;
|
||||||
import bisq.cli.opts.GetTradeOptionParser;
|
import bisq.cli.opts.GetTradeOptionParser;
|
||||||
import bisq.cli.opts.GetTransactionOptionParser;
|
import bisq.cli.opts.GetTransactionOptionParser;
|
||||||
|
import bisq.cli.opts.OfferIdOptionParser;
|
||||||
import bisq.cli.opts.RegisterDisputeAgentOptionParser;
|
import bisq.cli.opts.RegisterDisputeAgentOptionParser;
|
||||||
import bisq.cli.opts.RemoveWalletPasswordOptionParser;
|
import bisq.cli.opts.RemoveWalletPasswordOptionParser;
|
||||||
import bisq.cli.opts.SendBsqOptionParser;
|
import bisq.cli.opts.SendBsqOptionParser;
|
||||||
|
@ -332,6 +334,7 @@ public class CliMain {
|
||||||
out.println(client.getMethodHelp(method));
|
out.println(client.getMethodHelp(method));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var isSwap = opts.getIsSwap();
|
||||||
var paymentAcctId = opts.getPaymentAccountId();
|
var paymentAcctId = opts.getPaymentAccountId();
|
||||||
var direction = opts.getDirection();
|
var direction = opts.getDirection();
|
||||||
var currencyCode = opts.getCurrencyCode();
|
var currencyCode = opts.getCurrencyCode();
|
||||||
|
@ -340,30 +343,45 @@ public class CliMain {
|
||||||
var useMarketBasedPrice = opts.isUsingMktPriceMargin();
|
var useMarketBasedPrice = opts.isUsingMktPriceMargin();
|
||||||
var fixedPrice = opts.getFixedPrice();
|
var fixedPrice = opts.getFixedPrice();
|
||||||
var marketPriceMargin = opts.getMktPriceMarginAsBigDecimal();
|
var marketPriceMargin = opts.getMktPriceMarginAsBigDecimal();
|
||||||
var securityDeposit = toSecurityDepositAsPct(opts.getSecurityDeposit());
|
var securityDeposit = isSwap ? 0.00 : toSecurityDepositAsPct(opts.getSecurityDeposit());
|
||||||
var makerFeeCurrencyCode = opts.getMakerFeeCurrencyCode();
|
var makerFeeCurrencyCode = opts.getMakerFeeCurrencyCode();
|
||||||
var triggerPrice = 0; // Cannot be defined until offer is in book.
|
var triggerPrice = 0; // Cannot be defined until offer is in book.
|
||||||
var offer = client.createOffer(direction,
|
OfferInfo offer;
|
||||||
currencyCode,
|
if (isSwap) {
|
||||||
amount,
|
offer = client.createBsqSwapOffer(direction,
|
||||||
minAmount,
|
amount,
|
||||||
useMarketBasedPrice,
|
minAmount,
|
||||||
fixedPrice,
|
fixedPrice);
|
||||||
marketPriceMargin.doubleValue(),
|
} else {
|
||||||
securityDeposit,
|
offer = client.createOffer(direction,
|
||||||
paymentAcctId,
|
currencyCode,
|
||||||
makerFeeCurrencyCode,
|
amount,
|
||||||
triggerPrice);
|
minAmount,
|
||||||
|
useMarketBasedPrice,
|
||||||
|
fixedPrice,
|
||||||
|
marketPriceMargin.doubleValue(),
|
||||||
|
securityDeposit,
|
||||||
|
paymentAcctId,
|
||||||
|
makerFeeCurrencyCode,
|
||||||
|
triggerPrice);
|
||||||
|
}
|
||||||
new TableBuilder(OFFER_TBL, offer).build().print(out);
|
new TableBuilder(OFFER_TBL, offer).build().print(out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case editoffer: {
|
case editoffer: {
|
||||||
var opts = new EditOfferOptionParser(args).parse();
|
var offerIdOpt = new OfferIdOptionParser(args, true).parse();
|
||||||
if (opts.isForHelp()) {
|
if (offerIdOpt.isForHelp()) {
|
||||||
out.println(client.getMethodHelp(method));
|
out.println(client.getMethodHelp(method));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var offerId = opts.getOfferId();
|
// What kind of offer is being edited? BSQ swaps cannot be edited.
|
||||||
|
var offerId = offerIdOpt.getOfferId();
|
||||||
|
var offerCategory = client.getMyOfferCategory(offerId);
|
||||||
|
if (offerCategory.equals(BSQ_SWAP))
|
||||||
|
throw new IllegalStateException("bsq swap offers cannot be edited,"
|
||||||
|
+ " but you may cancel them without forfeiting any funds");
|
||||||
|
|
||||||
|
var opts = new EditOfferOptionParser(args).parse();
|
||||||
var fixedPrice = opts.getFixedPrice();
|
var fixedPrice = opts.getFixedPrice();
|
||||||
var isUsingMktPriceMargin = opts.isUsingMktPriceMargin();
|
var isUsingMktPriceMargin = opts.isUsingMktPriceMargin();
|
||||||
var marketPriceMargin = opts.getMktPriceMarginAsBigDecimal();
|
var marketPriceMargin = opts.getMktPriceMarginAsBigDecimal();
|
||||||
|
@ -392,7 +410,7 @@ public class CliMain {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case getoffer: {
|
case getoffer: {
|
||||||
var opts = new GetOfferOptionParser(args).parse();
|
var opts = new OfferIdOptionParser(args).parse();
|
||||||
if (opts.isForHelp()) {
|
if (opts.isForHelp()) {
|
||||||
out.println(client.getMethodHelp(method));
|
out.println(client.getMethodHelp(method));
|
||||||
return;
|
return;
|
||||||
|
@ -403,7 +421,7 @@ public class CliMain {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case getmyoffer: {
|
case getmyoffer: {
|
||||||
var opts = new GetOfferOptionParser(args).parse();
|
var opts = new OfferIdOptionParser(args).parse();
|
||||||
if (opts.isForHelp()) {
|
if (opts.isForHelp()) {
|
||||||
out.println(client.getMethodHelp(method));
|
out.println(client.getMethodHelp(method));
|
||||||
return;
|
return;
|
||||||
|
@ -446,15 +464,25 @@ public class CliMain {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case takeoffer: {
|
case takeoffer: {
|
||||||
var opts = new TakeOfferOptionParser(args).parse();
|
var offerIdOpt = new OfferIdOptionParser(args, true).parse();
|
||||||
if (opts.isForHelp()) {
|
if (offerIdOpt.isForHelp()) {
|
||||||
out.println(client.getMethodHelp(method));
|
out.println(client.getMethodHelp(method));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var offerId = opts.getOfferId();
|
var offerId = offerIdOpt.getOfferId();
|
||||||
var paymentAccountId = opts.getPaymentAccountId();
|
TradeInfo trade;
|
||||||
var takerFeeCurrencyCode = opts.getTakerFeeCurrencyCode();
|
// We only send an 'offer-id' param when taking a BsqSwapOffer.
|
||||||
var trade = client.takeOffer(offerId, paymentAccountId, takerFeeCurrencyCode);
|
// Find out what kind of offer is being taken before sending a
|
||||||
|
// 'takeoffer' request.
|
||||||
|
var offerCategory = client.getAvailableOfferCategory(offerId);
|
||||||
|
if (offerCategory.equals(BSQ_SWAP)) {
|
||||||
|
trade = client.takeBsqSwapOffer(offerId);
|
||||||
|
} else {
|
||||||
|
var opts = new TakeOfferOptionParser(args).parse();
|
||||||
|
var paymentAccountId = opts.getPaymentAccountId();
|
||||||
|
var takerFeeCurrencyCode = opts.getTakerFeeCurrencyCode();
|
||||||
|
trade = client.takeOffer(offerId, paymentAccountId, takerFeeCurrencyCode);
|
||||||
|
}
|
||||||
out.printf("trade %s successfully taken%n", trade.getTradeId());
|
out.printf("trade %s successfully taken%n", trade.getTradeId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -801,10 +829,11 @@ public class CliMain {
|
||||||
stream.format(rowFormat, "", "--currency-code=<currency-code> \\", "");
|
stream.format(rowFormat, "", "--currency-code=<currency-code> \\", "");
|
||||||
stream.format(rowFormat, "", "--amount=<btc-amount> \\", "");
|
stream.format(rowFormat, "", "--amount=<btc-amount> \\", "");
|
||||||
stream.format(rowFormat, "", "[--min-amount=<min-btc-amount>] \\", "");
|
stream.format(rowFormat, "", "[--min-amount=<min-btc-amount>] \\", "");
|
||||||
stream.format(rowFormat, "", "--fixed-price=<price> | --market-price=margin=<percent> \\", "");
|
stream.format(rowFormat, "", "--fixed-price=<price> | --market-price-margin=<percent> \\", "");
|
||||||
stream.format(rowFormat, "", "--security-deposit=<percent> \\", "");
|
stream.format(rowFormat, "", "--security-deposit=<percent> \\", "");
|
||||||
stream.format(rowFormat, "", "[--fee-currency=<bsq|btc>]", "");
|
stream.format(rowFormat, "", "[--fee-currency=<bsq|btc>]", "");
|
||||||
stream.format(rowFormat, "", "[--trigger-price=<price>]", "");
|
stream.format(rowFormat, "", "[--trigger-price=<price>]", "");
|
||||||
|
stream.format(rowFormat, "", "[--swap=<true|false>]", "");
|
||||||
stream.println();
|
stream.println();
|
||||||
stream.format(rowFormat, editoffer.name(), "--offer-id=<offer-id> \\", "Edit offer with id");
|
stream.format(rowFormat, editoffer.name(), "--offer-id=<offer-id> \\", "Edit offer with id");
|
||||||
stream.format(rowFormat, "", "[--fixed-price=<price>] \\", "");
|
stream.format(rowFormat, "", "[--fixed-price=<price>] \\", "");
|
||||||
|
@ -825,7 +854,7 @@ public class CliMain {
|
||||||
stream.format(rowFormat, "", "--currency-code=<currency-code>", "");
|
stream.format(rowFormat, "", "--currency-code=<currency-code>", "");
|
||||||
stream.println();
|
stream.println();
|
||||||
stream.format(rowFormat, takeoffer.name(), "--offer-id=<offer-id> \\", "Take offer with id");
|
stream.format(rowFormat, takeoffer.name(), "--offer-id=<offer-id> \\", "Take offer with id");
|
||||||
stream.format(rowFormat, "", "--payment-account=<payment-account-id>", "");
|
stream.format(rowFormat, "", "[--payment-account=<payment-account-id>]", "");
|
||||||
stream.format(rowFormat, "", "[--fee-currency=<btc|bsq>]", "");
|
stream.format(rowFormat, "", "[--fee-currency=<btc|bsq>]", "");
|
||||||
stream.println();
|
stream.println();
|
||||||
stream.format(rowFormat, gettrade.name(), "--trade-id=<trade-id> \\", "Get trade summary or full contract");
|
stream.format(rowFormat, gettrade.name(), "--trade-id=<trade-id> \\", "Get trade summary or full contract");
|
||||||
|
|
|
@ -20,17 +20,12 @@ package bisq.cli;
|
||||||
import bisq.proto.grpc.AddressBalanceInfo;
|
import bisq.proto.grpc.AddressBalanceInfo;
|
||||||
import bisq.proto.grpc.BalancesInfo;
|
import bisq.proto.grpc.BalancesInfo;
|
||||||
import bisq.proto.grpc.BsqBalanceInfo;
|
import bisq.proto.grpc.BsqBalanceInfo;
|
||||||
import bisq.proto.grpc.BsqSwapOfferInfo;
|
|
||||||
import bisq.proto.grpc.BsqSwapTradeInfo;
|
|
||||||
import bisq.proto.grpc.BtcBalanceInfo;
|
import bisq.proto.grpc.BtcBalanceInfo;
|
||||||
import bisq.proto.grpc.CreateBsqSwapOfferRequest;
|
|
||||||
import bisq.proto.grpc.GetMethodHelpRequest;
|
import bisq.proto.grpc.GetMethodHelpRequest;
|
||||||
import bisq.proto.grpc.GetVersionRequest;
|
import bisq.proto.grpc.GetVersionRequest;
|
||||||
import bisq.proto.grpc.OfferInfo;
|
import bisq.proto.grpc.OfferInfo;
|
||||||
import bisq.proto.grpc.RegisterDisputeAgentRequest;
|
import bisq.proto.grpc.RegisterDisputeAgentRequest;
|
||||||
import bisq.proto.grpc.StopRequest;
|
import bisq.proto.grpc.StopRequest;
|
||||||
import bisq.proto.grpc.TakeBsqSwapOfferReply;
|
|
||||||
import bisq.proto.grpc.TakeBsqSwapOfferRequest;
|
|
||||||
import bisq.proto.grpc.TakeOfferReply;
|
import bisq.proto.grpc.TakeOfferReply;
|
||||||
import bisq.proto.grpc.TradeInfo;
|
import bisq.proto.grpc.TradeInfo;
|
||||||
import bisq.proto.grpc.TxFeeRateInfo;
|
import bisq.proto.grpc.TxFeeRateInfo;
|
||||||
|
@ -44,6 +39,7 @@ import java.util.List;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import static bisq.proto.grpc.EditOfferRequest.EditType;
|
import static bisq.proto.grpc.EditOfferRequest.EditType;
|
||||||
|
import static bisq.proto.grpc.GetOfferCategoryReply.OfferCategory;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,19 +138,22 @@ public final class GrpcClient {
|
||||||
return walletsServiceRequest.getTransaction(txId);
|
return walletsServiceRequest.getTransaction(txId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BsqSwapOfferInfo createBsqSwapOffer(String direction,
|
public OfferCategory getAvailableOfferCategory(String offerId) {
|
||||||
long amount,
|
return offersServiceRequest.getAvailableOfferCategory(offerId);
|
||||||
long minAmount,
|
}
|
||||||
String fixedPrice,
|
|
||||||
String paymentAcctId) {
|
public OfferCategory getMyOfferCategory(String offerId) {
|
||||||
var request = CreateBsqSwapOfferRequest.newBuilder()
|
return offersServiceRequest.getMyOfferCategory(offerId);
|
||||||
.setDirection(direction)
|
}
|
||||||
.setAmount(amount)
|
|
||||||
.setMinAmount(minAmount)
|
public OfferInfo createBsqSwapOffer(String direction,
|
||||||
.setPrice(fixedPrice)
|
long amount,
|
||||||
.setPaymentAccountId(paymentAcctId)
|
long minAmount,
|
||||||
.build();
|
String fixedPrice) {
|
||||||
return grpcStubs.offersService.createBsqSwapOffer(request).getBsqSwapOffer();
|
return offersServiceRequest.createBsqSwapOffer(direction,
|
||||||
|
amount,
|
||||||
|
minAmount,
|
||||||
|
fixedPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OfferInfo createFixedPricedOffer(String direction,
|
public OfferInfo createFixedPricedOffer(String direction,
|
||||||
|
@ -263,7 +262,7 @@ public final class GrpcClient {
|
||||||
offersServiceRequest.cancelOffer(offerId);
|
offersServiceRequest.cancelOffer(offerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BsqSwapOfferInfo getBsqSwapOffer(String offerId) {
|
public OfferInfo getBsqSwapOffer(String offerId) {
|
||||||
return offersServiceRequest.getBsqSwapOffer(offerId);
|
return offersServiceRequest.getBsqSwapOffer(offerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +270,7 @@ public final class GrpcClient {
|
||||||
return offersServiceRequest.getOffer(offerId);
|
return offersServiceRequest.getOffer(offerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BsqSwapOfferInfo getMyBsqSwapOffer(String offerId) {
|
public OfferInfo getMyBsqSwapOffer(String offerId) {
|
||||||
return offersServiceRequest.getMyBsqSwapOffer(offerId);
|
return offersServiceRequest.getMyBsqSwapOffer(offerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,8 +278,8 @@ public final class GrpcClient {
|
||||||
return offersServiceRequest.getMyOffer(offerId);
|
return offersServiceRequest.getMyOffer(offerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BsqSwapOfferInfo> getBsqSwapOffers(String direction, String currencyCode) {
|
public List<OfferInfo> getBsqSwapOffers(String direction) {
|
||||||
return offersServiceRequest.getBsqSwapOffers(direction, currencyCode);
|
return offersServiceRequest.getBsqSwapOffers(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<OfferInfo> getOffers(String direction, String currencyCode) {
|
public List<OfferInfo> getOffers(String direction, String currencyCode) {
|
||||||
|
@ -303,12 +302,12 @@ public final class GrpcClient {
|
||||||
return offersServiceRequest.getBsqOffersSortedByDate();
|
return offersServiceRequest.getBsqOffersSortedByDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BsqSwapOfferInfo> getBsqSwapOffersSortedByDate() {
|
public List<OfferInfo> getBsqSwapOffersSortedByDate() {
|
||||||
return offersServiceRequest.getBsqSwapOffersSortedByDate();
|
return offersServiceRequest.getBsqSwapOffersSortedByDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BsqSwapOfferInfo> getMyBsqSwapOffers(String direction, String currencyCode) {
|
public List<OfferInfo> getMyBsqSwapOffers(String direction) {
|
||||||
return offersServiceRequest.getMyBsqSwapOffers(direction, currencyCode);
|
return offersServiceRequest.getMyBsqSwapOffers(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<OfferInfo> getMyOffers(String direction, String currencyCode) {
|
public List<OfferInfo> getMyOffers(String direction, String currencyCode) {
|
||||||
|
@ -335,7 +334,7 @@ public final class GrpcClient {
|
||||||
return offersServiceRequest.getMyBsqOffersSortedByDate();
|
return offersServiceRequest.getMyBsqOffersSortedByDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BsqSwapOfferInfo> getMyBsqSwapBsqOffersSortedByDate() {
|
public List<OfferInfo> getMyBsqSwapBsqOffersSortedByDate() {
|
||||||
return offersServiceRequest.getMyBsqSwapOffersSortedByDate();
|
return offersServiceRequest.getMyBsqSwapOffersSortedByDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,45 +342,26 @@ public final class GrpcClient {
|
||||||
return offersServiceRequest.getMostRecentOffer(direction, currencyCode);
|
return offersServiceRequest.getMostRecentOffer(direction, currencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BsqSwapOfferInfo> sortBsqSwapOffersByDate(List<BsqSwapOfferInfo> offerInfoList) {
|
public List<OfferInfo> sortBsqSwapOffersByDate(List<OfferInfo> offers) {
|
||||||
return offersServiceRequest.sortBsqSwapOffersByDate(offerInfoList);
|
return offersServiceRequest.sortOffersByDate(offers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<OfferInfo> sortOffersByDate(List<OfferInfo> offerInfoList) {
|
public List<OfferInfo> sortOffersByDate(List<OfferInfo> offers) {
|
||||||
return offersServiceRequest.sortOffersByDate(offerInfoList);
|
return offersServiceRequest.sortOffersByDate(offers);
|
||||||
}
|
|
||||||
|
|
||||||
public TakeBsqSwapOfferReply getTakeBsqSwapOfferReply(String offerId,
|
|
||||||
String paymentAccountId,
|
|
||||||
String takerFeeCurrencyCode) {
|
|
||||||
var request = TakeBsqSwapOfferRequest.newBuilder()
|
|
||||||
.setOfferId(offerId)
|
|
||||||
.setPaymentAccountId(paymentAccountId)
|
|
||||||
.setTakerFeeCurrencyCode(takerFeeCurrencyCode)
|
|
||||||
.build();
|
|
||||||
return grpcStubs.tradesService.takeBsqSwapOffer(request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TakeOfferReply getTakeOfferReply(String offerId, String paymentAccountId, String takerFeeCurrencyCode) {
|
public TakeOfferReply getTakeOfferReply(String offerId, String paymentAccountId, String takerFeeCurrencyCode) {
|
||||||
return tradesServiceRequest.getTakeOfferReply(offerId, paymentAccountId, takerFeeCurrencyCode);
|
return tradesServiceRequest.getTakeOfferReply(offerId, paymentAccountId, takerFeeCurrencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BsqSwapTradeInfo takeBsqSwapOffer(String offerId, String paymentAccountId, String takerFeeCurrencyCode) {
|
public TradeInfo takeBsqSwapOffer(String offerId) {
|
||||||
var reply = getTakeBsqSwapOfferReply(offerId, paymentAccountId, takerFeeCurrencyCode);
|
return tradesServiceRequest.takeBsqSwapOffer(offerId);
|
||||||
if (reply.hasBsqSwapTrade())
|
|
||||||
return reply.getBsqSwapTrade();
|
|
||||||
else
|
|
||||||
throw new IllegalStateException(reply.getFailureReason().getDescription());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TradeInfo takeOffer(String offerId, String paymentAccountId, String takerFeeCurrencyCode) {
|
public TradeInfo takeOffer(String offerId, String paymentAccountId, String takerFeeCurrencyCode) {
|
||||||
return tradesServiceRequest.takeOffer(offerId, paymentAccountId, takerFeeCurrencyCode);
|
return tradesServiceRequest.takeOffer(offerId, paymentAccountId, takerFeeCurrencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BsqSwapTradeInfo getBsqSwapTrade(String tradeId) {
|
|
||||||
return tradesServiceRequest.getBsqSwapTrade(tradeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfo getTrade(String tradeId) {
|
public TradeInfo getTrade(String tradeId) {
|
||||||
return tradesServiceRequest.getTrade(tradeId);
|
return tradesServiceRequest.getTrade(tradeId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ abstract class AbstractMethodOptionParser implements MethodOpts {
|
||||||
|
|
||||||
protected final OptionParser parser = new OptionParser();
|
protected final OptionParser parser = new OptionParser();
|
||||||
|
|
||||||
// The help option for a specific api method, e.g., takeoffer -help.
|
// The help option for a specific api method, e.g., takeoffer --help.
|
||||||
protected final OptionSpec<Void> helpOpt = parser.accepts(OPT_HELP, "Print method help").forHelp();
|
protected final OptionSpec<Void> helpOpt = parser.accepts(OPT_HELP, "Print method help").forHelp();
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
|
@ -18,14 +18,7 @@
|
||||||
package bisq.cli.opts;
|
package bisq.cli.opts;
|
||||||
|
|
||||||
|
|
||||||
import joptsimple.OptionSpec;
|
public class CancelOfferOptionParser extends OfferIdOptionParser implements MethodOpts {
|
||||||
|
|
||||||
import static bisq.cli.opts.OptLabel.OPT_OFFER_ID;
|
|
||||||
|
|
||||||
public class CancelOfferOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
|
||||||
|
|
||||||
final OptionSpec<String> offerIdOpt = parser.accepts(OPT_OFFER_ID, "id of offer to cancel")
|
|
||||||
.withRequiredArg();
|
|
||||||
|
|
||||||
public CancelOfferOptionParser(String[] args) {
|
public CancelOfferOptionParser(String[] args) {
|
||||||
super(args);
|
super(args);
|
||||||
|
@ -34,12 +27,7 @@ public class CancelOfferOptionParser extends AbstractMethodOptionParser implemen
|
||||||
public CancelOfferOptionParser parse() {
|
public CancelOfferOptionParser parse() {
|
||||||
super.parse();
|
super.parse();
|
||||||
|
|
||||||
// Short circuit opt validation if user just wants help.
|
// Super class will short-circuit parsing if help option is present.
|
||||||
if (options.has(helpOpt))
|
|
||||||
return this;
|
|
||||||
|
|
||||||
if (!options.has(offerIdOpt) || options.valueOf(offerIdOpt).isEmpty())
|
|
||||||
throw new IllegalArgumentException("no offer id specified");
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import static bisq.cli.opts.OptLabel.OPT_ACCOUNT_NAME;
|
||||||
import static bisq.cli.opts.OptLabel.OPT_ADDRESS;
|
import static bisq.cli.opts.OptLabel.OPT_ADDRESS;
|
||||||
import static bisq.cli.opts.OptLabel.OPT_CURRENCY_CODE;
|
import static bisq.cli.opts.OptLabel.OPT_CURRENCY_CODE;
|
||||||
import static bisq.cli.opts.OptLabel.OPT_TRADE_INSTANT;
|
import static bisq.cli.opts.OptLabel.OPT_TRADE_INSTANT;
|
||||||
|
import static java.lang.Boolean.FALSE;
|
||||||
|
|
||||||
public class CreateCryptoCurrencyPaymentAcctOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
public class CreateCryptoCurrencyPaymentAcctOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ public class CreateCryptoCurrencyPaymentAcctOptionParser extends AbstractMethodO
|
||||||
final OptionSpec<Boolean> tradeInstantOpt = parser.accepts(OPT_TRADE_INSTANT, "create trade instant account")
|
final OptionSpec<Boolean> tradeInstantOpt = parser.accepts(OPT_TRADE_INSTANT, "create trade instant account")
|
||||||
.withOptionalArg()
|
.withOptionalArg()
|
||||||
.ofType(boolean.class)
|
.ofType(boolean.class)
|
||||||
.defaultsTo(Boolean.FALSE);
|
.defaultsTo(FALSE);
|
||||||
|
|
||||||
public CreateCryptoCurrencyPaymentAcctOptionParser(String[] args) {
|
public CreateCryptoCurrencyPaymentAcctOptionParser(String[] args) {
|
||||||
super(args);
|
super(args);
|
||||||
|
|
|
@ -23,12 +23,13 @@ import joptsimple.OptionSpec;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
import static bisq.cli.opts.OptLabel.*;
|
import static bisq.cli.opts.OptLabel.*;
|
||||||
|
import static java.lang.Boolean.FALSE;
|
||||||
import static joptsimple.internal.Strings.EMPTY;
|
import static joptsimple.internal.Strings.EMPTY;
|
||||||
|
|
||||||
public class CreateOfferOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
public class CreateOfferOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
||||||
|
|
||||||
final OptionSpec<String> paymentAccountIdOpt = parser.accepts(OPT_PAYMENT_ACCOUNT,
|
final OptionSpec<String> paymentAccountIdOpt = parser.accepts(OPT_PAYMENT_ACCOUNT,
|
||||||
"id of payment account used for offer")
|
"id of payment account used for offer")
|
||||||
.withRequiredArg()
|
.withRequiredArg()
|
||||||
.defaultsTo(EMPTY);
|
.defaultsTo(EMPTY);
|
||||||
|
|
||||||
|
@ -59,6 +60,11 @@ public class CreateOfferOptionParser extends AbstractMethodOptionParser implemen
|
||||||
.withOptionalArg()
|
.withOptionalArg()
|
||||||
.defaultsTo("btc");
|
.defaultsTo("btc");
|
||||||
|
|
||||||
|
final OptionSpec<Boolean> isSwapOpt = parser.accepts(OPT_SWAP, "create bsq swap offer")
|
||||||
|
.withOptionalArg()
|
||||||
|
.ofType(boolean.class)
|
||||||
|
.defaultsTo(FALSE);
|
||||||
|
|
||||||
public CreateOfferOptionParser(String[] args) {
|
public CreateOfferOptionParser(String[] args) {
|
||||||
super(args);
|
super(args);
|
||||||
}
|
}
|
||||||
|
@ -70,9 +76,6 @@ public class CreateOfferOptionParser extends AbstractMethodOptionParser implemen
|
||||||
if (options.has(helpOpt))
|
if (options.has(helpOpt))
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
if (!options.has(paymentAccountIdOpt) || options.valueOf(paymentAccountIdOpt).isEmpty())
|
|
||||||
throw new IllegalArgumentException("no payment account id specified");
|
|
||||||
|
|
||||||
if (!options.has(directionOpt) || options.valueOf(directionOpt).isEmpty())
|
if (!options.has(directionOpt) || options.valueOf(directionOpt).isEmpty())
|
||||||
throw new IllegalArgumentException("no direction (buy|sell) specified");
|
throw new IllegalArgumentException("no direction (buy|sell) specified");
|
||||||
|
|
||||||
|
@ -82,17 +85,38 @@ public class CreateOfferOptionParser extends AbstractMethodOptionParser implemen
|
||||||
if (!options.has(amountOpt) || options.valueOf(amountOpt).isEmpty())
|
if (!options.has(amountOpt) || options.valueOf(amountOpt).isEmpty())
|
||||||
throw new IllegalArgumentException("no btc amount specified");
|
throw new IllegalArgumentException("no btc amount specified");
|
||||||
|
|
||||||
if (!options.has(mktPriceMarginOpt) && !options.has(fixedPriceOpt))
|
if (getIsSwap()) {
|
||||||
throw new IllegalArgumentException("no market price margin or fixed price specified");
|
if (!options.valueOf(currencyCodeOpt).equalsIgnoreCase("bsq"))
|
||||||
|
throw new IllegalArgumentException("only bsq swaps are currently supported");
|
||||||
|
|
||||||
if (options.has(mktPriceMarginOpt) && options.valueOf(mktPriceMarginOpt).isEmpty())
|
if (options.has(paymentAccountIdOpt))
|
||||||
throw new IllegalArgumentException("no market price margin specified");
|
throw new IllegalArgumentException("cannot use a payment account id in bsq swap offer");
|
||||||
|
|
||||||
if (options.has(fixedPriceOpt) && options.valueOf(fixedPriceOpt).isEmpty())
|
if (options.has(mktPriceMarginOpt))
|
||||||
throw new IllegalArgumentException("no fixed price specified");
|
throw new IllegalArgumentException("cannot use a market price margin in bsq swap offer");
|
||||||
|
|
||||||
if (!options.has(securityDepositOpt) || options.valueOf(securityDepositOpt).isEmpty())
|
if (options.has(securityDepositOpt))
|
||||||
throw new IllegalArgumentException("no security deposit specified");
|
throw new IllegalArgumentException("cannot use a security deposit in bsq swap offer");
|
||||||
|
|
||||||
|
if (!options.has(fixedPriceOpt) || options.valueOf(fixedPriceOpt).isEmpty())
|
||||||
|
throw new IllegalArgumentException("no fixed price specified");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (!options.has(paymentAccountIdOpt) || options.valueOf(paymentAccountIdOpt).isEmpty())
|
||||||
|
throw new IllegalArgumentException("no payment account id specified");
|
||||||
|
|
||||||
|
if (!options.has(mktPriceMarginOpt) && !options.has(fixedPriceOpt))
|
||||||
|
throw new IllegalArgumentException("no market price margin or fixed price specified");
|
||||||
|
|
||||||
|
if (options.has(mktPriceMarginOpt) && options.valueOf(mktPriceMarginOpt).isEmpty())
|
||||||
|
throw new IllegalArgumentException("no market price margin specified");
|
||||||
|
|
||||||
|
if (options.has(fixedPriceOpt) && options.valueOf(fixedPriceOpt).isEmpty())
|
||||||
|
throw new IllegalArgumentException("no fixed price specified");
|
||||||
|
|
||||||
|
if (!options.has(securityDepositOpt) || options.valueOf(securityDepositOpt).isEmpty())
|
||||||
|
throw new IllegalArgumentException("no security deposit specified");
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -141,4 +165,8 @@ public class CreateOfferOptionParser extends AbstractMethodOptionParser implemen
|
||||||
public String getMakerFeeCurrencyCode() {
|
public String getMakerFeeCurrencyCode() {
|
||||||
return options.has(makerFeeCurrencyCodeOpt) ? options.valueOf(makerFeeCurrencyCodeOpt) : "btc";
|
return options.has(makerFeeCurrencyCodeOpt) ? options.valueOf(makerFeeCurrencyCodeOpt) : "btc";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getIsSwap() {
|
||||||
|
return options.valueOf(isSwapOpt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import static java.lang.String.format;
|
||||||
public class CreatePaymentAcctOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
public class CreatePaymentAcctOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
||||||
|
|
||||||
final OptionSpec<String> paymentAcctFormPathOpt = parser.accepts(OPT_PAYMENT_ACCOUNT_FORM,
|
final OptionSpec<String> paymentAcctFormPathOpt = parser.accepts(OPT_PAYMENT_ACCOUNT_FORM,
|
||||||
"path to json payment account form")
|
"path to json payment account form")
|
||||||
.withRequiredArg();
|
.withRequiredArg();
|
||||||
|
|
||||||
public CreatePaymentAcctOptionParser(String[] args) {
|
public CreatePaymentAcctOptionParser(String[] args) {
|
||||||
|
|
|
@ -24,7 +24,10 @@ import joptsimple.OptionSpec;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
import static bisq.cli.opts.OptLabel.*;
|
import static bisq.cli.opts.OptLabel.OPT_ENABLE;
|
||||||
|
import static bisq.cli.opts.OptLabel.OPT_FIXED_PRICE;
|
||||||
|
import static bisq.cli.opts.OptLabel.OPT_MKT_PRICE_MARGIN;
|
||||||
|
import static bisq.cli.opts.OptLabel.OPT_TRIGGER_PRICE;
|
||||||
import static bisq.proto.grpc.EditOfferRequest.EditType.*;
|
import static bisq.proto.grpc.EditOfferRequest.EditType.*;
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
|
|
||||||
|
@ -32,26 +35,23 @@ import static java.lang.String.format;
|
||||||
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class EditOfferOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
public class EditOfferOptionParser extends OfferIdOptionParser implements MethodOpts {
|
||||||
|
|
||||||
static int OPT_ENABLE_ON = 1;
|
static int OPT_ENABLE_ON = 1;
|
||||||
static int OPT_ENABLE_OFF = 0;
|
static int OPT_ENABLE_OFF = 0;
|
||||||
static int OPT_ENABLE_IGNORED = -1;
|
static int OPT_ENABLE_IGNORED = -1;
|
||||||
|
|
||||||
final OptionSpec<String> offerIdOpt = parser.accepts(OPT_OFFER_ID, "id of offer to cancel")
|
|
||||||
.withRequiredArg();
|
|
||||||
|
|
||||||
final OptionSpec<String> fixedPriceOpt = parser.accepts(OPT_FIXED_PRICE, "fixed btc price")
|
final OptionSpec<String> fixedPriceOpt = parser.accepts(OPT_FIXED_PRICE, "fixed btc price")
|
||||||
.withOptionalArg()
|
.withOptionalArg()
|
||||||
.defaultsTo("0");
|
.defaultsTo("0");
|
||||||
|
|
||||||
final OptionSpec<String> mktPriceMarginOpt = parser.accepts(OPT_MKT_PRICE_MARGIN,
|
final OptionSpec<String> mktPriceMarginOpt = parser.accepts(OPT_MKT_PRICE_MARGIN,
|
||||||
"market btc price margin (%)")
|
"market btc price margin (%)")
|
||||||
.withOptionalArg()
|
.withOptionalArg()
|
||||||
.defaultsTo("0.00");
|
.defaultsTo("0.00");
|
||||||
|
|
||||||
final OptionSpec<String> triggerPriceOpt = parser.accepts(OPT_TRIGGER_PRICE,
|
final OptionSpec<String> triggerPriceOpt = parser.accepts(OPT_TRIGGER_PRICE,
|
||||||
"trigger price (applies to mkt price margin based offers)")
|
"trigger price (applies to mkt price margin based offers)")
|
||||||
.withOptionalArg()
|
.withOptionalArg()
|
||||||
.defaultsTo("0");
|
.defaultsTo("0");
|
||||||
|
|
||||||
|
@ -59,25 +59,20 @@ public class EditOfferOptionParser extends AbstractMethodOptionParser implements
|
||||||
// activation state). For this reason, a boolean type is not used (can only be
|
// activation state). For this reason, a boolean type is not used (can only be
|
||||||
// true or false).
|
// true or false).
|
||||||
final OptionSpec<String> enableOpt = parser.accepts(OPT_ENABLE,
|
final OptionSpec<String> enableOpt = parser.accepts(OPT_ENABLE,
|
||||||
"enable or disable offer")
|
"enable or disable offer")
|
||||||
.withOptionalArg()
|
.withOptionalArg()
|
||||||
.ofType(String.class);
|
.ofType(String.class);
|
||||||
|
|
||||||
private EditOfferRequest.EditType offerEditType;
|
private EditOfferRequest.EditType offerEditType;
|
||||||
|
|
||||||
public EditOfferOptionParser(String[] args) {
|
public EditOfferOptionParser(String[] args) {
|
||||||
super(args);
|
super(args, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EditOfferOptionParser parse() {
|
public EditOfferOptionParser parse() {
|
||||||
super.parse();
|
super.parse();
|
||||||
|
|
||||||
// Short circuit opt validation if user just wants help.
|
// Super class will short-circuit parsing if help option is present.
|
||||||
if (options.has(helpOpt))
|
|
||||||
return this;
|
|
||||||
|
|
||||||
if (!options.has(offerIdOpt) || options.valueOf(offerIdOpt).isEmpty())
|
|
||||||
throw new IllegalArgumentException("no offer id specified");
|
|
||||||
|
|
||||||
boolean hasNoEditDetails = !options.has(fixedPriceOpt)
|
boolean hasNoEditDetails = !options.has(fixedPriceOpt)
|
||||||
&& !options.has(mktPriceMarginOpt)
|
&& !options.has(mktPriceMarginOpt)
|
||||||
|
@ -201,10 +196,6 @@ public class EditOfferOptionParser extends AbstractMethodOptionParser implements
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOfferId() {
|
|
||||||
return options.valueOf(offerIdOpt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFixedPrice() {
|
public String getFixedPrice() {
|
||||||
if (offerEditType.equals(FIXED_PRICE_ONLY) || offerEditType.equals(FIXED_PRICE_AND_ACTIVATION_STATE)) {
|
if (offerEditType.equals(FIXED_PRICE_ONLY) || offerEditType.equals(FIXED_PRICE_AND_ACTIVATION_STATE)) {
|
||||||
return options.has(fixedPriceOpt) ? options.valueOf(fixedPriceOpt) : "0";
|
return options.has(fixedPriceOpt) ? options.valueOf(fixedPriceOpt) : "0";
|
||||||
|
|
|
@ -25,7 +25,7 @@ import static bisq.cli.opts.OptLabel.OPT_PAYMENT_METHOD_ID;
|
||||||
public class GetPaymentAcctFormOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
public class GetPaymentAcctFormOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
||||||
|
|
||||||
final OptionSpec<String> paymentMethodIdOpt = parser.accepts(OPT_PAYMENT_METHOD_ID,
|
final OptionSpec<String> paymentMethodIdOpt = parser.accepts(OPT_PAYMENT_METHOD_ID,
|
||||||
"id of payment method type used by a payment account")
|
"id of payment method type used by a payment account")
|
||||||
.withRequiredArg();
|
.withRequiredArg();
|
||||||
|
|
||||||
public GetPaymentAcctFormOptionParser(String[] args) {
|
public GetPaymentAcctFormOptionParser(String[] args) {
|
||||||
|
|
|
@ -22,16 +22,26 @@ import joptsimple.OptionSpec;
|
||||||
|
|
||||||
import static bisq.cli.opts.OptLabel.OPT_OFFER_ID;
|
import static bisq.cli.opts.OptLabel.OPT_OFFER_ID;
|
||||||
|
|
||||||
public class GetOfferOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
/**
|
||||||
|
* Superclass for option parsers requiring an offer-id. Avoids a small amount of
|
||||||
|
* duplicated boilerplate.
|
||||||
|
*/
|
||||||
|
public class OfferIdOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
||||||
|
|
||||||
final OptionSpec<String> offerIdOpt = parser.accepts(OPT_OFFER_ID, "id of offer to get")
|
final OptionSpec<String> offerIdOpt = parser.accepts(OPT_OFFER_ID, "id of offer")
|
||||||
.withRequiredArg();
|
.withRequiredArg();
|
||||||
|
|
||||||
public GetOfferOptionParser(String[] args) {
|
public OfferIdOptionParser(String[] args) {
|
||||||
super(args);
|
this(args, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GetOfferOptionParser parse() {
|
public OfferIdOptionParser(String[] args, boolean allowsUnrecognizedOptions) {
|
||||||
|
super(args);
|
||||||
|
if (allowsUnrecognizedOptions)
|
||||||
|
this.parser.allowsUnrecognizedOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferIdOptionParser parse() {
|
||||||
super.parse();
|
super.parse();
|
||||||
|
|
||||||
// Short circuit opt validation if user just wants help.
|
// Short circuit opt validation if user just wants help.
|
|
@ -44,6 +44,7 @@ public class OptLabel {
|
||||||
public final static String OPT_REGISTRATION_KEY = "registration-key";
|
public final static String OPT_REGISTRATION_KEY = "registration-key";
|
||||||
public final static String OPT_SECURITY_DEPOSIT = "security-deposit";
|
public final static String OPT_SECURITY_DEPOSIT = "security-deposit";
|
||||||
public final static String OPT_SHOW_CONTRACT = "show-contract";
|
public final static String OPT_SHOW_CONTRACT = "show-contract";
|
||||||
|
public final static String OPT_SWAP = "swap";
|
||||||
public final static String OPT_TRADE_ID = "trade-id";
|
public final static String OPT_TRADE_ID = "trade-id";
|
||||||
public final static String OPT_TRADE_INSTANT = "trade-instant";
|
public final static String OPT_TRADE_INSTANT = "trade-instant";
|
||||||
public final static String OPT_TIMEOUT = "timeout";
|
public final static String OPT_TIMEOUT = "timeout";
|
||||||
|
|
|
@ -25,7 +25,7 @@ import static bisq.cli.opts.OptLabel.OPT_TX_FEE_RATE;
|
||||||
public class SetTxFeeRateOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
public class SetTxFeeRateOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
||||||
|
|
||||||
final OptionSpec<String> feeRateOpt = parser.accepts(OPT_TX_FEE_RATE,
|
final OptionSpec<String> feeRateOpt = parser.accepts(OPT_TX_FEE_RATE,
|
||||||
"tx fee rate preference (sats/byte)")
|
"tx fee rate preference (sats/byte)")
|
||||||
.withRequiredArg();
|
.withRequiredArg();
|
||||||
|
|
||||||
public SetTxFeeRateOptionParser(String[] args) {
|
public SetTxFeeRateOptionParser(String[] args) {
|
||||||
|
|
|
@ -21,13 +21,9 @@ package bisq.cli.opts;
|
||||||
import joptsimple.OptionSpec;
|
import joptsimple.OptionSpec;
|
||||||
|
|
||||||
import static bisq.cli.opts.OptLabel.OPT_FEE_CURRENCY;
|
import static bisq.cli.opts.OptLabel.OPT_FEE_CURRENCY;
|
||||||
import static bisq.cli.opts.OptLabel.OPT_OFFER_ID;
|
|
||||||
import static bisq.cli.opts.OptLabel.OPT_PAYMENT_ACCOUNT;
|
import static bisq.cli.opts.OptLabel.OPT_PAYMENT_ACCOUNT;
|
||||||
|
|
||||||
public class TakeOfferOptionParser extends AbstractMethodOptionParser implements MethodOpts {
|
public class TakeOfferOptionParser extends OfferIdOptionParser implements MethodOpts {
|
||||||
|
|
||||||
final OptionSpec<String> offerIdOpt = parser.accepts(OPT_OFFER_ID, "id of offer to take")
|
|
||||||
.withRequiredArg();
|
|
||||||
|
|
||||||
final OptionSpec<String> paymentAccountIdOpt = parser.accepts(OPT_PAYMENT_ACCOUNT, "id of payment account used for trade")
|
final OptionSpec<String> paymentAccountIdOpt = parser.accepts(OPT_PAYMENT_ACCOUNT, "id of payment account used for trade")
|
||||||
.withRequiredArg();
|
.withRequiredArg();
|
||||||
|
@ -37,18 +33,13 @@ public class TakeOfferOptionParser extends AbstractMethodOptionParser implements
|
||||||
.defaultsTo("btc");
|
.defaultsTo("btc");
|
||||||
|
|
||||||
public TakeOfferOptionParser(String[] args) {
|
public TakeOfferOptionParser(String[] args) {
|
||||||
super(args);
|
super(args, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TakeOfferOptionParser parse() {
|
public TakeOfferOptionParser parse() {
|
||||||
super.parse();
|
super.parse();
|
||||||
|
|
||||||
// Short circuit opt validation if user just wants help.
|
// Super class will short-circuit parsing if help option is present.
|
||||||
if (options.has(helpOpt))
|
|
||||||
return this;
|
|
||||||
|
|
||||||
if (!options.has(offerIdOpt) || options.valueOf(offerIdOpt).isEmpty())
|
|
||||||
throw new IllegalArgumentException("no offer id specified");
|
|
||||||
|
|
||||||
if (!options.has(paymentAccountIdOpt) || options.valueOf(paymentAccountIdOpt).isEmpty())
|
if (!options.has(paymentAccountIdOpt) || options.valueOf(paymentAccountIdOpt).isEmpty())
|
||||||
throw new IllegalArgumentException("no payment account id specified");
|
throw new IllegalArgumentException("no payment account id specified");
|
||||||
|
@ -56,10 +47,6 @@ public class TakeOfferOptionParser extends AbstractMethodOptionParser implements
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOfferId() {
|
|
||||||
return options.valueOf(offerIdOpt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPaymentAccountId() {
|
public String getPaymentAccountId() {
|
||||||
return options.valueOf(paymentAccountIdOpt);
|
return options.valueOf(paymentAccountIdOpt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,14 @@
|
||||||
|
|
||||||
package bisq.cli.request;
|
package bisq.cli.request;
|
||||||
|
|
||||||
import bisq.proto.grpc.BsqSwapOfferInfo;
|
|
||||||
import bisq.proto.grpc.CancelOfferRequest;
|
import bisq.proto.grpc.CancelOfferRequest;
|
||||||
|
import bisq.proto.grpc.CreateBsqSwapOfferRequest;
|
||||||
import bisq.proto.grpc.CreateOfferRequest;
|
import bisq.proto.grpc.CreateOfferRequest;
|
||||||
import bisq.proto.grpc.EditOfferRequest;
|
import bisq.proto.grpc.EditOfferRequest;
|
||||||
|
import bisq.proto.grpc.GetBsqSwapOffersRequest;
|
||||||
import bisq.proto.grpc.GetMyOfferRequest;
|
import bisq.proto.grpc.GetMyOfferRequest;
|
||||||
import bisq.proto.grpc.GetMyOffersRequest;
|
import bisq.proto.grpc.GetMyOffersRequest;
|
||||||
|
import bisq.proto.grpc.GetOfferCategoryRequest;
|
||||||
import bisq.proto.grpc.GetOfferRequest;
|
import bisq.proto.grpc.GetOfferRequest;
|
||||||
import bisq.proto.grpc.GetOffersRequest;
|
import bisq.proto.grpc.GetOffersRequest;
|
||||||
import bisq.proto.grpc.OfferInfo;
|
import bisq.proto.grpc.OfferInfo;
|
||||||
|
@ -37,6 +39,7 @@ import static bisq.proto.grpc.EditOfferRequest.EditType.ACTIVATION_STATE_ONLY;
|
||||||
import static bisq.proto.grpc.EditOfferRequest.EditType.FIXED_PRICE_ONLY;
|
import static bisq.proto.grpc.EditOfferRequest.EditType.FIXED_PRICE_ONLY;
|
||||||
import static bisq.proto.grpc.EditOfferRequest.EditType.MKT_PRICE_MARGIN_ONLY;
|
import static bisq.proto.grpc.EditOfferRequest.EditType.MKT_PRICE_MARGIN_ONLY;
|
||||||
import static bisq.proto.grpc.EditOfferRequest.EditType.TRIGGER_PRICE_ONLY;
|
import static bisq.proto.grpc.EditOfferRequest.EditType.TRIGGER_PRICE_ONLY;
|
||||||
|
import static bisq.proto.grpc.GetOfferCategoryReply.OfferCategory;
|
||||||
import static java.util.Comparator.comparing;
|
import static java.util.Comparator.comparing;
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
import static protobuf.OfferDirection.BUY;
|
import static protobuf.OfferDirection.BUY;
|
||||||
|
@ -60,6 +63,27 @@ public class OffersServiceRequest {
|
||||||
this.grpcStubs = grpcStubs;
|
this.grpcStubs = grpcStubs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OfferCategory getAvailableOfferCategory(String offerId) {
|
||||||
|
return getOfferCategory(offerId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferCategory getMyOfferCategory(String offerId) {
|
||||||
|
return getOfferCategory(offerId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfo createBsqSwapOffer(String direction,
|
||||||
|
long amount,
|
||||||
|
long minAmount,
|
||||||
|
String fixedPrice) {
|
||||||
|
var request = CreateBsqSwapOfferRequest.newBuilder()
|
||||||
|
.setDirection(direction)
|
||||||
|
.setAmount(amount)
|
||||||
|
.setMinAmount(minAmount)
|
||||||
|
.setPrice(fixedPrice)
|
||||||
|
.build();
|
||||||
|
return grpcStubs.offersService.createBsqSwapOffer(request).getBsqSwapOffer();
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public OfferInfo createFixedPricedOffer(String direction,
|
public OfferInfo createFixedPricedOffer(String direction,
|
||||||
String currencyCode,
|
String currencyCode,
|
||||||
|
@ -210,7 +234,7 @@ public class OffersServiceRequest {
|
||||||
grpcStubs.offersService.cancelOffer(request);
|
grpcStubs.offersService.cancelOffer(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BsqSwapOfferInfo getBsqSwapOffer(String offerId) {
|
public OfferInfo getBsqSwapOffer(String offerId) {
|
||||||
var request = GetOfferRequest.newBuilder()
|
var request = GetOfferRequest.newBuilder()
|
||||||
.setId(offerId)
|
.setId(offerId)
|
||||||
.build();
|
.build();
|
||||||
|
@ -224,7 +248,7 @@ public class OffersServiceRequest {
|
||||||
return grpcStubs.offersService.getOffer(request).getOffer();
|
return grpcStubs.offersService.getOffer(request).getOffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BsqSwapOfferInfo getMyBsqSwapOffer(String offerId) {
|
public OfferInfo getMyBsqSwapOffer(String offerId) {
|
||||||
var request = GetMyOfferRequest.newBuilder()
|
var request = GetMyOfferRequest.newBuilder()
|
||||||
.setId(offerId)
|
.setId(offerId)
|
||||||
.build();
|
.build();
|
||||||
|
@ -239,10 +263,9 @@ public class OffersServiceRequest {
|
||||||
return grpcStubs.offersService.getMyOffer(request).getOffer();
|
return grpcStubs.offersService.getMyOffer(request).getOffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BsqSwapOfferInfo> getBsqSwapOffers(String direction, String currencyCode) {
|
public List<OfferInfo> getBsqSwapOffers(String direction) {
|
||||||
var request = GetOffersRequest.newBuilder()
|
var request = GetBsqSwapOffersRequest.newBuilder()
|
||||||
.setDirection(direction)
|
.setDirection(direction)
|
||||||
.setCurrencyCode(currencyCode)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return grpcStubs.offersService.getBsqSwapOffers(request).getBsqSwapOffersList();
|
return grpcStubs.offersService.getBsqSwapOffers(request).getBsqSwapOffersList();
|
||||||
|
@ -278,11 +301,11 @@ public class OffersServiceRequest {
|
||||||
return offers.isEmpty() ? offers : sortOffersByDate(offers);
|
return offers.isEmpty() ? offers : sortOffersByDate(offers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BsqSwapOfferInfo> getBsqSwapOffersSortedByDate() {
|
public List<OfferInfo> getBsqSwapOffersSortedByDate() {
|
||||||
ArrayList<BsqSwapOfferInfo> offers = new ArrayList<>();
|
ArrayList<OfferInfo> offers = new ArrayList<>();
|
||||||
offers.addAll(getBsqSwapOffers(BUY.name(), "BSQ"));
|
offers.addAll(getBsqSwapOffers(BUY.name()));
|
||||||
offers.addAll(getBsqSwapOffers(SELL.name(), "BSQ"));
|
offers.addAll(getBsqSwapOffers(SELL.name()));
|
||||||
return sortBsqSwapOffersByDate(offers);
|
return sortOffersByDate(offers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<OfferInfo> getBsqOffersSortedByDate() {
|
public List<OfferInfo> getBsqOffersSortedByDate() {
|
||||||
|
@ -292,10 +315,9 @@ public class OffersServiceRequest {
|
||||||
return sortOffersByDate(offers);
|
return sortOffersByDate(offers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BsqSwapOfferInfo> getMyBsqSwapOffers(String direction, String currencyCode) {
|
public List<OfferInfo> getMyBsqSwapOffers(String direction) {
|
||||||
var request = GetMyOffersRequest.newBuilder()
|
var request = GetBsqSwapOffersRequest.newBuilder()
|
||||||
.setDirection(direction)
|
.setDirection(direction)
|
||||||
.setCurrencyCode(currencyCode)
|
|
||||||
.build();
|
.build();
|
||||||
return grpcStubs.offersService.getMyBsqSwapOffers(request).getBsqSwapOffersList();
|
return grpcStubs.offersService.getMyBsqSwapOffers(request).getBsqSwapOffersList();
|
||||||
}
|
}
|
||||||
|
@ -344,11 +366,11 @@ public class OffersServiceRequest {
|
||||||
return sortOffersByDate(offers);
|
return sortOffersByDate(offers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BsqSwapOfferInfo> getMyBsqSwapOffersSortedByDate() {
|
public List<OfferInfo> getMyBsqSwapOffersSortedByDate() {
|
||||||
ArrayList<BsqSwapOfferInfo> offers = new ArrayList<>();
|
ArrayList<OfferInfo> offers = new ArrayList<>();
|
||||||
offers.addAll(getMyBsqSwapOffers(BUY.name(), "BSQ"));
|
offers.addAll(getMyBsqSwapOffers(BUY.name()));
|
||||||
offers.addAll(getMyBsqSwapOffers(SELL.name(), "BSQ"));
|
offers.addAll(getMyBsqSwapOffers(SELL.name()));
|
||||||
return sortBsqSwapOffersByDate(offers);
|
return sortOffersByDate(offers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OfferInfo getMostRecentOffer(String direction, String currencyCode) {
|
public OfferInfo getMostRecentOffer(String direction, String currencyCode) {
|
||||||
|
@ -356,19 +378,20 @@ public class OffersServiceRequest {
|
||||||
return offers.isEmpty() ? null : offers.get(offers.size() - 1);
|
return offers.isEmpty() ? null : offers.get(offers.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BsqSwapOfferInfo> sortBsqSwapOffersByDate(List<BsqSwapOfferInfo> offerInfoList) {
|
|
||||||
return offerInfoList.stream()
|
|
||||||
.sorted(comparing(BsqSwapOfferInfo::getDate))
|
|
||||||
.collect(toList());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<OfferInfo> sortOffersByDate(List<OfferInfo> offerInfoList) {
|
public List<OfferInfo> sortOffersByDate(List<OfferInfo> offerInfoList) {
|
||||||
return offerInfoList.stream()
|
return offerInfoList.stream()
|
||||||
.sorted(comparing(OfferInfo::getDate))
|
.sorted(comparing(OfferInfo::getDate))
|
||||||
.collect(toList());
|
.collect(toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private OfferCategory getOfferCategory(String offerId, boolean isMyOffer) {
|
||||||
|
var request = GetOfferCategoryRequest.newBuilder()
|
||||||
|
.setId(offerId)
|
||||||
|
.setIsMyOffer(isMyOffer)
|
||||||
|
.build();
|
||||||
|
return grpcStubs.offersService.getOfferCategory(request).getOfferCategory();
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isSupportedCryptoCurrency(String currencyCode) {
|
private static boolean isSupportedCryptoCurrency(String currencyCode) {
|
||||||
return getSupportedCryptoCurrencies().contains(currencyCode.toUpperCase());
|
return getSupportedCryptoCurrencies().contains(currencyCode.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package bisq.cli.request;
|
package bisq.cli.request;
|
||||||
|
|
||||||
import bisq.proto.grpc.BsqSwapTradeInfo;
|
|
||||||
import bisq.proto.grpc.ConfirmPaymentReceivedRequest;
|
import bisq.proto.grpc.ConfirmPaymentReceivedRequest;
|
||||||
import bisq.proto.grpc.ConfirmPaymentStartedRequest;
|
import bisq.proto.grpc.ConfirmPaymentStartedRequest;
|
||||||
import bisq.proto.grpc.GetTradeRequest;
|
import bisq.proto.grpc.GetTradeRequest;
|
||||||
|
@ -48,19 +47,20 @@ public class TradesServiceRequest {
|
||||||
return grpcStubs.tradesService.takeOffer(request);
|
return grpcStubs.tradesService.takeOffer(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TradeInfo takeOffer(String offerId, String paymentAccountId, String takerFeeCurrencyCode) {
|
public TradeInfo takeBsqSwapOffer(String offerId) {
|
||||||
var reply = getTakeOfferReply(offerId, paymentAccountId, takerFeeCurrencyCode);
|
var reply = getTakeOfferReply(offerId, "", "");
|
||||||
if (reply.hasTrade())
|
if (reply.hasTrade())
|
||||||
return reply.getTrade();
|
return reply.getTrade();
|
||||||
else
|
else
|
||||||
throw new IllegalStateException(reply.getFailureReason().getDescription());
|
throw new IllegalStateException(reply.getFailureReason().getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
public BsqSwapTradeInfo getBsqSwapTrade(String tradeId) {
|
public TradeInfo takeOffer(String offerId, String paymentAccountId, String takerFeeCurrencyCode) {
|
||||||
var request = GetTradeRequest.newBuilder()
|
var reply = getTakeOfferReply(offerId, paymentAccountId, takerFeeCurrencyCode);
|
||||||
.setTradeId(tradeId)
|
if (reply.hasTrade())
|
||||||
.build();
|
return reply.getTrade();
|
||||||
return grpcStubs.tradesService.getBsqSwapTrade(request).getBsqSwapTrade();
|
else
|
||||||
|
throw new IllegalStateException(reply.getFailureReason().getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
public TradeInfo getTrade(String tradeId) {
|
public TradeInfo getTrade(String tradeId) {
|
||||||
|
|
|
@ -102,6 +102,15 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder {
|
||||||
@Nullable
|
@Nullable
|
||||||
protected final Column<String> colAltcoinReceiveAddressColumn;
|
protected final Column<String> colAltcoinReceiveAddressColumn;
|
||||||
|
|
||||||
|
// BSQ swap trade detail specific columns
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
protected final Column<String> status;
|
||||||
|
@Nullable
|
||||||
|
protected final Column<String> colTxId;
|
||||||
|
@Nullable
|
||||||
|
protected final Column<Long> colNumConfirmations;
|
||||||
|
|
||||||
AbstractTradeListBuilder(TableType tableType, List<?> protos) {
|
AbstractTradeListBuilder(TableType tableType, List<?> protos) {
|
||||||
super(tableType, protos);
|
super(tableType, protos);
|
||||||
validate();
|
validate();
|
||||||
|
@ -125,7 +134,9 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder {
|
||||||
this.colRole = colSupplier.roleColumn.get();
|
this.colRole = colSupplier.roleColumn.get();
|
||||||
this.colOfferType = colSupplier.offerTypeColumn.get();
|
this.colOfferType = colSupplier.offerTypeColumn.get();
|
||||||
this.colStatusDescription = colSupplier.statusDescriptionColumn.get();
|
this.colStatusDescription = colSupplier.statusDescriptionColumn.get();
|
||||||
// Trade detail specific columns
|
|
||||||
|
// Trade detail specific columns, some in common with BSQ swap trades detail.
|
||||||
|
|
||||||
this.colIsDepositPublished = colSupplier.depositPublishedColumn.get();
|
this.colIsDepositPublished = colSupplier.depositPublishedColumn.get();
|
||||||
this.colIsDepositConfirmed = colSupplier.depositConfirmedColumn.get();
|
this.colIsDepositConfirmed = colSupplier.depositConfirmedColumn.get();
|
||||||
this.colIsPayoutPublished = colSupplier.payoutPublishedColumn.get();
|
this.colIsPayoutPublished = colSupplier.payoutPublishedColumn.get();
|
||||||
|
@ -135,6 +146,12 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder {
|
||||||
this.colIsPaymentSent = colSupplier.paymentSentColumn.get();
|
this.colIsPaymentSent = colSupplier.paymentSentColumn.get();
|
||||||
this.colIsPaymentReceived = colSupplier.paymentReceivedColumn.get();
|
this.colIsPaymentReceived = colSupplier.paymentReceivedColumn.get();
|
||||||
this.colAltcoinReceiveAddressColumn = colSupplier.altcoinReceiveAddressColumn.get();
|
this.colAltcoinReceiveAddressColumn = colSupplier.altcoinReceiveAddressColumn.get();
|
||||||
|
|
||||||
|
// BSQ swap trade detail specific columns
|
||||||
|
|
||||||
|
this.status = colSupplier.bsqSwapStatusColumn.get();
|
||||||
|
this.colTxId = colSupplier.bsqSwapTxIdColumn.get();
|
||||||
|
this.colNumConfirmations = colSupplier.numConfirmationsColumn.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void validate() {
|
protected void validate() {
|
||||||
|
@ -149,9 +166,8 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder {
|
||||||
// Helper Functions
|
// Helper Functions
|
||||||
|
|
||||||
private final Supplier<Boolean> isTradeDetailTblBuilder = () -> tableType.equals(TRADE_DETAIL_TBL);
|
private final Supplier<Boolean> isTradeDetailTblBuilder = () -> tableType.equals(TRADE_DETAIL_TBL);
|
||||||
|
|
||||||
protected final Predicate<TradeInfo> isFiatTrade = (t) -> isFiatOffer.test(t.getOffer());
|
protected final Predicate<TradeInfo> isFiatTrade = (t) -> isFiatOffer.test(t.getOffer());
|
||||||
|
protected final Predicate<TradeInfo> isBsqSwapTrade = (t) -> t.getOffer().getIsBsqSwapOffer();
|
||||||
protected final Predicate<TradeInfo> isTaker = (t) -> t.getRole().toLowerCase().contains("taker");
|
protected final Predicate<TradeInfo> isTaker = (t) -> t.getRole().toLowerCase().contains("taker");
|
||||||
|
|
||||||
// Column Value Functions
|
// Column Value Functions
|
||||||
|
@ -185,7 +201,6 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO Move to TradeUtil ?
|
|
||||||
protected final Function<TradeInfo, String> toPriceDeviation = (t) ->
|
protected final Function<TradeInfo, String> toPriceDeviation = (t) ->
|
||||||
t.getOffer().getUseMarketBasedPrice()
|
t.getOffer().getUseMarketBasedPrice()
|
||||||
? formatToPercent(t.getOffer().getMarketPriceMargin())
|
? formatToPercent(t.getOffer().getMarketPriceMargin())
|
||||||
|
@ -196,8 +211,6 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder {
|
||||||
? t.getTxFeeAsLong()
|
? t.getTxFeeAsLong()
|
||||||
: t.getOffer().getTxFee();
|
: t.getOffer().getTxFee();
|
||||||
|
|
||||||
|
|
||||||
// TODO Move to TradeUtil ?
|
|
||||||
protected final BiFunction<TradeInfo, Boolean, Long> toTradeFeeBsq = (t, isMyOffer) -> {
|
protected final BiFunction<TradeInfo, Boolean, Long> toTradeFeeBsq = (t, isMyOffer) -> {
|
||||||
if (isMyOffer) {
|
if (isMyOffer) {
|
||||||
return t.getOffer().getIsCurrencyForMakerFeeBtc()
|
return t.getOffer().getIsCurrencyForMakerFeeBtc()
|
||||||
|
@ -210,7 +223,6 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO Move to TradeUtil ?
|
|
||||||
protected final BiFunction<TradeInfo, Boolean, Long> toTradeFeeBtc = (t, isMyOffer) -> {
|
protected final BiFunction<TradeInfo, Boolean, Long> toTradeFeeBtc = (t, isMyOffer) -> {
|
||||||
if (isMyOffer) {
|
if (isMyOffer) {
|
||||||
return t.getOffer().getIsCurrencyForMakerFeeBtc()
|
return t.getOffer().getIsCurrencyForMakerFeeBtc()
|
||||||
|
@ -223,12 +235,18 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
protected final Function<TradeInfo, Long> toMyMakerOrTakerFee = (t) ->
|
protected final Function<TradeInfo, Long> toMyMakerOrTakerFee = (t) -> {
|
||||||
isTaker.test(t)
|
if (isBsqSwapTrade.test(t)) {
|
||||||
|
return isTaker.test(t)
|
||||||
|
? t.getBsqSwapTradeInfo().getBsqTakerTradeFee()
|
||||||
|
: t.getBsqSwapTradeInfo().getBsqMakerTradeFee();
|
||||||
|
} else {
|
||||||
|
return isTaker.test(t)
|
||||||
? t.getTakerFeeAsLong()
|
? t.getTakerFeeAsLong()
|
||||||
: t.getOffer().getMakerFee();
|
: t.getOffer().getMakerFee();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// TODO Move to TradeUtil ? SEE ClosedTradesViewModel # getDirectionLabel
|
|
||||||
protected final Function<TradeInfo, String> toOfferType = (t) -> {
|
protected final Function<TradeInfo, String> toOfferType = (t) -> {
|
||||||
if (isFiatTrade.test(t)) {
|
if (isFiatTrade.test(t)) {
|
||||||
return t.getOffer().getDirection() + " " + t.getOffer().getBaseCurrencyCode();
|
return t.getOffer().getDirection() + " " + t.getOffer().getBaseCurrencyCode();
|
||||||
|
@ -267,7 +285,7 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO Stuff to move into bisq/cli/CurrencyFormat.java ?
|
// TODO Move to bisq/cli/CurrencyFormat.java ?
|
||||||
|
|
||||||
public static String formatToPercent(double value) {
|
public static String formatToPercent(double value) {
|
||||||
DecimalFormat decimalFormat = new DecimalFormat("#.##");
|
DecimalFormat decimalFormat = new DecimalFormat("#.##");
|
||||||
|
|
|
@ -35,6 +35,7 @@ class TableBuilderConstants {
|
||||||
static final String COL_HEADER_LOCKUP_BONDS_BALANCE = "Lockup Bonds Balance";
|
static final String COL_HEADER_LOCKUP_BONDS_BALANCE = "Lockup Bonds Balance";
|
||||||
static final String COL_HEADER_UNLOCKING_BONDS_BALANCE = "Unlocking Bonds Balance";
|
static final String COL_HEADER_UNLOCKING_BONDS_BALANCE = "Unlocking Bonds Balance";
|
||||||
static final String COL_HEADER_UNVERIFIED_BALANCE = "Unverified Balance";
|
static final String COL_HEADER_UNVERIFIED_BALANCE = "Unverified Balance";
|
||||||
|
static final String COL_HEADER_BSQ_SWAP_TRADE_ROLE = "My BSQ Swap Role";
|
||||||
static final String COL_HEADER_BUYER_DEPOSIT = "Buyer Deposit";
|
static final String COL_HEADER_BUYER_DEPOSIT = "Buyer Deposit";
|
||||||
static final String COL_HEADER_SELLER_DEPOSIT = "Seller Deposit";
|
static final String COL_HEADER_SELLER_DEPOSIT = "Seller Deposit";
|
||||||
static final String COL_HEADER_CONFIRMATIONS = "Confirmations";
|
static final String COL_HEADER_CONFIRMATIONS = "Confirmations";
|
||||||
|
@ -65,8 +66,6 @@ class TableBuilderConstants {
|
||||||
static final String COL_HEADER_TRADE_ID = "Trade ID";
|
static final String COL_HEADER_TRADE_ID = "Trade ID";
|
||||||
static final String COL_HEADER_TRADE_ROLE = "My Role";
|
static final String COL_HEADER_TRADE_ROLE = "My Role";
|
||||||
static final String COL_HEADER_TRADE_SHORT_ID = "ID";
|
static final String COL_HEADER_TRADE_SHORT_ID = "ID";
|
||||||
@Deprecated
|
|
||||||
static final String COL_HEADER_TRADE_TX_FEE = "Tx Fee(BTC)";
|
|
||||||
static final String COL_HEADER_TRADE_MAKER_FEE = "Maker Fee(%-3s)";
|
static final String COL_HEADER_TRADE_MAKER_FEE = "Maker Fee(%-3s)";
|
||||||
static final String COL_HEADER_TRADE_TAKER_FEE = "Taker Fee(%-3s)";
|
static final String COL_HEADER_TRADE_TAKER_FEE = "Taker Fee(%-3s)";
|
||||||
static final String COL_HEADER_TRADE_FEE = "Trade Fee";
|
static final String COL_HEADER_TRADE_FEE = "Trade Fee";
|
||||||
|
|
|
@ -17,10 +17,16 @@
|
||||||
|
|
||||||
package bisq.cli.table.builder;
|
package bisq.cli.table.builder;
|
||||||
|
|
||||||
|
import bisq.proto.grpc.TradeInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import static bisq.cli.table.builder.TableType.TRADE_DETAIL_TBL;
|
import static bisq.cli.table.builder.TableType.TRADE_DETAIL_TBL;
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static protobuf.BsqSwapTrade.State.COMPLETED;
|
||||||
|
import static protobuf.BsqSwapTrade.State.PREPARATION;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,8 +36,12 @@ import bisq.cli.table.column.Column;
|
||||||
/**
|
/**
|
||||||
* Builds a {@code bisq.cli.table.Table} from a {@code bisq.proto.grpc.TradeInfo} object.
|
* Builds a {@code bisq.cli.table.Table} from a {@code bisq.proto.grpc.TradeInfo} object.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
class TradeDetailTableBuilder extends AbstractTradeListBuilder {
|
class TradeDetailTableBuilder extends AbstractTradeListBuilder {
|
||||||
|
|
||||||
|
private final Predicate<TradeInfo> isPendingBsqSwap = (t) -> t.getState().equals(PREPARATION.name());
|
||||||
|
private final Predicate<TradeInfo> isCompletedBsqSwap = (t) -> t.getState().equals(COMPLETED.name());
|
||||||
|
|
||||||
TradeDetailTableBuilder(List<?> protos) {
|
TradeDetailTableBuilder(List<?> protos) {
|
||||||
super(TRADE_DETAIL_TBL, protos);
|
super(TRADE_DETAIL_TBL, protos);
|
||||||
}
|
}
|
||||||
|
@ -41,33 +51,70 @@ class TradeDetailTableBuilder extends AbstractTradeListBuilder {
|
||||||
* @return Table containing one row
|
* @return Table containing one row
|
||||||
*/
|
*/
|
||||||
public Table build() {
|
public Table build() {
|
||||||
populateColumns();
|
// A trade detail table only has one row.
|
||||||
List<Column<?>> columns = defineColumnList();
|
var trade = trades.get(0);
|
||||||
|
populateColumns(trade);
|
||||||
|
List<Column<?>> columns = defineColumnList(trade);
|
||||||
return new Table(columns.toArray(new Column<?>[0]));
|
return new Table(columns.toArray(new Column<?>[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateColumns() {
|
private void populateColumns(TradeInfo trade) {
|
||||||
trades.stream().forEachOrdered(t -> {
|
if (isBsqSwapTrade.test(trade)) {
|
||||||
colTradeId.addRow(t.getShortId());
|
var isPending = isPendingBsqSwap.test(trade);
|
||||||
colRole.addRow(t.getRole());
|
var isCompleted = isCompletedBsqSwap.test(trade);
|
||||||
colPrice.addRow(t.getTradePrice());
|
if (isPending == isCompleted)
|
||||||
colAmountInBtc.addRow(toAmount.apply(t));
|
throw new IllegalStateException(
|
||||||
colMinerTxFee.addRow(toMyMinerTxFee.apply(t));
|
format("programmer error: trade must be either pending or completed, is pending=%s and completed=%s",
|
||||||
colBisqTradeFee.addRow(toMyMakerOrTakerFee.apply(t));
|
isPending,
|
||||||
colIsDepositPublished.addRow(t.getIsDepositPublished());
|
isCompleted));
|
||||||
colIsDepositConfirmed.addRow(t.getIsDepositConfirmed());
|
populateBsqSwapTradeColumns(trade);
|
||||||
colTradeCost.addRow(toTradeVolume.apply(t));
|
} else {
|
||||||
colIsPaymentSent.addRow(t.getIsFiatSent());
|
populateBisqV1TradeColumns(trade);
|
||||||
colIsPaymentReceived.addRow(t.getIsFiatReceived());
|
}
|
||||||
colIsPayoutPublished.addRow(t.getIsPayoutPublished());
|
|
||||||
colIsFundsWithdrawn.addRow(t.getIsWithdrawn());
|
|
||||||
|
|
||||||
if (colAltcoinReceiveAddressColumn != null)
|
|
||||||
colAltcoinReceiveAddressColumn.addRow(toAltcoinReceiveAddress.apply(t));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Column<?>> defineColumnList() {
|
private void populateBisqV1TradeColumns(TradeInfo trade) {
|
||||||
|
colTradeId.addRow(trade.getShortId());
|
||||||
|
colRole.addRow(trade.getRole());
|
||||||
|
colPrice.addRow(trade.getTradePrice());
|
||||||
|
colAmountInBtc.addRow(toAmount.apply(trade));
|
||||||
|
colMinerTxFee.addRow(toMyMinerTxFee.apply(trade));
|
||||||
|
colBisqTradeFee.addRow(toMyMakerOrTakerFee.apply(trade));
|
||||||
|
colIsDepositPublished.addRow(trade.getIsDepositPublished());
|
||||||
|
colIsDepositConfirmed.addRow(trade.getIsDepositConfirmed());
|
||||||
|
colTradeCost.addRow(toTradeVolume.apply(trade));
|
||||||
|
colIsPaymentSent.addRow(trade.getIsFiatSent());
|
||||||
|
colIsPaymentReceived.addRow(trade.getIsFiatReceived());
|
||||||
|
colIsPayoutPublished.addRow(trade.getIsPayoutPublished());
|
||||||
|
colIsFundsWithdrawn.addRow(trade.getIsWithdrawn());
|
||||||
|
if (colAltcoinReceiveAddressColumn != null)
|
||||||
|
colAltcoinReceiveAddressColumn.addRow(toAltcoinReceiveAddress.apply(trade));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateBsqSwapTradeColumns(TradeInfo trade) {
|
||||||
|
colTradeId.addRow(trade.getShortId());
|
||||||
|
colRole.addRow(trade.getRole());
|
||||||
|
colPrice.addRow(trade.getTradePrice());
|
||||||
|
colAmountInBtc.addRow(toAmount.apply(trade));
|
||||||
|
colMinerTxFee.addRow(toMyMinerTxFee.apply(trade));
|
||||||
|
colBisqTradeFee.addRow(toMyMakerOrTakerFee.apply(trade));
|
||||||
|
colTradeCost.addRow(toTradeVolume.apply(trade));
|
||||||
|
|
||||||
|
var isCompleted = isCompletedBsqSwap.test(trade);
|
||||||
|
status.addRow(isCompleted ? "COMPLETED" : "PENDING");
|
||||||
|
if (isCompleted) {
|
||||||
|
colTxId.addRow(trade.getBsqSwapTradeInfo().getTxId());
|
||||||
|
colNumConfirmations.addRow(trade.getBsqSwapTradeInfo().getNumConfirmations());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Column<?>> defineColumnList(TradeInfo trade) {
|
||||||
|
return isBsqSwapTrade.test(trade)
|
||||||
|
? getBsqSwapTradeColumnList(isCompletedBsqSwap.test(trade))
|
||||||
|
: getBisqV1TradeColumnList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Column<?>> getBisqV1TradeColumnList() {
|
||||||
List<Column<?>> columns = new ArrayList<>() {{
|
List<Column<?>> columns = new ArrayList<>() {{
|
||||||
add(colTradeId);
|
add(colTradeId);
|
||||||
add(colRole);
|
add(colRole);
|
||||||
|
@ -89,4 +136,25 @@ class TradeDetailTableBuilder extends AbstractTradeListBuilder {
|
||||||
|
|
||||||
return columns;
|
return columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Column<?>> getBsqSwapTradeColumnList(boolean isCompleted) {
|
||||||
|
List<Column<?>> columns = new ArrayList<>() {{
|
||||||
|
add(colTradeId);
|
||||||
|
add(colRole);
|
||||||
|
add(colPrice.asStringColumn());
|
||||||
|
add(colAmountInBtc.asStringColumn());
|
||||||
|
add(colMinerTxFee.asStringColumn());
|
||||||
|
add(colBisqTradeFee.asStringColumn());
|
||||||
|
add(colTradeCost.asStringColumn());
|
||||||
|
add(status);
|
||||||
|
}};
|
||||||
|
|
||||||
|
if (isCompleted)
|
||||||
|
columns.add(colTxId);
|
||||||
|
|
||||||
|
if (!colNumConfirmations.isEmpty())
|
||||||
|
columns.add(colNumConfirmations.asStringColumn());
|
||||||
|
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ import static bisq.cli.table.column.AltcoinColumn.DISPLAY_MODE.ALTCOIN_OFFER_VOL
|
||||||
import static bisq.cli.table.column.Column.JUSTIFICATION.LEFT;
|
import static bisq.cli.table.column.Column.JUSTIFICATION.LEFT;
|
||||||
import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT;
|
import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT;
|
||||||
import static bisq.cli.table.column.FiatColumn.DISPLAY_MODE.VOLUME;
|
import static bisq.cli.table.column.FiatColumn.DISPLAY_MODE.VOLUME;
|
||||||
|
import static java.lang.String.format;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ import bisq.cli.table.column.BtcColumn;
|
||||||
import bisq.cli.table.column.Column;
|
import bisq.cli.table.column.Column;
|
||||||
import bisq.cli.table.column.FiatColumn;
|
import bisq.cli.table.column.FiatColumn;
|
||||||
import bisq.cli.table.column.Iso8601DateTimeColumn;
|
import bisq.cli.table.column.Iso8601DateTimeColumn;
|
||||||
|
import bisq.cli.table.column.LongColumn;
|
||||||
import bisq.cli.table.column.MixedPriceColumn;
|
import bisq.cli.table.column.MixedPriceColumn;
|
||||||
import bisq.cli.table.column.MixedTradeFeeColumn;
|
import bisq.cli.table.column.MixedTradeFeeColumn;
|
||||||
import bisq.cli.table.column.MixedVolumeColumn;
|
import bisq.cli.table.column.MixedVolumeColumn;
|
||||||
|
@ -79,7 +81,10 @@ class TradeTableColumnSupplier {
|
||||||
private final Supplier<TradeInfo> firstRow = () -> getTrades().get(0);
|
private final Supplier<TradeInfo> firstRow = () -> getTrades().get(0);
|
||||||
private final Predicate<OfferInfo> isFiatOffer = (o) -> o.getBaseCurrencyCode().equals("BTC");
|
private final Predicate<OfferInfo> isFiatOffer = (o) -> o.getBaseCurrencyCode().equals("BTC");
|
||||||
private final Predicate<TradeInfo> isFiatTrade = (t) -> isFiatOffer.test(t.getOffer());
|
private final Predicate<TradeInfo> isFiatTrade = (t) -> isFiatOffer.test(t.getOffer());
|
||||||
|
private final Predicate<TradeInfo> isBsqSwapTrade = (t) -> t.getOffer().getIsBsqSwapOffer();
|
||||||
private final Predicate<TradeInfo> isTaker = (t) -> t.getRole().toLowerCase().contains("taker");
|
private final Predicate<TradeInfo> isTaker = (t) -> t.getRole().toLowerCase().contains("taker");
|
||||||
|
private final Supplier<Boolean> isSwapTradeDetail = () ->
|
||||||
|
isTradeDetailTblBuilder.get() && isBsqSwapTrade.test(firstRow.get());
|
||||||
|
|
||||||
final Supplier<StringColumn> tradeIdColumn = () -> isTradeDetailTblBuilder.get()
|
final Supplier<StringColumn> tradeIdColumn = () -> isTradeDetailTblBuilder.get()
|
||||||
? new StringColumn(COL_HEADER_TRADE_SHORT_ID)
|
? new StringColumn(COL_HEADER_TRADE_SHORT_ID)
|
||||||
|
@ -95,8 +100,8 @@ class TradeTableColumnSupplier {
|
||||||
|
|
||||||
private final Function<TradeInfo, Column<Long>> toDetailedPriceColumn = (t) -> {
|
private final Function<TradeInfo, Column<Long>> toDetailedPriceColumn = (t) -> {
|
||||||
String colHeader = isFiatTrade.test(t)
|
String colHeader = isFiatTrade.test(t)
|
||||||
? String.format(COL_HEADER_DETAILED_PRICE, t.getOffer().getCounterCurrencyCode())
|
? format(COL_HEADER_DETAILED_PRICE, t.getOffer().getCounterCurrencyCode())
|
||||||
: String.format(COL_HEADER_DETAILED_PRICE_OF_ALTCOIN, t.getOffer().getBaseCurrencyCode());
|
: format(COL_HEADER_DETAILED_PRICE_OF_ALTCOIN, t.getOffer().getBaseCurrencyCode());
|
||||||
return isFiatTrade.test(t)
|
return isFiatTrade.test(t)
|
||||||
? new FiatColumn(colHeader)
|
? new FiatColumn(colHeader)
|
||||||
: new AltcoinColumn(colHeader);
|
: new AltcoinColumn(colHeader);
|
||||||
|
@ -116,7 +121,7 @@ class TradeTableColumnSupplier {
|
||||||
|
|
||||||
private final Function<TradeInfo, Column<Long>> toDetailedAmountColumn = (t) -> {
|
private final Function<TradeInfo, Column<Long>> toDetailedAmountColumn = (t) -> {
|
||||||
String headerCurrencyCode = t.getOffer().getBaseCurrencyCode();
|
String headerCurrencyCode = t.getOffer().getBaseCurrencyCode();
|
||||||
String colHeader = String.format(COL_HEADER_DETAILED_AMOUNT, headerCurrencyCode);
|
String colHeader = format(COL_HEADER_DETAILED_AMOUNT, headerCurrencyCode);
|
||||||
return isFiatTrade.test(t)
|
return isFiatTrade.test(t)
|
||||||
? new SatoshiColumn(colHeader)
|
? new SatoshiColumn(colHeader)
|
||||||
: new AltcoinColumn(colHeader, ALTCOIN_OFFER_VOLUME);
|
: new AltcoinColumn(colHeader, ALTCOIN_OFFER_VOLUME);
|
||||||
|
@ -142,10 +147,14 @@ class TradeTableColumnSupplier {
|
||||||
? null
|
? null
|
||||||
: new StringColumn(COL_HEADER_PAYMENT_METHOD, LEFT);
|
: new StringColumn(COL_HEADER_PAYMENT_METHOD, LEFT);
|
||||||
|
|
||||||
final Supplier<StringColumn> roleColumn = () ->
|
final Supplier<StringColumn> roleColumn = () -> {
|
||||||
isTradeDetailTblBuilder.get() || isOpenTradeTblBuilder.get() || isFailedTradeTblBuilder.get()
|
if (isSwapTradeDetail.get())
|
||||||
|
return new StringColumn(COL_HEADER_BSQ_SWAP_TRADE_ROLE);
|
||||||
|
else
|
||||||
|
return isTradeDetailTblBuilder.get() || isOpenTradeTblBuilder.get() || isFailedTradeTblBuilder.get()
|
||||||
? new StringColumn(COL_HEADER_TRADE_ROLE)
|
? new StringColumn(COL_HEADER_TRADE_ROLE)
|
||||||
: null;
|
: null;
|
||||||
|
};
|
||||||
|
|
||||||
final Function<String, Column<Long>> toSecurityDepositColumn = (name) -> isClosedTradeTblBuilder.get()
|
final Function<String, Column<Long>> toSecurityDepositColumn = (name) -> isClosedTradeTblBuilder.get()
|
||||||
? new SatoshiColumn(name)
|
? new SatoshiColumn(name)
|
||||||
|
@ -161,21 +170,42 @@ class TradeTableColumnSupplier {
|
||||||
|
|
||||||
private final Function<String, Column<Boolean>> toBooleanColumn = BooleanColumn::new;
|
private final Function<String, Column<Boolean>> toBooleanColumn = BooleanColumn::new;
|
||||||
|
|
||||||
final Supplier<Column<Boolean>> depositPublishedColumn = () -> isTradeDetailTblBuilder.get()
|
final Supplier<Column<Boolean>> depositPublishedColumn = () -> {
|
||||||
? toBooleanColumn.apply(COL_HEADER_TRADE_DEPOSIT_PUBLISHED)
|
if (isSwapTradeDetail.get())
|
||||||
: null;
|
return null;
|
||||||
|
else
|
||||||
|
return isTradeDetailTblBuilder.get()
|
||||||
|
? toBooleanColumn.apply(COL_HEADER_TRADE_DEPOSIT_PUBLISHED)
|
||||||
|
: null;
|
||||||
|
};
|
||||||
|
|
||||||
final Supplier<Column<Boolean>> depositConfirmedColumn = () -> isTradeDetailTblBuilder.get()
|
final Supplier<Column<Boolean>> depositConfirmedColumn = () -> {
|
||||||
? toBooleanColumn.apply(COL_HEADER_TRADE_DEPOSIT_CONFIRMED)
|
if (isSwapTradeDetail.get())
|
||||||
: null;
|
return null;
|
||||||
|
else
|
||||||
|
return isTradeDetailTblBuilder.get()
|
||||||
|
? toBooleanColumn.apply(COL_HEADER_TRADE_DEPOSIT_CONFIRMED)
|
||||||
|
: null;
|
||||||
|
|
||||||
final Supplier<Column<Boolean>> payoutPublishedColumn = () -> isTradeDetailTblBuilder.get()
|
};
|
||||||
? toBooleanColumn.apply(COL_HEADER_TRADE_PAYOUT_PUBLISHED)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
final Supplier<Column<Boolean>> fundsWithdrawnColumn = () -> isTradeDetailTblBuilder.get()
|
final Supplier<Column<Boolean>> payoutPublishedColumn = () -> {
|
||||||
? toBooleanColumn.apply(COL_HEADER_TRADE_WITHDRAWN)
|
if (isSwapTradeDetail.get())
|
||||||
: null;
|
return null;
|
||||||
|
else
|
||||||
|
return isTradeDetailTblBuilder.get()
|
||||||
|
? toBooleanColumn.apply(COL_HEADER_TRADE_PAYOUT_PUBLISHED)
|
||||||
|
: null;
|
||||||
|
};
|
||||||
|
|
||||||
|
final Supplier<Column<Boolean>> fundsWithdrawnColumn = () -> {
|
||||||
|
if (isSwapTradeDetail.get())
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return isTradeDetailTblBuilder.get()
|
||||||
|
? toBooleanColumn.apply(COL_HEADER_TRADE_WITHDRAWN)
|
||||||
|
: null;
|
||||||
|
};
|
||||||
|
|
||||||
final Supplier<Column<Long>> bisqTradeDetailFeeColumn = () -> {
|
final Supplier<Column<Long>> bisqTradeDetailFeeColumn = () -> {
|
||||||
if (isTradeDetailTblBuilder.get()) {
|
if (isTradeDetailTblBuilder.get()) {
|
||||||
|
@ -184,8 +214,8 @@ class TradeTableColumnSupplier {
|
||||||
? t.getIsCurrencyForTakerFeeBtc() ? "BTC" : "BSQ"
|
? t.getIsCurrencyForTakerFeeBtc() ? "BTC" : "BSQ"
|
||||||
: t.getOffer().getIsCurrencyForMakerFeeBtc() ? "BTC" : "BSQ";
|
: t.getOffer().getIsCurrencyForMakerFeeBtc() ? "BTC" : "BSQ";
|
||||||
String colHeader = isTaker.test(t)
|
String colHeader = isTaker.test(t)
|
||||||
? String.format(COL_HEADER_TRADE_TAKER_FEE, headerCurrencyCode)
|
? format(COL_HEADER_TRADE_TAKER_FEE, headerCurrencyCode)
|
||||||
: String.format(COL_HEADER_TRADE_MAKER_FEE, headerCurrencyCode);
|
: format(COL_HEADER_TRADE_MAKER_FEE, headerCurrencyCode);
|
||||||
boolean isBsqSatoshis = headerCurrencyCode.equals("BSQ");
|
boolean isBsqSatoshis = headerCurrencyCode.equals("BSQ");
|
||||||
return new SatoshiColumn(colHeader, isBsqSatoshis);
|
return new SatoshiColumn(colHeader, isBsqSatoshis);
|
||||||
} else {
|
} else {
|
||||||
|
@ -201,7 +231,7 @@ class TradeTableColumnSupplier {
|
||||||
final Supplier<Column<Boolean>> paymentSentColumn = () -> {
|
final Supplier<Column<Boolean>> paymentSentColumn = () -> {
|
||||||
if (isTradeDetailTblBuilder.get()) {
|
if (isTradeDetailTblBuilder.get()) {
|
||||||
String headerCurrencyCode = toPaymentCurrencyCode.apply(firstRow.get());
|
String headerCurrencyCode = toPaymentCurrencyCode.apply(firstRow.get());
|
||||||
String colHeader = String.format(COL_HEADER_TRADE_PAYMENT_SENT, headerCurrencyCode);
|
String colHeader = format(COL_HEADER_TRADE_PAYMENT_SENT, headerCurrencyCode);
|
||||||
return new BooleanColumn(colHeader);
|
return new BooleanColumn(colHeader);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -211,7 +241,7 @@ class TradeTableColumnSupplier {
|
||||||
final Supplier<Column<Boolean>> paymentReceivedColumn = () -> {
|
final Supplier<Column<Boolean>> paymentReceivedColumn = () -> {
|
||||||
if (isTradeDetailTblBuilder.get()) {
|
if (isTradeDetailTblBuilder.get()) {
|
||||||
String headerCurrencyCode = toPaymentCurrencyCode.apply(firstRow.get());
|
String headerCurrencyCode = toPaymentCurrencyCode.apply(firstRow.get());
|
||||||
String colHeader = String.format(COL_HEADER_TRADE_PAYMENT_RECEIVED, headerCurrencyCode);
|
String colHeader = format(COL_HEADER_TRADE_PAYMENT_RECEIVED, headerCurrencyCode);
|
||||||
return new BooleanColumn(colHeader);
|
return new BooleanColumn(colHeader);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -222,7 +252,7 @@ class TradeTableColumnSupplier {
|
||||||
if (isTradeDetailTblBuilder.get()) {
|
if (isTradeDetailTblBuilder.get()) {
|
||||||
TradeInfo t = firstRow.get();
|
TradeInfo t = firstRow.get();
|
||||||
String headerCurrencyCode = t.getOffer().getCounterCurrencyCode();
|
String headerCurrencyCode = t.getOffer().getCounterCurrencyCode();
|
||||||
String colHeader = String.format(COL_HEADER_TRADE_BUYER_COST, headerCurrencyCode);
|
String colHeader = format(COL_HEADER_TRADE_BUYER_COST, headerCurrencyCode);
|
||||||
return isFiatTrade.test(t)
|
return isFiatTrade.test(t)
|
||||||
? new FiatColumn(colHeader, VOLUME)
|
? new FiatColumn(colHeader, VOLUME)
|
||||||
: new SatoshiColumn(colHeader);
|
: new SatoshiColumn(colHeader);
|
||||||
|
@ -231,6 +261,18 @@ class TradeTableColumnSupplier {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
final Supplier<Column<String>> bsqSwapTxIdColumn = () -> isSwapTradeDetail.get()
|
||||||
|
? new StringColumn(COL_HEADER_TX_ID)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
final Supplier<Column<String>> bsqSwapStatusColumn = () -> isSwapTradeDetail.get()
|
||||||
|
? new StringColumn(COL_HEADER_STATUS)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
final Supplier<Column<Long>> numConfirmationsColumn = () -> isSwapTradeDetail.get()
|
||||||
|
? new LongColumn(COL_HEADER_CONFIRMATIONS)
|
||||||
|
: null;
|
||||||
|
|
||||||
final Predicate<TradeInfo> showAltCoinBuyerAddress = (t) -> {
|
final Predicate<TradeInfo> showAltCoinBuyerAddress = (t) -> {
|
||||||
if (isFiatTrade.test(t)) {
|
if (isFiatTrade.test(t)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -251,7 +293,7 @@ class TradeTableColumnSupplier {
|
||||||
TradeInfo t = firstRow.get();
|
TradeInfo t = firstRow.get();
|
||||||
if (showAltCoinBuyerAddress.test(t)) {
|
if (showAltCoinBuyerAddress.test(t)) {
|
||||||
String headerCurrencyCode = toPaymentCurrencyCode.apply(t);
|
String headerCurrencyCode = toPaymentCurrencyCode.apply(t);
|
||||||
String colHeader = String.format(COL_HEADER_TRADE_ALTCOIN_BUYER_ADDRESS, headerCurrencyCode);
|
String colHeader = format(COL_HEADER_TRADE_ALTCOIN_BUYER_ADDRESS, headerCurrencyCode);
|
||||||
return new StringColumn(colHeader);
|
return new StringColumn(colHeader);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
|
93
cli/src/main/java/bisq/cli/table/column/IntegerColumn.java
Normal file
93
cli/src/main/java/bisq/cli/table/column/IntegerColumn.java
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* 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.table.column;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For displaying Integer values.
|
||||||
|
*/
|
||||||
|
public class IntegerColumn extends NumberColumn<IntegerColumn, Integer> {
|
||||||
|
|
||||||
|
protected final List<Integer> rows = new ArrayList<>();
|
||||||
|
|
||||||
|
protected final Predicate<String> isNewMaxWidth = (s) -> s != null && !s.isEmpty() && s.length() > maxWidth;
|
||||||
|
|
||||||
|
// The default IntegerColumn JUSTIFICATION is RIGHT.
|
||||||
|
public IntegerColumn(String name) {
|
||||||
|
this(name, RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntegerColumn(String name, JUSTIFICATION justification) {
|
||||||
|
super(name, justification);
|
||||||
|
this.maxWidth = name.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addRow(Integer value) {
|
||||||
|
rows.add(value);
|
||||||
|
|
||||||
|
String s = String.valueOf(value);
|
||||||
|
if (isNewMaxWidth.test(s))
|
||||||
|
maxWidth = s.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Integer> getRows() {
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int rowCount() {
|
||||||
|
return rows.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return rows.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getRow(int rowIndex) {
|
||||||
|
return rows.get(rowIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRow(int rowIndex, Integer newValue) {
|
||||||
|
rows.set(rowIndex, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRowAsFormattedString(int rowIndex) {
|
||||||
|
String s = String.valueOf(getRow(rowIndex));
|
||||||
|
return toJustifiedString(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringColumn asStringColumn() {
|
||||||
|
IntStream.range(0, rows.size()).forEachOrdered(rowIndex ->
|
||||||
|
stringColumn.addRow(getRowAsFormattedString(rowIndex)));
|
||||||
|
|
||||||
|
return stringColumn;
|
||||||
|
}
|
||||||
|
}
|
85
cli/src/test/java/bisq/cli/CreateOfferSmokeTest.java
Normal file
85
cli/src/test/java/bisq/cli/CreateOfferSmokeTest.java
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
package bisq.cli;
|
||||||
|
|
||||||
|
import static java.lang.System.out;
|
||||||
|
import static java.util.Arrays.stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Smoke tests for createoffer method. Useful for testing CLI command and examining the
|
||||||
|
format of its console output.
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
|
||||||
|
- Run `./bisq-apitest --apiPassword=xyz --supportingApps=bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon --shutdownAfterTests=false --enableBisqDebugging=false`
|
||||||
|
|
||||||
|
Note: Test harness will not automatically generate BTC blocks to confirm transactions.
|
||||||
|
|
||||||
|
Never run on mainnet!
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"CommentedOutCode", "unused"})
|
||||||
|
public class CreateOfferSmokeTest extends AbstractCliTest {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
createBsqSwapOffer("buy");
|
||||||
|
createBsqSwapOffer("sell");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createBsqSwapOffer(String direction) {
|
||||||
|
String[] args = createBsqSwapOfferCommand(direction, "0.01", "0.005", "0.00005");
|
||||||
|
out.print(">>>>> bisq-cli ");
|
||||||
|
stream(args).forEach(a -> out.print(a + " "));
|
||||||
|
out.println();
|
||||||
|
CliMain.main(args);
|
||||||
|
out.println("<<<<<");
|
||||||
|
|
||||||
|
args = getMyOffersCommand(direction);
|
||||||
|
out.print(">>>>> bisq-cli ");
|
||||||
|
stream(args).forEach(a -> out.print(a + " "));
|
||||||
|
out.println();
|
||||||
|
CliMain.main(args);
|
||||||
|
out.println("<<<<<");
|
||||||
|
|
||||||
|
args = getAvailableOffersCommand(direction);
|
||||||
|
out.print(">>>>> bisq-cli ");
|
||||||
|
stream(args).forEach(a -> out.print(a + " "));
|
||||||
|
out.println();
|
||||||
|
CliMain.main(args);
|
||||||
|
out.println("<<<<<");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] createBsqSwapOfferCommand(String direction,
|
||||||
|
String amount,
|
||||||
|
String minAmount,
|
||||||
|
String fixedPrice) {
|
||||||
|
return new String[]{
|
||||||
|
PASSWORD_OPT,
|
||||||
|
ALICE_PORT_OPT,
|
||||||
|
"createoffer",
|
||||||
|
"--swap=true",
|
||||||
|
"--direction=" + direction,
|
||||||
|
"--currency-code=bsq",
|
||||||
|
"--amount=" + amount,
|
||||||
|
"--min-amount=" + minAmount,
|
||||||
|
"--fixed-price=" + fixedPrice
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] getMyOffersCommand(String direction) {
|
||||||
|
return new String[]{
|
||||||
|
PASSWORD_OPT,
|
||||||
|
ALICE_PORT_OPT,
|
||||||
|
"getmyoffers",
|
||||||
|
"--direction=" + direction,
|
||||||
|
"--currency-code=bsq"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] getAvailableOffersCommand(String direction) {
|
||||||
|
return new String[]{
|
||||||
|
PASSWORD_OPT,
|
||||||
|
BOB_PORT_OPT,
|
||||||
|
"getoffers",
|
||||||
|
"--direction=" + direction,
|
||||||
|
"--currency-code=bsq"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,15 +11,50 @@ import static java.lang.System.out;
|
||||||
|
|
||||||
This can be run on mainnet.
|
This can be run on mainnet.
|
||||||
*/
|
*/
|
||||||
public class GetOffersSmokeTest {
|
@SuppressWarnings({"CommentedOutCode", "unused"})
|
||||||
|
public class GetOffersSmokeTest extends AbstractCliTest {
|
||||||
|
|
||||||
|
// TODO use the static password and port opt definitions in superclass
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
getMyBsqOffers();
|
||||||
|
// getAvailableBsqOffers();
|
||||||
|
// getMyUsdOffers();
|
||||||
|
// getAvailableUsdOffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getMyBsqOffers() {
|
||||||
|
out.println(">>> getmyoffers buy bsq");
|
||||||
|
CliMain.main(new String[]{"--password=xyz", "--port=9998", "getmyoffers", "--direction=buy", "--currency-code=bsq"});
|
||||||
|
out.println(">>> getmyoffers sell bsq");
|
||||||
|
CliMain.main(new String[]{"--password=xyz", "--port=9998", "getmyoffers", "--direction=sell", "--currency-code=bsq"});
|
||||||
|
out.println(">>> getmyoffer --offer-id=KRONTTMO-11cef1a9-c636-4dc7-b3f2-1616e4960c28-175");
|
||||||
|
CliMain.main(new String[]{"--password=xyz", "--port=9998", "getmyoffer", "--offer-id=KRONTTMO-11cef1a9-c636-4dc7-b3f2-1616e4960c28-175"});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getAvailableBsqOffers() {
|
||||||
|
out.println(">>> getoffers buy bsq");
|
||||||
|
CliMain.main(new String[]{"--password=xyz", "--port=9998", "getoffers", "--direction=buy", "--currency-code=bsq"});
|
||||||
|
out.println(">>> getoffers sell bsq");
|
||||||
|
CliMain.main(new String[]{"--password=xyz", "--port=9998", "getoffers", "--direction=sell", "--currency-code=bsq"});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void getMyUsdOffers() {
|
||||||
|
out.println(">>> getmyoffers buy usd");
|
||||||
|
CliMain.main(new String[]{"--password=xyz", "--port=9998", "getmyoffers", "--direction=buy", "--currency-code=usd"});
|
||||||
|
out.println(">>> getmyoffers sell usd");
|
||||||
|
CliMain.main(new String[]{"--password=xyz", "--port=9998", "getmyoffers", "--direction=sell", "--currency-code=usd"});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getAvailableUsdOffers() {
|
||||||
out.println(">>> getoffers buy usd");
|
out.println(">>> getoffers buy usd");
|
||||||
CliMain.main(new String[]{"--password=xyz", "getoffers", "--direction=buy", "--currency-code=usd"});
|
CliMain.main(new String[]{"--password=xyz", "--port=9998", "getoffers", "--direction=buy", "--currency-code=usd"});
|
||||||
out.println(">>> getoffers sell usd");
|
out.println(">>> getoffers sell usd");
|
||||||
CliMain.main(new String[]{"--password=xyz", "getoffers", "--direction=sell", "--currency-code=usd"});
|
CliMain.main(new String[]{"--password=xyz", "--port=9998", "getoffers", "--direction=sell", "--currency-code=usd"});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void TODO() {
|
||||||
out.println(">>> getoffers buy eur");
|
out.println(">>> getoffers buy eur");
|
||||||
CliMain.main(new String[]{"--password=xyz", "getoffers", "--direction=buy", "--currency-code=eur"});
|
CliMain.main(new String[]{"--password=xyz", "getoffers", "--direction=buy", "--currency-code=eur"});
|
||||||
out.println(">>> getoffers sell eur");
|
out.println(">>> getoffers sell eur");
|
||||||
|
@ -35,5 +70,4 @@ public class GetOffersSmokeTest {
|
||||||
out.println(">>> getoffers sell brl");
|
out.println(">>> getoffers sell brl");
|
||||||
CliMain.main(new String[]{"--password=xyz", "getoffers", "--direction=sell", "--currency-code=brl"});
|
CliMain.main(new String[]{"--password=xyz", "getoffers", "--direction=sell", "--currency-code=brl"});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import static bisq.cli.Method.createpaymentacct;
|
||||||
import static bisq.cli.opts.OptLabel.*;
|
import static bisq.cli.opts.OptLabel.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
|
||||||
public class OptionParsersTest {
|
public class OptionParsersTest {
|
||||||
|
@ -62,13 +63,16 @@ public class OptionParsersTest {
|
||||||
new CancelOfferOptionParser(args).parse();
|
new CancelOfferOptionParser(args).parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
// createoffer opt parser tests
|
// createoffer (v1) opt parser tests
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateOfferOptParserWithMissingPaymentAccountIdOptShouldThrowException() {
|
public void testCreateOfferWithMissingPaymentAccountIdOptShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createoffer.name()
|
createoffer.name(),
|
||||||
|
"--" + OPT_DIRECTION + "=" + "SELL",
|
||||||
|
"--" + OPT_CURRENCY_CODE + "=" + "JPY",
|
||||||
|
"--" + OPT_AMOUNT + "=" + "0.1"
|
||||||
};
|
};
|
||||||
Throwable exception = assertThrows(RuntimeException.class, () ->
|
Throwable exception = assertThrows(RuntimeException.class, () ->
|
||||||
new CreateOfferOptionParser(args).parse());
|
new CreateOfferOptionParser(args).parse());
|
||||||
|
@ -76,7 +80,7 @@ public class OptionParsersTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateOfferOptParserWithEmptyPaymentAccountIdOptShouldThrowException() {
|
public void testCreateOfferWithEmptyPaymentAccountIdOptShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createoffer.name(),
|
createoffer.name(),
|
||||||
|
@ -88,7 +92,7 @@ public class OptionParsersTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateOfferOptParserWithMissingDirectionOptShouldThrowException() {
|
public void testCreateOfferWithMissingDirectionOptShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createoffer.name(),
|
createoffer.name(),
|
||||||
|
@ -101,7 +105,7 @@ public class OptionParsersTest {
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateOfferOptParserWithMissingDirectionOptValueShouldThrowException() {
|
public void testCreateOfferWithMissingDirectionOptValueShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createoffer.name(),
|
createoffer.name(),
|
||||||
|
@ -134,10 +138,114 @@ public class OptionParsersTest {
|
||||||
assertEquals("25.0", parser.getSecurityDeposit());
|
assertEquals("25.0", parser.getSecurityDeposit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// createoffer (bsq swap) opt parser tests
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateBsqSwapOfferWithPaymentAcctIdOptShouldThrowException() {
|
||||||
|
String[] args = new String[]{
|
||||||
|
PASSWORD_OPT,
|
||||||
|
createoffer.name(),
|
||||||
|
"--" + OPT_SWAP + "=" + "true",
|
||||||
|
"--" + OPT_PAYMENT_ACCOUNT + "=" + "abc",
|
||||||
|
"--" + OPT_DIRECTION + "=" + "buy",
|
||||||
|
"--" + OPT_CURRENCY_CODE + "=" + "bsq",
|
||||||
|
"--" + OPT_AMOUNT + "=" + "0.125"
|
||||||
|
};
|
||||||
|
Throwable exception = assertThrows(RuntimeException.class, () ->
|
||||||
|
new CreateOfferOptionParser(args).parse());
|
||||||
|
assertEquals("cannot use a payment account id in bsq swap offer", exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateBsqSwapOfferWithMktMarginPriceOptShouldThrowException() {
|
||||||
|
String[] args = new String[]{
|
||||||
|
PASSWORD_OPT,
|
||||||
|
createoffer.name(),
|
||||||
|
"--" + OPT_SWAP + "=" + "true",
|
||||||
|
"--" + OPT_DIRECTION + "=" + "buy",
|
||||||
|
"--" + OPT_CURRENCY_CODE + "=" + "bsq",
|
||||||
|
"--" + OPT_AMOUNT + "=" + "0.125",
|
||||||
|
"--" + OPT_MKT_PRICE_MARGIN + "=" + "0.0"
|
||||||
|
};
|
||||||
|
Throwable exception = assertThrows(RuntimeException.class, () ->
|
||||||
|
new CreateOfferOptionParser(args).parse());
|
||||||
|
assertEquals("cannot use a market price margin in bsq swap offer", exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateBsqSwapOfferWithSecurityDepositOptShouldThrowException() {
|
||||||
|
String[] args = new String[]{
|
||||||
|
PASSWORD_OPT,
|
||||||
|
createoffer.name(),
|
||||||
|
"--" + OPT_SWAP + "=" + "true",
|
||||||
|
"--" + OPT_DIRECTION + "=" + "buy",
|
||||||
|
"--" + OPT_CURRENCY_CODE + "=" + "bsq",
|
||||||
|
"--" + OPT_AMOUNT + "=" + "0.125",
|
||||||
|
"--" + OPT_SECURITY_DEPOSIT + "=" + "25.0"
|
||||||
|
};
|
||||||
|
Throwable exception = assertThrows(RuntimeException.class, () ->
|
||||||
|
new CreateOfferOptionParser(args).parse());
|
||||||
|
assertEquals("cannot use a security deposit in bsq swap offer", exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateBsqSwapOfferWithMissingFixedPriceOptShouldThrowException() {
|
||||||
|
String[] args = new String[]{
|
||||||
|
PASSWORD_OPT,
|
||||||
|
createoffer.name(),
|
||||||
|
"--" + OPT_SWAP + "=" + "true",
|
||||||
|
"--" + OPT_DIRECTION + "=" + "sell",
|
||||||
|
"--" + OPT_CURRENCY_CODE + "=" + "bsq",
|
||||||
|
"--" + OPT_MIN_AMOUNT + "=" + "0.075",
|
||||||
|
"--" + OPT_AMOUNT + "=" + "0.125"
|
||||||
|
};
|
||||||
|
Throwable exception = assertThrows(RuntimeException.class, () ->
|
||||||
|
new CreateOfferOptionParser(args).parse());
|
||||||
|
assertEquals("no fixed price specified", exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateBsqSwapOfferWithIncorrectCurrencyCodeOptShouldThrowException() {
|
||||||
|
String[] args = new String[]{
|
||||||
|
PASSWORD_OPT,
|
||||||
|
createoffer.name(),
|
||||||
|
"--" + OPT_SWAP + "=" + "true",
|
||||||
|
"--" + OPT_DIRECTION + "=" + "sell",
|
||||||
|
"--" + OPT_CURRENCY_CODE + "=" + "xmr",
|
||||||
|
"--" + OPT_MIN_AMOUNT + "=" + "0.075",
|
||||||
|
"--" + OPT_AMOUNT + "=" + "0.125",
|
||||||
|
"--" + OPT_FIXED_PRICE + "=" + "0.00005555"
|
||||||
|
};
|
||||||
|
Throwable exception = assertThrows(RuntimeException.class, () ->
|
||||||
|
new CreateOfferOptionParser(args).parse());
|
||||||
|
assertEquals("only bsq swaps are currently supported", exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidCreateBsqSwapOfferOpts() {
|
||||||
|
String[] args = new String[]{
|
||||||
|
PASSWORD_OPT,
|
||||||
|
createoffer.name(),
|
||||||
|
"--" + OPT_SWAP + "=" + "true",
|
||||||
|
"--" + OPT_DIRECTION + "=" + "sell",
|
||||||
|
"--" + OPT_CURRENCY_CODE + "=" + "bsq",
|
||||||
|
"--" + OPT_MIN_AMOUNT + "=" + "0.075",
|
||||||
|
"--" + OPT_AMOUNT + "=" + "0.125",
|
||||||
|
"--" + OPT_FIXED_PRICE + "=" + "0.00005555"
|
||||||
|
};
|
||||||
|
CreateOfferOptionParser parser = new CreateOfferOptionParser(args).parse();
|
||||||
|
assertTrue(parser.getIsSwap());
|
||||||
|
assertEquals("sell", parser.getDirection());
|
||||||
|
assertEquals("bsq", parser.getCurrencyCode());
|
||||||
|
assertEquals("0.075", parser.getMinAmount());
|
||||||
|
assertEquals("0.125", parser.getAmount());
|
||||||
|
assertEquals("0.00005555", parser.getFixedPrice());
|
||||||
|
}
|
||||||
|
|
||||||
// createpaymentacct opt parser tests
|
// createpaymentacct opt parser tests
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreatePaymentAcctOptParserWithMissingPaymentFormOptShouldThrowException() {
|
public void testCreatePaymentAcctWithMissingPaymentFormOptShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createpaymentacct.name()
|
createpaymentacct.name()
|
||||||
|
@ -149,7 +257,7 @@ public class OptionParsersTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreatePaymentAcctOptParserWithMissingPaymentFormOptValueShouldThrowException() {
|
public void testCreatePaymentAcctWithMissingPaymentFormOptValueShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createpaymentacct.name(),
|
createpaymentacct.name(),
|
||||||
|
@ -161,7 +269,7 @@ public class OptionParsersTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreatePaymentAcctOptParserWithInvalidPaymentFormOptValueShouldThrowException() {
|
public void testCreatePaymentAcctWithInvalidPaymentFormOptValueShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createpaymentacct.name(),
|
createpaymentacct.name(),
|
||||||
|
@ -180,7 +288,7 @@ public class OptionParsersTest {
|
||||||
// createcryptopaymentacct parser tests
|
// createcryptopaymentacct parser tests
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateCryptoCurrencyPaymentAcctOptionParserWithMissingAcctNameOptShouldThrowException() {
|
public void testCreateCryptoCurrencyPaymentAcctWithMissingAcctNameOptShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createcryptopaymentacct.name()
|
createcryptopaymentacct.name()
|
||||||
|
@ -191,7 +299,7 @@ public class OptionParsersTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateCryptoCurrencyPaymentAcctOptionParserWithEmptyAcctNameOptShouldThrowException() {
|
public void testCreateCryptoCurrencyPaymentAcctWithEmptyAcctNameOptShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createcryptopaymentacct.name(),
|
createcryptopaymentacct.name(),
|
||||||
|
@ -203,7 +311,7 @@ public class OptionParsersTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateCryptoCurrencyPaymentAcctOptionParserWithMissingCurrencyCodeOptShouldThrowException() {
|
public void testCreateCryptoCurrencyPaymentAcctWithMissingCurrencyCodeOptShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createcryptopaymentacct.name(),
|
createcryptopaymentacct.name(),
|
||||||
|
@ -215,7 +323,7 @@ public class OptionParsersTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateCryptoCurrencyPaymentAcctOptionParserWithInvalidCurrencyCodeOptShouldThrowException() {
|
public void testCreateCryptoCurrencyPaymentAcctWithInvalidCurrencyCodeOptShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createcryptopaymentacct.name(),
|
createcryptopaymentacct.name(),
|
||||||
|
@ -228,7 +336,7 @@ public class OptionParsersTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateCryptoCurrencyPaymentAcctOptionParserWithMissingAddressOptShouldThrowException() {
|
public void testCreateCryptoCurrencyPaymentAcctWithMissingAddressOptShouldThrowException() {
|
||||||
String[] args = new String[]{
|
String[] args = new String[]{
|
||||||
PASSWORD_OPT,
|
PASSWORD_OPT,
|
||||||
createcryptopaymentacct.name(),
|
createcryptopaymentacct.name(),
|
||||||
|
@ -241,7 +349,7 @@ public class OptionParsersTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateCryptoCurrencyPaymentAcctOptionParser() {
|
public void testCreateCryptoCurrencyPaymentAcct() {
|
||||||
var acctName = "bsq payment account";
|
var acctName = "bsq payment account";
|
||||||
var currencyCode = "bsq";
|
var currencyCode = "bsq";
|
||||||
var address = "B1nXyZ"; // address is validated on server
|
var address = "B1nXyZ"; // address is validated on server
|
||||||
|
|
|
@ -26,6 +26,7 @@ import bisq.core.offer.OpenOffer;
|
||||||
import bisq.core.payment.PaymentAccount;
|
import bisq.core.payment.PaymentAccount;
|
||||||
import bisq.core.payment.payload.PaymentMethod;
|
import bisq.core.payment.payload.PaymentMethod;
|
||||||
import bisq.core.trade.bisq_v1.TradeResultHandler;
|
import bisq.core.trade.bisq_v1.TradeResultHandler;
|
||||||
|
import bisq.core.trade.model.TradeModel;
|
||||||
import bisq.core.trade.model.bisq_v1.Trade;
|
import bisq.core.trade.model.bisq_v1.Trade;
|
||||||
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
|
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
|
||||||
import bisq.core.trade.statistics.TradeStatistics3;
|
import bisq.core.trade.statistics.TradeStatistics3;
|
||||||
|
@ -119,6 +120,18 @@ public class CoreApi {
|
||||||
// Offers
|
// Offers
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public boolean isFiatOffer(String id, boolean isMyOffer) {
|
||||||
|
return coreOffersService.isFiatOffer(id, isMyOffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAltcoinOffer(String id, boolean isMyOffer) {
|
||||||
|
return coreOffersService.isAltcoinOffer(id, isMyOffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBsqSwapOffer(String id, boolean isMyOffer) {
|
||||||
|
return coreOffersService.isBsqSwapOffer(id, isMyOffer);
|
||||||
|
}
|
||||||
|
|
||||||
public Offer getBsqSwapOffer(String id) {
|
public Offer getBsqSwapOffer(String id) {
|
||||||
return coreOffersService.getBsqSwapOffer(id);
|
return coreOffersService.getBsqSwapOffer(id);
|
||||||
}
|
}
|
||||||
|
@ -264,14 +277,10 @@ public class CoreApi {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public void takeBsqSwapOffer(String offerId,
|
public void takeBsqSwapOffer(String offerId,
|
||||||
String paymentAccountId,
|
|
||||||
String takerFeeCurrencyCode,
|
|
||||||
TradeResultHandler<BsqSwapTrade> tradeResultHandler,
|
TradeResultHandler<BsqSwapTrade> tradeResultHandler,
|
||||||
ErrorMessageHandler errorMessageHandler) {
|
ErrorMessageHandler errorMessageHandler) {
|
||||||
Offer bsqSwapOffer = coreOffersService.getBsqSwapOffer(offerId);
|
Offer bsqSwapOffer = coreOffersService.getBsqSwapOffer(offerId);
|
||||||
coreTradesService.takeBsqSwapOffer(bsqSwapOffer,
|
coreTradesService.takeBsqSwapOffer(bsqSwapOffer,
|
||||||
paymentAccountId,
|
|
||||||
takerFeeCurrencyCode,
|
|
||||||
tradeResultHandler,
|
tradeResultHandler,
|
||||||
errorMessageHandler);
|
errorMessageHandler);
|
||||||
}
|
}
|
||||||
|
@ -305,18 +314,18 @@ public class CoreApi {
|
||||||
coreTradesService.withdrawFunds(tradeId, address, memo);
|
coreTradesService.withdrawFunds(tradeId, address, memo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BsqSwapTrade getBsqSwapTrade(String tradeId) {
|
public TradeModel getTradeModel(String tradeId) {
|
||||||
return coreTradesService.getBsqSwapTrade(tradeId);
|
return coreTradesService.getTradeModel(tradeId);
|
||||||
}
|
|
||||||
|
|
||||||
public Trade getTrade(String tradeId) {
|
|
||||||
return coreTradesService.getTrade(tradeId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTradeRole(String tradeId) {
|
public String getTradeRole(String tradeId) {
|
||||||
return coreTradesService.getTradeRole(tradeId);
|
return coreTradesService.getTradeRole(tradeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getBsqSwapTradeRole(BsqSwapTrade bsqSwapTrade) {
|
||||||
|
return coreTradesService.getBsqSwapTradeRole(bsqSwapTrade);
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Wallets
|
// Wallets
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -381,6 +390,10 @@ public class CoreApi {
|
||||||
return walletsService.getTransaction(txId);
|
return walletsService.getTransaction(txId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getTransactionConfirmations(String txId) {
|
||||||
|
return walletsService.getTransactionConfirmations(txId);
|
||||||
|
}
|
||||||
|
|
||||||
public void setWalletPassword(String password, String newPassword) {
|
public void setWalletPassword(String password, String newPassword) {
|
||||||
walletsService.setWalletPassword(password, newPassword);
|
walletsService.setWalletPassword(password, newPassword);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,8 @@ import java.math.BigDecimal;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -60,6 +62,7 @@ import static bisq.common.util.MathUtils.scaleUpByPowerOf10;
|
||||||
import static bisq.core.locale.CurrencyUtil.isCryptoCurrency;
|
import static bisq.core.locale.CurrencyUtil.isCryptoCurrency;
|
||||||
import static bisq.core.offer.Offer.State;
|
import static bisq.core.offer.Offer.State;
|
||||||
import static bisq.core.offer.OfferDirection.BUY;
|
import static bisq.core.offer.OfferDirection.BUY;
|
||||||
|
import static bisq.core.offer.OfferUtil.getRandomOfferId;
|
||||||
import static bisq.core.offer.OpenOffer.State.AVAILABLE;
|
import static bisq.core.offer.OpenOffer.State.AVAILABLE;
|
||||||
import static bisq.core.offer.OpenOffer.State.DEACTIVATED;
|
import static bisq.core.offer.OpenOffer.State.DEACTIVATED;
|
||||||
import static bisq.core.payment.PaymentAccountUtil.isPaymentAccountValidForOffer;
|
import static bisq.core.payment.PaymentAccountUtil.isPaymentAccountValidForOffer;
|
||||||
|
@ -78,6 +81,9 @@ class CoreOffersService {
|
||||||
private final Supplier<Comparator<OpenOffer>> openOfferPriceComparator = () ->
|
private final Supplier<Comparator<OpenOffer>> openOfferPriceComparator = () ->
|
||||||
comparing(openOffer -> openOffer.getOffer().getPrice());
|
comparing(openOffer -> openOffer.getOffer().getPrice());
|
||||||
|
|
||||||
|
private final BiFunction<String, Boolean, Offer> toOfferWithId = (id, isMyOffer) ->
|
||||||
|
isMyOffer ? getMyOffer(id).getOffer() : getOffer(id);
|
||||||
|
|
||||||
private final CoreContext coreContext;
|
private final CoreContext coreContext;
|
||||||
private final KeyRing keyRing;
|
private final KeyRing keyRing;
|
||||||
// Dependencies on core api services in this package must be kept to an absolute
|
// Dependencies on core api services in this package must be kept to an absolute
|
||||||
|
@ -118,51 +124,48 @@ class CoreOffersService {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
Offer getBsqSwapOffer(String id) {
|
boolean isFiatOffer(String id, boolean isMyOffer) {
|
||||||
return offerBookService.getOffers().stream()
|
var offer = toOfferWithId.apply(id, isMyOffer);
|
||||||
.filter(o -> o.getId().equals(id))
|
return OfferUtil.isFiatOffer(offer);
|
||||||
.filter(o -> !o.isMyOffer(keyRing))
|
}
|
||||||
.filter(o -> offerFilterService.canTakeOffer(o, coreContext.isApiUser()).isValid())
|
|
||||||
.filter(o -> o.isBsqSwapOffer())
|
boolean isAltcoinOffer(String id, boolean isMyOffer) {
|
||||||
.findAny().orElseThrow(() ->
|
var offer = toOfferWithId.apply(id, isMyOffer);
|
||||||
new IllegalStateException(format("offer with id '%s' not found", id)));
|
return OfferUtil.isAltcoinOffer(offer);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isBsqSwapOffer(String id, boolean isMyOffer) {
|
||||||
|
var offer = toOfferWithId.apply(id, isMyOffer);
|
||||||
|
return offer.isBsqSwapOffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
Offer getOffer(String id) {
|
Offer getOffer(String id) {
|
||||||
return offerBookService.getOffers().stream()
|
return findAvailableOffer(id).orElseThrow(() ->
|
||||||
.filter(o -> o.getId().equals(id))
|
new IllegalStateException(format("offer with id '%s' not found", id)));
|
||||||
.filter(o -> !o.isMyOffer(keyRing))
|
|
||||||
.filter(o -> offerFilterService.canTakeOffer(o, coreContext.isApiUser()).isValid())
|
|
||||||
.findAny().orElseThrow(() ->
|
|
||||||
new IllegalStateException(format("offer with id '%s' not found", id)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenOffer getMyOffer(String id) {
|
OpenOffer getMyOffer(String id) {
|
||||||
return openOfferManager.getObservableList().stream()
|
return findMyOpenOffer(id).orElseThrow(() ->
|
||||||
.filter(o -> o.getId().equals(id))
|
new IllegalStateException(format("offer with id '%s' not found", id)));
|
||||||
.filter(o -> o.getOffer().isMyOffer(keyRing))
|
}
|
||||||
.findAny().orElseThrow(() ->
|
|
||||||
new IllegalStateException(format("offer with id '%s' not found", id)));
|
Offer getBsqSwapOffer(String id) {
|
||||||
|
return findAvailableBsqSwapOffer(id).orElseThrow(() ->
|
||||||
|
new IllegalStateException(format("offer with id '%s' not found", id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Offer getMyBsqSwapOffer(String id) {
|
Offer getMyBsqSwapOffer(String id) {
|
||||||
return offerBookService.getOffers().stream()
|
return findMyBsqSwapOffer(id).orElseThrow(() ->
|
||||||
.filter(o -> o.getId().equals(id))
|
new IllegalStateException(format("offer with id '%s' not found", id)));
|
||||||
.filter(o -> o.isMyOffer(keyRing))
|
|
||||||
.filter(o -> o.isBsqSwapOffer())
|
|
||||||
.findAny().orElseThrow(() ->
|
|
||||||
new IllegalStateException(format("offer with id '%s' not found", id)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List<Offer> getBsqSwapOffers(String direction) {
|
List<Offer> getBsqSwapOffers(String direction) {
|
||||||
var offers = offerBookService.getOffers().stream()
|
return offerBookService.getOffers().stream()
|
||||||
.filter(o -> !o.isMyOffer(keyRing))
|
.filter(o -> !o.isMyOffer(keyRing))
|
||||||
.filter(o -> o.getDirection().name().equalsIgnoreCase(direction))
|
.filter(o -> o.getDirection().name().equalsIgnoreCase(direction))
|
||||||
.filter(o -> o.isBsqSwapOffer())
|
.filter(Offer::isBsqSwapOffer)
|
||||||
.sorted(priceComparator(direction))
|
.sorted(priceComparator(direction))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return offers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Offer> getOffers(String direction, String currencyCode) {
|
List<Offer> getOffers(String direction, String currencyCode) {
|
||||||
|
@ -183,13 +186,12 @@ class CoreOffersService {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Offer> getMyBsqSwapOffers(String direction) {
|
List<Offer> getMyBsqSwapOffers(String direction) {
|
||||||
var offers = offerBookService.getOffers().stream()
|
return offerBookService.getOffers().stream()
|
||||||
.filter(o -> o.isMyOffer(keyRing))
|
.filter(o -> o.isMyOffer(keyRing))
|
||||||
.filter(o -> o.getDirection().name().equalsIgnoreCase(direction))
|
.filter(o -> o.getDirection().name().equalsIgnoreCase(direction))
|
||||||
.filter(Offer::isBsqSwapOffer)
|
.filter(Offer::isBsqSwapOffer)
|
||||||
.sorted(priceComparator(direction))
|
.sorted(priceComparator(direction))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return offers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenOffer getMyOpenBsqSwapOffer(String id) {
|
OpenOffer getMyOpenBsqSwapOffer(String id) {
|
||||||
|
@ -208,9 +210,12 @@ class CoreOffersService {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isMyOffer(String id) {
|
boolean isMyOffer(String id) {
|
||||||
return openOfferManager.getOpenOfferById(id)
|
boolean isMyOpenOffer = openOfferManager.getOpenOfferById(id)
|
||||||
.filter(open -> open.getOffer().isMyOffer(keyRing))
|
.filter(open -> open.getOffer().isMyOffer(keyRing))
|
||||||
.isPresent();
|
.isPresent();
|
||||||
|
boolean wasMyOffer = offerBookService.getOffers().stream()
|
||||||
|
.anyMatch(o -> o.getId().equals(id) && o.isMyOffer(keyRing));
|
||||||
|
return isMyOpenOffer || wasMyOffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createAndPlaceBsqSwapOffer(String directionAsString,
|
void createAndPlaceBsqSwapOffer(String directionAsString,
|
||||||
|
@ -222,7 +227,7 @@ class CoreOffersService {
|
||||||
coreWalletsService.verifyEncryptedWalletIsUnlocked();
|
coreWalletsService.verifyEncryptedWalletIsUnlocked();
|
||||||
|
|
||||||
String currencyCode = "BSQ";
|
String currencyCode = "BSQ";
|
||||||
String offerId = OfferUtil.getRandomOfferId();
|
String offerId = getRandomOfferId();
|
||||||
OfferDirection direction = OfferDirection.valueOf(directionAsString.toUpperCase());
|
OfferDirection direction = OfferDirection.valueOf(directionAsString.toUpperCase());
|
||||||
Coin amount = Coin.valueOf(amountAsLong);
|
Coin amount = Coin.valueOf(amountAsLong);
|
||||||
Coin minAmount = Coin.valueOf(minAmountAsLong);
|
Coin minAmount = Coin.valueOf(minAmountAsLong);
|
||||||
|
@ -256,7 +261,7 @@ class CoreOffersService {
|
||||||
throw new IllegalArgumentException(format("payment account with id %s not found", paymentAccountId));
|
throw new IllegalArgumentException(format("payment account with id %s not found", paymentAccountId));
|
||||||
|
|
||||||
String upperCaseCurrencyCode = currencyCode.toUpperCase();
|
String upperCaseCurrencyCode = currencyCode.toUpperCase();
|
||||||
String offerId = OfferUtil.getRandomOfferId();
|
String offerId = getRandomOfferId();
|
||||||
OfferDirection direction = OfferDirection.valueOf(directionAsString.toUpperCase());
|
OfferDirection direction = OfferDirection.valueOf(directionAsString.toUpperCase());
|
||||||
Price price = Price.valueOf(upperCaseCurrencyCode, priceStringToLong(priceAsString, upperCaseCurrencyCode));
|
Price price = Price.valueOf(upperCaseCurrencyCode, priceStringToLong(priceAsString, upperCaseCurrencyCode));
|
||||||
Coin amount = Coin.valueOf(amountAsLong);
|
Coin amount = Coin.valueOf(amountAsLong);
|
||||||
|
@ -375,6 +380,38 @@ class CoreOffersService {
|
||||||
throw new IllegalStateException(offer.getErrorMessage());
|
throw new IllegalStateException(offer.getErrorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<Offer> findAvailableBsqSwapOffer(String id) {
|
||||||
|
return offerBookService.getOffers().stream()
|
||||||
|
.filter(o -> o.getId().equals(id))
|
||||||
|
.filter(o -> !o.isMyOffer(keyRing))
|
||||||
|
.filter(o -> offerFilterService.canTakeOffer(o, coreContext.isApiUser()).isValid())
|
||||||
|
.filter(Offer::isBsqSwapOffer)
|
||||||
|
.findAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Offer> findMyBsqSwapOffer(String id) {
|
||||||
|
return offerBookService.getOffers().stream()
|
||||||
|
.filter(o -> o.getId().equals(id))
|
||||||
|
.filter(o -> o.isMyOffer(keyRing))
|
||||||
|
.filter(Offer::isBsqSwapOffer)
|
||||||
|
.findAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Offer> findAvailableOffer(String id) {
|
||||||
|
return offerBookService.getOffers().stream()
|
||||||
|
.filter(o -> o.getId().equals(id))
|
||||||
|
.filter(o -> !o.isMyOffer(keyRing))
|
||||||
|
.filter(o -> offerFilterService.canTakeOffer(o, coreContext.isApiUser()).isValid())
|
||||||
|
.findAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<OpenOffer> findMyOpenOffer(String id) {
|
||||||
|
return openOfferManager.getObservableList().stream()
|
||||||
|
.filter(o -> o.getId().equals(id))
|
||||||
|
.filter(o -> o.getOffer().isMyOffer(keyRing))
|
||||||
|
.findAny();
|
||||||
|
}
|
||||||
|
|
||||||
private OfferPayload getMergedOfferPayload(OpenOffer openOffer,
|
private OfferPayload getMergedOfferPayload(OpenOffer openOffer,
|
||||||
String editedPriceAsString,
|
String editedPriceAsString,
|
||||||
double editedMarketPriceMargin,
|
double editedMarketPriceMargin,
|
||||||
|
@ -427,10 +464,9 @@ class CoreOffersService {
|
||||||
private boolean offerMatchesDirectionAndCurrency(Offer offer,
|
private boolean offerMatchesDirectionAndCurrency(Offer offer,
|
||||||
String direction,
|
String direction,
|
||||||
String currencyCode) {
|
String currencyCode) {
|
||||||
var offerOfWantedDirection = offer.getDirection().name().equalsIgnoreCase(direction);
|
var isDirectionMatch = offer.getDirection().name().equalsIgnoreCase(direction);
|
||||||
var offerInWantedCurrency = offer.getCounterCurrencyCode()
|
var isCurrencyMatch = offer.getCounterCurrencyCode().equalsIgnoreCase(currencyCode);
|
||||||
.equalsIgnoreCase(currencyCode);
|
return isDirectionMatch && isCurrencyMatch;
|
||||||
return offerOfWantedDirection && offerInWantedCurrency;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Comparator<OpenOffer> openOfferPriceComparator(String direction) {
|
private Comparator<OpenOffer> openOfferPriceComparator(String direction) {
|
||||||
|
|
|
@ -28,6 +28,7 @@ import bisq.core.trade.TradeManager;
|
||||||
import bisq.core.trade.bisq_v1.TradeResultHandler;
|
import bisq.core.trade.bisq_v1.TradeResultHandler;
|
||||||
import bisq.core.trade.bisq_v1.TradeUtil;
|
import bisq.core.trade.bisq_v1.TradeUtil;
|
||||||
import bisq.core.trade.model.Tradable;
|
import bisq.core.trade.model.Tradable;
|
||||||
|
import bisq.core.trade.model.TradeModel;
|
||||||
import bisq.core.trade.model.bisq_v1.Trade;
|
import bisq.core.trade.model.bisq_v1.Trade;
|
||||||
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
|
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
|
||||||
import bisq.core.trade.protocol.bisq_v1.BuyerProtocol;
|
import bisq.core.trade.protocol.bisq_v1.BuyerProtocol;
|
||||||
|
@ -91,27 +92,26 @@ class CoreTradesService {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo we need to pass the intended trade amount
|
// TODO We need to pass the intended trade amount, not default to the maximum.
|
||||||
void takeBsqSwapOffer(Offer offer,
|
void takeBsqSwapOffer(Offer offer,
|
||||||
String paymentAccountId,
|
|
||||||
String takerFeeCurrencyCode,
|
|
||||||
TradeResultHandler<BsqSwapTrade> tradeResultHandler,
|
TradeResultHandler<BsqSwapTrade> tradeResultHandler,
|
||||||
ErrorMessageHandler errorMessageHandler) {
|
ErrorMessageHandler errorMessageHandler) {
|
||||||
coreWalletsService.verifyWalletsAreAvailable();
|
coreWalletsService.verifyWalletsAreAvailable();
|
||||||
coreWalletsService.verifyEncryptedWalletIsUnlocked();
|
coreWalletsService.verifyEncryptedWalletIsUnlocked();
|
||||||
|
|
||||||
bsqSwapTakeOfferModel.initWithData(offer);
|
bsqSwapTakeOfferModel.initWithData(offer);
|
||||||
|
|
||||||
//todo use the intended trade amount
|
|
||||||
bsqSwapTakeOfferModel.applyAmount(offer.getAmount());
|
bsqSwapTakeOfferModel.applyAmount(offer.getAmount());
|
||||||
|
|
||||||
log.info("Initiating take {} offer, {}",
|
log.info("Initiating take {} offer, {}",
|
||||||
offer.isBuyOffer() ? "buy" : "sell",
|
offer.isBuyOffer() ? "buy" : "sell",
|
||||||
bsqSwapTakeOfferModel);
|
bsqSwapTakeOfferModel);
|
||||||
|
bsqSwapTakeOfferModel.onTakeOffer(tradeResultHandler,
|
||||||
bsqSwapTakeOfferModel.onTakeOffer(tradeResultHandler, log::warn, errorMessageHandler, coreContext.isApiUser());
|
log::warn,
|
||||||
|
errorMessageHandler,
|
||||||
|
coreContext.isApiUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO We need to pass the intended trade amount, not default to the maximum.
|
||||||
void takeOffer(Offer offer,
|
void takeOffer(Offer offer,
|
||||||
String paymentAccountId,
|
String paymentAccountId,
|
||||||
String takerFeeCurrencyCode,
|
String takerFeeCurrencyCode,
|
||||||
|
@ -232,13 +232,28 @@ class CoreTradesService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
BsqSwapTrade getBsqSwapTrade(String tradeId) {
|
TradeModel getTradeModel(String tradeId) {
|
||||||
coreWalletsService.verifyWalletsAreAvailable();
|
coreWalletsService.verifyWalletsAreAvailable();
|
||||||
coreWalletsService.verifyEncryptedWalletIsUnlocked();
|
coreWalletsService.verifyEncryptedWalletIsUnlocked();
|
||||||
|
|
||||||
|
Optional<Trade> openTrade = getOpenTrade(tradeId);
|
||||||
|
if (openTrade.isPresent())
|
||||||
|
return openTrade.get();
|
||||||
|
|
||||||
|
Optional<Trade> closedTrade = getClosedTrade(tradeId);
|
||||||
|
if (closedTrade.isPresent())
|
||||||
|
return closedTrade.get();
|
||||||
|
|
||||||
return tradeManager.findBsqSwapTradeById(tradeId).orElseThrow(() ->
|
return tradeManager.findBsqSwapTradeById(tradeId).orElseThrow(() ->
|
||||||
new IllegalArgumentException(format("trade with id '%s' not found", tradeId)));
|
new IllegalArgumentException(format("trade with id '%s' not found", tradeId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getBsqSwapTradeRole(BsqSwapTrade bsqSwapTrade) {
|
||||||
|
coreWalletsService.verifyWalletsAreAvailable();
|
||||||
|
coreWalletsService.verifyEncryptedWalletIsUnlocked();
|
||||||
|
return tradeUtil.getRole(bsqSwapTrade);
|
||||||
|
}
|
||||||
|
|
||||||
String getTradeRole(String tradeId) {
|
String getTradeRole(String tradeId) {
|
||||||
coreWalletsService.verifyWalletsAreAvailable();
|
coreWalletsService.verifyWalletsAreAvailable();
|
||||||
coreWalletsService.verifyEncryptedWalletIsUnlocked();
|
coreWalletsService.verifyEncryptedWalletIsUnlocked();
|
||||||
|
|
|
@ -85,6 +85,7 @@ import javax.annotation.Nullable;
|
||||||
import static bisq.core.btc.wallet.Restrictions.getMinNonDustOutput;
|
import static bisq.core.btc.wallet.Restrictions.getMinNonDustOutput;
|
||||||
import static bisq.core.util.ParsingUtils.parseToCoin;
|
import static bisq.core.util.ParsingUtils.parseToCoin;
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
|
@ -209,10 +210,10 @@ class CoreWalletsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
return addressStrings.stream().map(address ->
|
return addressStrings.stream().map(address ->
|
||||||
new AddressBalanceInfo(address,
|
new AddressBalanceInfo(address,
|
||||||
balances.getUnchecked(address),
|
balances.getUnchecked(address),
|
||||||
getNumConfirmationsForMostRecentTransaction(address),
|
getNumConfirmationsForMostRecentTransaction(address),
|
||||||
btcWalletService.isAddressUnused(getAddressEntry(address).getAddress())))
|
btcWalletService.isAddressUnused(getAddressEntry(address).getAddress())))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +325,7 @@ class CoreWalletsService {
|
||||||
for (TransactionOutput txOut : spendableBsqTxOutputs) {
|
for (TransactionOutput txOut : spendableBsqTxOutputs) {
|
||||||
if (isTxOutputAddressMatch.test(txOut) && isTxOutputValueMatch.test(txOut)) {
|
if (isTxOutputAddressMatch.test(txOut) && isTxOutputValueMatch.test(txOut)) {
|
||||||
log.info("\t\tTx {} output has matching address {} and value {}.",
|
log.info("\t\tTx {} output has matching address {} and value {}.",
|
||||||
txOut.getParentTransaction().getTxId(),
|
requireNonNull(txOut.getParentTransaction()).getTxId(),
|
||||||
address,
|
address,
|
||||||
txOut.getValue().toPlainString());
|
txOut.getValue().toPlainString());
|
||||||
numMatches++;
|
numMatches++;
|
||||||
|
@ -346,6 +347,7 @@ class CoreWalletsService {
|
||||||
@SuppressWarnings({"unchecked", "Convert2MethodRef"})
|
@SuppressWarnings({"unchecked", "Convert2MethodRef"})
|
||||||
ListenableFuture<Void> future =
|
ListenableFuture<Void> future =
|
||||||
(ListenableFuture<Void>) executor.submit(() -> feeService.requestFees());
|
(ListenableFuture<Void>) executor.submit(() -> feeService.requestFees());
|
||||||
|
//noinspection NullableProblems
|
||||||
Futures.addCallback(future, new FutureCallback<>() {
|
Futures.addCallback(future, new FutureCallback<>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable Void ignored) {
|
public void onSuccess(@Nullable Void ignored) {
|
||||||
|
@ -393,23 +395,11 @@ class CoreWalletsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Transaction getTransaction(String txId) {
|
Transaction getTransaction(String txId) {
|
||||||
if (txId.length() != 64)
|
return getTransactionWithId(txId);
|
||||||
throw new IllegalArgumentException(format("%s is not a transaction id", txId));
|
}
|
||||||
|
|
||||||
try {
|
int getTransactionConfirmations(String txId) {
|
||||||
Transaction tx = btcWalletService.getTransaction(txId);
|
return getTransactionWithId(txId).getConfidence().getDepthInBlocks();
|
||||||
if (tx == null)
|
|
||||||
throw new IllegalArgumentException(format("tx with id %s not found", txId));
|
|
||||||
else
|
|
||||||
return tx;
|
|
||||||
|
|
||||||
} catch (IllegalArgumentException ex) {
|
|
||||||
log.error("", ex);
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
format("could not get transaction with id %s%ncause: %s",
|
|
||||||
txId,
|
|
||||||
ex.getMessage().toLowerCase()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int getNumConfirmationsForMostRecentTransaction(String addressString) {
|
int getNumConfirmationsForMostRecentTransaction(String addressString) {
|
||||||
|
@ -654,12 +644,32 @@ class CoreWalletsService {
|
||||||
return addressEntry.get();
|
return addressEntry.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Transaction getTransactionWithId(String txId) {
|
||||||
|
if (txId.length() != 64)
|
||||||
|
throw new IllegalArgumentException(format("%s is not a transaction id", txId));
|
||||||
|
|
||||||
|
try {
|
||||||
|
Transaction tx = btcWalletService.getTransaction(txId);
|
||||||
|
if (tx == null)
|
||||||
|
throw new IllegalArgumentException(format("tx with id %s not found", txId));
|
||||||
|
else
|
||||||
|
return tx;
|
||||||
|
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
log.error("", ex);
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
format("could not get transaction with id %s%ncause: %s",
|
||||||
|
txId,
|
||||||
|
ex.getMessage().toLowerCase()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memoization stores the results of expensive function calls and returns
|
* Memoization stores the results of expensive function calls and returns
|
||||||
* the cached result when the same input occurs again.
|
* the cached result when the same input occurs again.
|
||||||
*
|
*
|
||||||
* Resulting LoadingCache is used by calling `.get(input I)` or
|
* Resulting LoadingCache is used by calling `.get(input I)` or
|
||||||
* `.getUnchecked(input I)`, depending on whether or not `f` can return null.
|
* `.getUnchecked(input I)`, depending on whether `f` can return null.
|
||||||
* That's because CacheLoader throws an exception on null output from `f`.
|
* That's because CacheLoader throws an exception on null output from `f`.
|
||||||
*/
|
*/
|
||||||
private static <I, O> LoadingCache<I, O> memoize(Function<I, O> f) {
|
private static <I, O> LoadingCache<I, O> memoize(Function<I, O> f) {
|
||||||
|
|
|
@ -45,7 +45,8 @@ class EditOfferValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
void validate() {
|
void validate() {
|
||||||
log.info("Verifying 'editoffer' params OK for editType {}", editType);
|
log.info("Verifying 'editoffer' params for editType {}", editType);
|
||||||
|
checkNotBsqSwapOffer();
|
||||||
switch (editType) {
|
switch (editType) {
|
||||||
case ACTIVATION_STATE_ONLY: {
|
case ACTIVATION_STATE_ONLY: {
|
||||||
validateEditedActivationState();
|
validateEditedActivationState();
|
||||||
|
@ -138,4 +139,11 @@ class EditOfferValidator {
|
||||||
currentlyOpenOffer.getId()));
|
currentlyOpenOffer.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkNotBsqSwapOffer() {
|
||||||
|
if (currentlyOpenOffer.getOffer().isBsqSwapOffer()) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
format("cannot edit bsq swap offer with id '%s'", currentlyOpenOffer.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,227 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.core.api.model;
|
|
||||||
|
|
||||||
import bisq.core.offer.Offer;
|
|
||||||
|
|
||||||
import bisq.common.Payload;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
@EqualsAndHashCode
|
|
||||||
@ToString
|
|
||||||
@Getter
|
|
||||||
public class BsqSwapOfferInfo implements Payload {
|
|
||||||
private final String id;
|
|
||||||
private final String direction;
|
|
||||||
private final long amount;
|
|
||||||
private final long minAmount;
|
|
||||||
private final long price;
|
|
||||||
private final String makerPaymentAccountId;
|
|
||||||
private final String paymentMethodId;
|
|
||||||
private final String paymentMethodShortName;
|
|
||||||
private final String baseCurrencyCode;
|
|
||||||
private final String counterCurrencyCode;
|
|
||||||
private final long date;
|
|
||||||
private final String ownerNodeAddress;
|
|
||||||
private final String pubKeyRing; // TODO ?
|
|
||||||
private final String versionNumber;
|
|
||||||
private final int protocolVersion;
|
|
||||||
|
|
||||||
public BsqSwapOfferInfo(BsqSwapOfferInfoBuilder builder) {
|
|
||||||
this.id = builder.id;
|
|
||||||
this.direction = builder.direction;
|
|
||||||
this.amount = builder.amount;
|
|
||||||
this.minAmount = builder.minAmount;
|
|
||||||
this.price = builder.price;
|
|
||||||
this.makerPaymentAccountId = builder.makerPaymentAccountId;
|
|
||||||
this.paymentMethodId = builder.paymentMethodId;
|
|
||||||
this.paymentMethodShortName = builder.paymentMethodShortName;
|
|
||||||
this.baseCurrencyCode = builder.baseCurrencyCode;
|
|
||||||
this.counterCurrencyCode = builder.counterCurrencyCode;
|
|
||||||
this.date = builder.date;
|
|
||||||
this.ownerNodeAddress = builder.ownerNodeAddress;
|
|
||||||
this.pubKeyRing = builder.pubKeyRing;
|
|
||||||
this.versionNumber = builder.versionNumber;
|
|
||||||
this.protocolVersion = builder.protocolVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BsqSwapOfferInfo toBsqSwapOfferInfo(Offer offer) {
|
|
||||||
// TODO support triggerPrice
|
|
||||||
return getAtomicOfferInfoBuilder(offer).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BsqSwapOfferInfoBuilder getAtomicOfferInfoBuilder(Offer offer) {
|
|
||||||
return new BsqSwapOfferInfoBuilder()
|
|
||||||
.withId(offer.getId())
|
|
||||||
.withDirection(offer.getDirection().name())
|
|
||||||
.withAmount(offer.getAmount().value)
|
|
||||||
.withMinAmount(offer.getMinAmount().value)
|
|
||||||
.withPrice(Objects.requireNonNull(offer.getPrice()).getValue())
|
|
||||||
//.withMakerPaymentAccountId(offer.getOfferPayloadI().getMakerPaymentAccountId())
|
|
||||||
//.withPaymentMethodId(offer.getOfferPayloadI().getPaymentMethodId())
|
|
||||||
//.withPaymentMethodShortName(getPaymentMethodById(offer.getOfferPayloadI().getPaymentMethodId()).getShortName())
|
|
||||||
.withBaseCurrencyCode(offer.getOfferPayloadBase().getBaseCurrencyCode())
|
|
||||||
.withCounterCurrencyCode(offer.getOfferPayloadBase().getCounterCurrencyCode())
|
|
||||||
.withDate(offer.getDate().getTime())
|
|
||||||
.withOwnerNodeAddress(offer.getOfferPayloadBase().getOwnerNodeAddress().getFullAddress())
|
|
||||||
.withPubKeyRing(offer.getOfferPayloadBase().getPubKeyRing().toString())
|
|
||||||
.withVersionNumber(offer.getOfferPayloadBase().getVersionNr())
|
|
||||||
.withProtocolVersion(offer.getOfferPayloadBase().getProtocolVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROTO BUFFER
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public bisq.proto.grpc.BsqSwapOfferInfo toProtoMessage() {
|
|
||||||
return bisq.proto.grpc.BsqSwapOfferInfo.newBuilder()
|
|
||||||
.setId(id)
|
|
||||||
.setDirection(direction)
|
|
||||||
.setAmount(amount)
|
|
||||||
.setMinAmount(minAmount)
|
|
||||||
.setPrice(price)
|
|
||||||
.setBaseCurrencyCode(baseCurrencyCode)
|
|
||||||
.setCounterCurrencyCode(counterCurrencyCode)
|
|
||||||
.setDate(date)
|
|
||||||
.setOwnerNodeAddress(ownerNodeAddress)
|
|
||||||
.setPubKeyRing(pubKeyRing)
|
|
||||||
.setVersionNr(versionNumber)
|
|
||||||
.setProtocolVersion(protocolVersion)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BsqSwapOfferInfo fromProto(bisq.proto.grpc.BsqSwapOfferInfo proto) {
|
|
||||||
return new BsqSwapOfferInfoBuilder()
|
|
||||||
.withId(proto.getId())
|
|
||||||
.withDirection(proto.getDirection())
|
|
||||||
.withAmount(proto.getAmount())
|
|
||||||
.withMinAmount(proto.getMinAmount())
|
|
||||||
.withPrice(proto.getPrice())
|
|
||||||
.withBaseCurrencyCode(proto.getBaseCurrencyCode())
|
|
||||||
.withCounterCurrencyCode(proto.getCounterCurrencyCode())
|
|
||||||
.withDate(proto.getDate())
|
|
||||||
.withOwnerNodeAddress(proto.getOwnerNodeAddress())
|
|
||||||
.withPubKeyRing(proto.getPubKeyRing())
|
|
||||||
.withVersionNumber(proto.getVersionNr())
|
|
||||||
.withProtocolVersion(proto.getProtocolVersion())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class BsqSwapOfferInfoBuilder {
|
|
||||||
private String id;
|
|
||||||
private String direction;
|
|
||||||
private long amount;
|
|
||||||
private long minAmount;
|
|
||||||
private long price;
|
|
||||||
private String makerPaymentAccountId;
|
|
||||||
private String paymentMethodId;
|
|
||||||
private String paymentMethodShortName;
|
|
||||||
private String baseCurrencyCode;
|
|
||||||
private String counterCurrencyCode;
|
|
||||||
private long date;
|
|
||||||
private String ownerNodeAddress;
|
|
||||||
private String pubKeyRing;
|
|
||||||
private String versionNumber;
|
|
||||||
private int protocolVersion;
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withDirection(String direction) {
|
|
||||||
this.direction = direction;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withAmount(long amount) {
|
|
||||||
this.amount = amount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withMinAmount(long minAmount) {
|
|
||||||
this.minAmount = minAmount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withPrice(long price) {
|
|
||||||
this.price = price;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withMakerPaymentAccountId(String makerPaymentAccountId) {
|
|
||||||
this.makerPaymentAccountId = makerPaymentAccountId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withPaymentMethodId(String paymentMethodId) {
|
|
||||||
this.paymentMethodId = paymentMethodId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withPaymentMethodShortName(String paymentMethodShortName) {
|
|
||||||
this.paymentMethodShortName = paymentMethodShortName;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withBaseCurrencyCode(String baseCurrencyCode) {
|
|
||||||
this.baseCurrencyCode = baseCurrencyCode;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withCounterCurrencyCode(String counterCurrencyCode) {
|
|
||||||
this.counterCurrencyCode = counterCurrencyCode;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withDate(long date) {
|
|
||||||
this.date = date;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withOwnerNodeAddress(String ownerNodeAddress) {
|
|
||||||
this.ownerNodeAddress = ownerNodeAddress;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withPubKeyRing(String pubKeyRing) {
|
|
||||||
this.pubKeyRing = pubKeyRing;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withVersionNumber(String versionNumber) {
|
|
||||||
this.versionNumber = versionNumber;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfoBuilder withProtocolVersion(int protocolVersion) {
|
|
||||||
this.protocolVersion = protocolVersion;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapOfferInfo build() {
|
|
||||||
return new BsqSwapOfferInfo(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,100 +17,67 @@
|
||||||
|
|
||||||
package bisq.core.api.model;
|
package bisq.core.api.model;
|
||||||
|
|
||||||
|
import bisq.core.api.model.builder.BsqSwapTradeInfoBuilder;
|
||||||
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
|
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
|
||||||
|
|
||||||
import bisq.common.Payload;
|
import bisq.common.Payload;
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
import static bisq.core.api.model.BsqSwapOfferInfo.toBsqSwapOfferInfo;
|
|
||||||
|
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
@ToString
|
|
||||||
@Getter
|
@Getter
|
||||||
public class BsqSwapTradeInfo implements Payload {
|
public class BsqSwapTradeInfo implements Payload {
|
||||||
|
|
||||||
private final BsqSwapOfferInfo bsqSwapOffer;
|
|
||||||
private final String tradeId;
|
|
||||||
private final String tempTradingPeerNodeAddress;
|
|
||||||
private final String peerNodeAddress;
|
|
||||||
private final String txId;
|
private final String txId;
|
||||||
private final long bsqTradeAmount;
|
private final long bsqTradeAmount;
|
||||||
private final long bsqMaxTradeAmount;
|
|
||||||
private final long bsqMinTradeAmount;
|
|
||||||
private final long btcTradeAmount;
|
private final long btcTradeAmount;
|
||||||
private final long btcMaxTradeAmount;
|
|
||||||
private final long btcMinTradeAmount;
|
|
||||||
private final long tradePrice;
|
|
||||||
private final long bsqMakerTradeFee;
|
private final long bsqMakerTradeFee;
|
||||||
private final long bsqTakerTradeFee;
|
private final long bsqTakerTradeFee;
|
||||||
private final long txFeePerVbyte;
|
private final long txFeePerVbyte;
|
||||||
private final long txFee;
|
|
||||||
private final String makerBsqAddress;
|
private final String makerBsqAddress;
|
||||||
private final String makerBtcAddress;
|
private final String makerBtcAddress;
|
||||||
private final String takerBsqAddress;
|
private final String takerBsqAddress;
|
||||||
private final String takerBtcAddress;
|
private final String takerBtcAddress;
|
||||||
private final long takeOfferDate;
|
private final long numConfirmations;
|
||||||
private final String state;
|
|
||||||
private final String errorMessage;
|
private final String errorMessage;
|
||||||
|
|
||||||
public BsqSwapTradeInfo(BsqSwapTradeInfoBuilder builder) {
|
public BsqSwapTradeInfo(BsqSwapTradeInfoBuilder builder) {
|
||||||
this.bsqSwapOffer = builder.bsqSwapOfferInfo;
|
this.txId = builder.getTxId();
|
||||||
this.tradeId = builder.tradeId;
|
this.bsqTradeAmount = builder.getBsqTradeAmount();
|
||||||
this.tempTradingPeerNodeAddress = builder.tempTradingPeerNodeAddress;
|
this.btcTradeAmount = builder.getBtcTradeAmount();
|
||||||
this.peerNodeAddress = builder.peerNodeAddress;
|
this.bsqMakerTradeFee = builder.getBsqMakerTradeFee();
|
||||||
this.txId = builder.txId;
|
this.bsqTakerTradeFee = builder.getBsqTakerTradeFee();
|
||||||
this.bsqTradeAmount = builder.bsqTradeAmount;
|
this.txFeePerVbyte = builder.getTxFeePerVbyte();
|
||||||
this.bsqMaxTradeAmount = builder.bsqMaxTradeAmount;
|
this.makerBsqAddress = builder.getMakerBsqAddress();
|
||||||
this.bsqMinTradeAmount = builder.bsqMinTradeAmount;
|
this.makerBtcAddress = builder.getMakerBtcAddress();
|
||||||
this.btcTradeAmount = builder.btcTradeAmount;
|
this.takerBsqAddress = builder.getTakerBsqAddress();
|
||||||
this.btcMaxTradeAmount = builder.btcMaxTradeAmount;
|
this.takerBtcAddress = builder.getTakerBtcAddress();
|
||||||
this.btcMinTradeAmount = builder.btcMinTradeAmount;
|
this.numConfirmations = builder.getNumConfirmations();
|
||||||
this.tradePrice = builder.tradePrice;
|
this.errorMessage = builder.getErrorMessage();
|
||||||
this.bsqMakerTradeFee = builder.bsqMakerTradeFee;
|
|
||||||
this.bsqTakerTradeFee = builder.bsqTakerTradeFee;
|
|
||||||
this.txFeePerVbyte = builder.txFeePerVbyte;
|
|
||||||
this.txFee = builder.txFee;
|
|
||||||
this.makerBsqAddress = builder.makerBsqAddress;
|
|
||||||
this.makerBtcAddress = builder.makerBtcAddress;
|
|
||||||
this.takerBsqAddress = builder.takerBsqAddress;
|
|
||||||
this.takerBtcAddress = builder.takerBtcAddress;
|
|
||||||
this.takeOfferDate = builder.takeOfferDate;
|
|
||||||
this.state = builder.state;
|
|
||||||
this.errorMessage = builder.errorMessage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BsqSwapTradeInfo toBsqSwapTradeInfo(BsqSwapTrade trade) {
|
public static BsqSwapTradeInfo toBsqSwapTradeInfo(BsqSwapTrade trade,
|
||||||
return toBsqSwapTradeInfo(trade, null);
|
boolean wasMyOffer,
|
||||||
}
|
int numConfirmations) {
|
||||||
|
var protocolModel = trade.getBsqSwapProtocolModel();
|
||||||
//TODO
|
var swapPeer = protocolModel.getTradePeer();
|
||||||
public static BsqSwapTradeInfo toBsqSwapTradeInfo(BsqSwapTrade trade, String role) {
|
var makerBsqAddress = wasMyOffer ? protocolModel.getBsqAddress() : swapPeer.getBsqAddress();
|
||||||
|
var makerBtcAddress = wasMyOffer ? protocolModel.getBtcAddress() : swapPeer.getBtcAddress();
|
||||||
|
var takerBsqAddress = wasMyOffer ? swapPeer.getBsqAddress() : protocolModel.getBsqAddress();
|
||||||
|
var takerBtcAddress = wasMyOffer ? swapPeer.getBtcAddress() : protocolModel.getBtcAddress();
|
||||||
return new BsqSwapTradeInfoBuilder()
|
return new BsqSwapTradeInfoBuilder()
|
||||||
.withBsqSwapOffer(toBsqSwapOfferInfo(trade.getOffer()))
|
|
||||||
.withTradeId(trade.getId())
|
|
||||||
.withTempTradingPeerNodeAddress(trade.getBsqSwapProtocolModel().getTempTradingPeerNodeAddress().getFullAddress())
|
|
||||||
.withPeerNodeAddress(trade.getTradingPeerNodeAddress().getFullAddress())
|
|
||||||
.withTxId(trade.getTxId())
|
.withTxId(trade.getTxId())
|
||||||
/* .withBsqTradeAmount(trade.getBsqSwapProtocolModel().getBsqTradeAmount())
|
.withBsqTradeAmount(trade.getBsqTradeAmount())
|
||||||
.withBsqMaxTradeAmount(trade.getBsqSwapProtocolModel().getBsqMaxTradeAmount())
|
.withBtcTradeAmount(trade.getAmountAsLong())
|
||||||
.withBsqMinTradeAmount(trade.getBsqSwapProtocolModel().getBsqMinTradeAmount())
|
.withBsqMakerTradeFee(trade.getMakerFeeAsLong())
|
||||||
.withBtcTradeAmount(trade.getBsqSwapProtocolModel().getBtcTradeAmount())
|
.withBsqTakerTradeFee(trade.getTakerFeeAsLong())
|
||||||
.withBtcMaxTradeAmount(trade.getBsqSwapProtocolModel().getBtcMaxTradeAmount())
|
.withTxFeePerVbyte(trade.getTxFeePerVbyte())
|
||||||
.withBtcMinTradeAmount(trade.getBsqSwapProtocolModel().getBtcMinTradeAmount())
|
.withMakerBsqAddress(makerBsqAddress)
|
||||||
.withTradePrice(trade.getBsqSwapProtocolModel().getTradePrice())
|
.withMakerBtcAddress(makerBtcAddress)
|
||||||
.withBsqMakerTradeFee(trade.getBsqSwapProtocolModel().getBsqMakerTradeFee())
|
.withTakerBsqAddress(takerBsqAddress)
|
||||||
.withBsqTakerTradeFee(trade.getBsqSwapProtocolModel().getBsqTakerTradeFee())
|
.withTakerBtcAddress(takerBtcAddress)
|
||||||
.withTxFeePerVbyte(trade.getBsqSwapProtocolModel().getTxFeePerVbyte())
|
.withNumConfirmations(numConfirmations)
|
||||||
.withTxFee(trade.getBsqSwapProtocolModel().getTxFee())
|
|
||||||
.withMakerBsqAddress(trade.getBsqSwapProtocolModel().getMakerBsqAddress())
|
|
||||||
.withMakerBtcAddress(trade.getBsqSwapProtocolModel().getMakerBtcAddress())
|
|
||||||
.withTakerBsqAddress(trade.getBsqSwapProtocolModel().getTakerBsqAddress())
|
|
||||||
.withTakerBtcAddress(trade.getBsqSwapProtocolModel().getTakerBtcAddress())*/
|
|
||||||
.withTakeOfferDate(trade.getTakeOfferDate())
|
|
||||||
.withState(trade.getTradeState().name())
|
|
||||||
.withErrorMessage(trade.getErrorMessage())
|
.withErrorMessage(trade.getErrorMessage())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
@ -122,202 +89,53 @@ public class BsqSwapTradeInfo implements Payload {
|
||||||
@Override
|
@Override
|
||||||
public bisq.proto.grpc.BsqSwapTradeInfo toProtoMessage() {
|
public bisq.proto.grpc.BsqSwapTradeInfo toProtoMessage() {
|
||||||
return bisq.proto.grpc.BsqSwapTradeInfo.newBuilder()
|
return bisq.proto.grpc.BsqSwapTradeInfo.newBuilder()
|
||||||
.setBsqSwapOfferInfo(bsqSwapOffer.toProtoMessage())
|
|
||||||
.setTradeId(tradeId)
|
|
||||||
.setTempTradingPeerNodeAddress(tempTradingPeerNodeAddress != null ? tempTradingPeerNodeAddress : "")
|
|
||||||
.setPeerNodeAddress(peerNodeAddress != null ? peerNodeAddress : "")
|
|
||||||
.setTxId(txId != null ? txId : "")
|
.setTxId(txId != null ? txId : "")
|
||||||
.setBsqTradeAmount(bsqTradeAmount)
|
.setBsqTradeAmount(bsqTradeAmount)
|
||||||
.setBsqMaxTradeAmount(bsqMaxTradeAmount)
|
|
||||||
.setBsqMinTradeAmount(bsqMinTradeAmount)
|
|
||||||
.setBtcTradeAmount(btcTradeAmount)
|
.setBtcTradeAmount(btcTradeAmount)
|
||||||
.setBtcMaxTradeAmount(btcMaxTradeAmount)
|
|
||||||
.setBtcMinTradeAmount(btcMinTradeAmount)
|
|
||||||
.setTradePrice(tradePrice)
|
|
||||||
.setBsqMakerTradeFee(bsqMakerTradeFee)
|
.setBsqMakerTradeFee(bsqMakerTradeFee)
|
||||||
.setBsqTakerTradeFee(bsqTakerTradeFee)
|
.setBsqTakerTradeFee(bsqTakerTradeFee)
|
||||||
.setTxFeePerVbyte(txFeePerVbyte)
|
.setTxFeePerVbyte(txFeePerVbyte)
|
||||||
.setTxFee(txFee)
|
|
||||||
.setMakerBsqAddress(makerBsqAddress != null ? makerBsqAddress : "")
|
.setMakerBsqAddress(makerBsqAddress != null ? makerBsqAddress : "")
|
||||||
.setTakerBsqAddress(takerBsqAddress != null ? takerBsqAddress : "")
|
.setTakerBsqAddress(takerBsqAddress != null ? takerBsqAddress : "")
|
||||||
.setMakerBtcAddress(makerBtcAddress != null ? makerBtcAddress : "")
|
.setMakerBtcAddress(makerBtcAddress != null ? makerBtcAddress : "")
|
||||||
.setTakerBtcAddress(takerBtcAddress != null ? takerBtcAddress : "")
|
.setTakerBtcAddress(takerBtcAddress != null ? takerBtcAddress : "")
|
||||||
.setTakeOfferDate(takeOfferDate)
|
.setTakerBtcAddress(takerBtcAddress != null ? takerBtcAddress : "")
|
||||||
.setState(state)
|
.setNumConfirmations(numConfirmations)
|
||||||
.setErrorMessage(errorMessage != null ? errorMessage : "")
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BsqSwapTradeInfo fromProto(bisq.proto.grpc.BsqSwapTradeInfo proto) {
|
public static BsqSwapTradeInfo fromProto(bisq.proto.grpc.BsqSwapTradeInfo proto) {
|
||||||
return new BsqSwapTradeInfoBuilder()
|
return new BsqSwapTradeInfoBuilder()
|
||||||
.withBsqSwapOffer(BsqSwapOfferInfo.fromProto(proto.getBsqSwapOfferInfo()))
|
|
||||||
.withTradeId(proto.getTradeId())
|
|
||||||
.withTempTradingPeerNodeAddress(proto.getTempTradingPeerNodeAddress())
|
|
||||||
.withPeerNodeAddress(proto.getPeerNodeAddress())
|
|
||||||
.withTxId(proto.getTxId())
|
.withTxId(proto.getTxId())
|
||||||
.withBsqTradeAmount(proto.getBsqTradeAmount())
|
.withBsqTradeAmount(proto.getBsqTradeAmount())
|
||||||
.withBsqMaxTradeAmount(proto.getBsqMaxTradeAmount())
|
|
||||||
.withBsqMinTradeAmount(proto.getBsqMinTradeAmount())
|
|
||||||
.withBtcTradeAmount(proto.getBtcTradeAmount())
|
.withBtcTradeAmount(proto.getBtcTradeAmount())
|
||||||
.withBtcMaxTradeAmount(proto.getBtcMaxTradeAmount())
|
|
||||||
.withBtcMinTradeAmount(proto.getBtcMinTradeAmount())
|
|
||||||
.withTradePrice(proto.getTradePrice())
|
|
||||||
.withBsqMakerTradeFee(proto.getBsqMakerTradeFee())
|
.withBsqMakerTradeFee(proto.getBsqMakerTradeFee())
|
||||||
.withBsqTakerTradeFee(proto.getBsqTakerTradeFee())
|
.withBsqTakerTradeFee(proto.getBsqTakerTradeFee())
|
||||||
.withTxFeePerVbyte(proto.getTxFeePerVbyte())
|
.withTxFeePerVbyte(proto.getTxFeePerVbyte())
|
||||||
.withTxFee(proto.getTxFee())
|
|
||||||
.withMakerBsqAddress(proto.getMakerBsqAddress())
|
.withMakerBsqAddress(proto.getMakerBsqAddress())
|
||||||
.withMakerBtcAddress(proto.getMakerBtcAddress())
|
.withMakerBtcAddress(proto.getMakerBtcAddress())
|
||||||
.withTakerBsqAddress(proto.getTakerBsqAddress())
|
.withTakerBsqAddress(proto.getTakerBsqAddress())
|
||||||
.withTakerBtcAddress(proto.getTakerBtcAddress())
|
.withTakerBtcAddress(proto.getTakerBtcAddress())
|
||||||
.withTakeOfferDate(proto.getTakeOfferDate())
|
.withNumConfirmations(proto.getNumConfirmations())
|
||||||
.withState(proto.getState())
|
|
||||||
.withErrorMessage(proto.getErrorMessage())
|
.withErrorMessage(proto.getErrorMessage())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BsqSwapTradeInfoBuilder {
|
@Override
|
||||||
private BsqSwapOfferInfo bsqSwapOfferInfo;
|
public String toString() {
|
||||||
private String tradeId;
|
return "BsqSwapTradeInfo{" +
|
||||||
private String tempTradingPeerNodeAddress;
|
", txId='" + txId + '\'' +
|
||||||
private String peerNodeAddress;
|
", bsqTradeAmount=" + bsqTradeAmount +
|
||||||
private String txId;
|
", btcTradeAmount=" + btcTradeAmount +
|
||||||
private long bsqTradeAmount;
|
", bsqMakerTradeFee=" + bsqMakerTradeFee +
|
||||||
private long bsqMaxTradeAmount;
|
", bsqTakerTradeFee=" + bsqTakerTradeFee +
|
||||||
private long bsqMinTradeAmount;
|
", txFeePerVbyte=" + txFeePerVbyte +
|
||||||
private long btcTradeAmount;
|
", makerBsqAddress='" + makerBsqAddress + '\'' +
|
||||||
private long btcMaxTradeAmount;
|
", makerBtcAddress='" + makerBtcAddress + '\'' +
|
||||||
private long btcMinTradeAmount;
|
", takerBsqAddress='" + takerBsqAddress + '\'' +
|
||||||
private long tradePrice;
|
", takerBtcAddress='" + takerBtcAddress + '\'' +
|
||||||
private long bsqMakerTradeFee;
|
", numConfirmations='" + numConfirmations + '\'' +
|
||||||
private long bsqTakerTradeFee;
|
", errorMessage='" + errorMessage + '\'' +
|
||||||
private long txFeePerVbyte;
|
'}';
|
||||||
private long txFee;
|
|
||||||
private String makerBsqAddress;
|
|
||||||
private String makerBtcAddress;
|
|
||||||
private String takerBsqAddress;
|
|
||||||
private String takerBtcAddress;
|
|
||||||
private long takeOfferDate;
|
|
||||||
private String state;
|
|
||||||
private String errorMessage;
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withBsqSwapOffer(BsqSwapOfferInfo bsqSwapOfferInfo) {
|
|
||||||
this.bsqSwapOfferInfo = bsqSwapOfferInfo;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withTradeId(String tradeId) {
|
|
||||||
this.tradeId = tradeId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withTempTradingPeerNodeAddress(String tempTradingPeerNodeAddress) {
|
|
||||||
this.tempTradingPeerNodeAddress = tempTradingPeerNodeAddress;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withPeerNodeAddress(String peerNodeAddress) {
|
|
||||||
this.peerNodeAddress = peerNodeAddress;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withTxId(String txId) {
|
|
||||||
this.txId = txId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withBsqTradeAmount(long bsqTradeAmount) {
|
|
||||||
this.bsqTradeAmount = bsqTradeAmount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withBsqMaxTradeAmount(long bsqMaxTradeAmount) {
|
|
||||||
this.bsqMaxTradeAmount = bsqMaxTradeAmount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withBsqMinTradeAmount(long bsqMinTradeAmount) {
|
|
||||||
this.bsqMinTradeAmount = bsqMinTradeAmount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withBtcTradeAmount(long btcTradeAmount) {
|
|
||||||
this.btcTradeAmount = btcTradeAmount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withBtcMaxTradeAmount(long btcMaxTradeAmount) {
|
|
||||||
this.btcMaxTradeAmount = btcMaxTradeAmount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withBtcMinTradeAmount(long btcMinTradeAmount) {
|
|
||||||
this.btcMinTradeAmount = btcMinTradeAmount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withTradePrice(long tradePrice) {
|
|
||||||
this.tradePrice = tradePrice;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withBsqMakerTradeFee(long bsqMakerTradeFee) {
|
|
||||||
this.bsqMakerTradeFee = bsqMakerTradeFee;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withBsqTakerTradeFee(long bsqTakerTradeFee) {
|
|
||||||
this.bsqTakerTradeFee = bsqTakerTradeFee;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withTxFeePerVbyte(long txFeePerVbyte) {
|
|
||||||
this.txFeePerVbyte = txFeePerVbyte;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withTxFee(long txFee) {
|
|
||||||
this.txFee = txFee;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withMakerBsqAddress(String makerBsqAddress) {
|
|
||||||
this.makerBsqAddress = makerBsqAddress;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withMakerBtcAddress(String makerBtcAddress) {
|
|
||||||
this.makerBtcAddress = makerBtcAddress;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withTakerBsqAddress(String takerBsqAddress) {
|
|
||||||
this.takerBsqAddress = takerBsqAddress;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withTakerBtcAddress(String takerBtcAddress) {
|
|
||||||
this.takerBtcAddress = takerBtcAddress;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withTakeOfferDate(long takeOfferDate) {
|
|
||||||
this.takeOfferDate = takeOfferDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withState(String state) {
|
|
||||||
this.state = state;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfoBuilder withErrorMessage(String errorMessage) {
|
|
||||||
this.errorMessage = errorMessage;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsqSwapTradeInfo build() {
|
|
||||||
return new BsqSwapTradeInfo(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ public class ContractInfo implements Payload {
|
||||||
|
|
||||||
|
|
||||||
// For transmitting TradeInfo messages when no contract is available.
|
// For transmitting TradeInfo messages when no contract is available.
|
||||||
|
// TODO Is this necessary as protobuf will send a DEFAULT_INSTANCE.
|
||||||
public static Supplier<ContractInfo> emptyContract = () ->
|
public static Supplier<ContractInfo> emptyContract = () ->
|
||||||
new ContractInfo("",
|
new ContractInfo("",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -17,17 +17,19 @@
|
||||||
|
|
||||||
package bisq.core.api.model;
|
package bisq.core.api.model;
|
||||||
|
|
||||||
|
import bisq.core.api.model.builder.OfferInfoBuilder;
|
||||||
import bisq.core.offer.Offer;
|
import bisq.core.offer.Offer;
|
||||||
import bisq.core.offer.OpenOffer;
|
import bisq.core.offer.OpenOffer;
|
||||||
|
import bisq.core.util.coin.CoinUtil;
|
||||||
|
|
||||||
import bisq.common.Payload;
|
import bisq.common.Payload;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
@ToString
|
@ToString
|
||||||
@Getter
|
@Getter
|
||||||
|
@ -56,86 +58,95 @@ public class OfferInfo implements Payload {
|
||||||
private final String paymentAccountId;
|
private final String paymentAccountId;
|
||||||
private final String paymentMethodId;
|
private final String paymentMethodId;
|
||||||
private final String paymentMethodShortName;
|
private final String paymentMethodShortName;
|
||||||
// For fiat offer the baseCurrencyCode is BTC and the counterCurrencyCode is the fiat currency
|
// Fiat offer: baseCurrencyCode = BTC, counterCurrencyCode = fiat ccy code.
|
||||||
// For altcoin offers it is the opposite. baseCurrencyCode is the altcoin and the counterCurrencyCode is BTC.
|
// Altcoin offer: baseCurrencyCode = altcoin ccy code, counterCurrencyCode = BTC.
|
||||||
private final String baseCurrencyCode;
|
private final String baseCurrencyCode;
|
||||||
private final String counterCurrencyCode;
|
private final String counterCurrencyCode;
|
||||||
private final long date;
|
private final long date;
|
||||||
private final String state;
|
private final String state;
|
||||||
private final boolean isActivated;
|
private final boolean isActivated;
|
||||||
private boolean isMyOffer; // Not final -- may be re-set after instantiation.
|
private final boolean isMyOffer;
|
||||||
private final boolean isMyPendingOffer;
|
private final boolean isMyPendingOffer;
|
||||||
|
private final boolean isBsqSwapOffer;
|
||||||
|
private final String ownerNodeAddress;
|
||||||
|
private final String pubKeyRing;
|
||||||
|
private final String versionNumber;
|
||||||
|
private final int protocolVersion;
|
||||||
|
|
||||||
public OfferInfo(OfferInfoBuilder builder) {
|
public OfferInfo(OfferInfoBuilder builder) {
|
||||||
this.id = builder.id;
|
this.id = builder.getId();
|
||||||
this.direction = builder.direction;
|
this.direction = builder.getDirection();
|
||||||
this.price = builder.price;
|
this.price = builder.getPrice();
|
||||||
this.useMarketBasedPrice = builder.useMarketBasedPrice;
|
this.useMarketBasedPrice = builder.isUseMarketBasedPrice();
|
||||||
this.marketPriceMargin = builder.marketPriceMargin;
|
this.marketPriceMargin = builder.getMarketPriceMargin();
|
||||||
this.amount = builder.amount;
|
this.amount = builder.getAmount();
|
||||||
this.minAmount = builder.minAmount;
|
this.minAmount = builder.getMinAmount();
|
||||||
this.volume = builder.volume;
|
this.volume = builder.getVolume();
|
||||||
this.minVolume = builder.minVolume;
|
this.minVolume = builder.getMinVolume();
|
||||||
this.txFee = builder.txFee;
|
this.txFee = builder.getTxFee();
|
||||||
this.makerFee = builder.makerFee;
|
this.makerFee = builder.getMakerFee();
|
||||||
this.offerFeePaymentTxId = builder.offerFeePaymentTxId;
|
this.offerFeePaymentTxId = builder.getOfferFeePaymentTxId();
|
||||||
this.buyerSecurityDeposit = builder.buyerSecurityDeposit;
|
this.buyerSecurityDeposit = builder.getBuyerSecurityDeposit();
|
||||||
this.sellerSecurityDeposit = builder.sellerSecurityDeposit;
|
this.sellerSecurityDeposit = builder.getSellerSecurityDeposit();
|
||||||
this.triggerPrice = builder.triggerPrice;
|
this.triggerPrice = builder.getTriggerPrice();
|
||||||
this.isCurrencyForMakerFeeBtc = builder.isCurrencyForMakerFeeBtc;
|
this.isCurrencyForMakerFeeBtc = builder.isCurrencyForMakerFeeBtc();
|
||||||
this.paymentAccountId = builder.paymentAccountId;
|
this.paymentAccountId = builder.getPaymentAccountId();
|
||||||
this.paymentMethodId = builder.paymentMethodId;
|
this.paymentMethodId = builder.getPaymentMethodId();
|
||||||
this.paymentMethodShortName = builder.paymentMethodShortName;
|
this.paymentMethodShortName = builder.getPaymentMethodShortName();
|
||||||
this.baseCurrencyCode = builder.baseCurrencyCode;
|
this.baseCurrencyCode = builder.getBaseCurrencyCode();
|
||||||
this.counterCurrencyCode = builder.counterCurrencyCode;
|
this.counterCurrencyCode = builder.getCounterCurrencyCode();
|
||||||
this.date = builder.date;
|
this.date = builder.getDate();
|
||||||
this.state = builder.state;
|
this.state = builder.getState();
|
||||||
this.isActivated = builder.isActivated;
|
this.isActivated = builder.isActivated();
|
||||||
this.isMyOffer = builder.isMyOffer;
|
this.isMyOffer = builder.isMyOffer();
|
||||||
this.isMyPendingOffer = builder.isMyPendingOffer;
|
this.isMyPendingOffer = builder.isMyPendingOffer();
|
||||||
|
this.isBsqSwapOffer = builder.isBsqSwapOffer();
|
||||||
|
this.ownerNodeAddress = builder.getOwnerNodeAddress();
|
||||||
|
this.pubKeyRing = builder.getPubKeyRing();
|
||||||
|
this.versionNumber = builder.getVersionNumber();
|
||||||
|
this.protocolVersion = builder.getProtocolVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow isMyOffer to be set on a new offer's OfferInfo instance.
|
public static OfferInfo toMyOfferInfo(Offer offer) {
|
||||||
public void setIsMyOffer(boolean isMyOffer) {
|
return getBuilder(offer, true).build();
|
||||||
this.isMyOffer = isMyOffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OfferInfo toOfferInfo(Offer offer) {
|
public static OfferInfo toOfferInfo(Offer offer) {
|
||||||
// Assume the offer is not mine, but isMyOffer can be reset to true, i.e., when
|
// Assume the offer is not mine, but isMyOffer can be reset to true, i.e., when
|
||||||
// calling TradeInfo toTradeInfo(Trade trade, String role, boolean isMyOffer);
|
// calling TradeInfo toTradeInfo(Trade trade, String role, boolean isMyOffer);
|
||||||
return getOfferInfoBuilder(offer, false).build();
|
return getBuilder(offer, false).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OfferInfo toPendingOfferInfo(Offer myNewOffer) {
|
public static OfferInfo toMyPendingOfferInfo(Offer myNewOffer) {
|
||||||
// Use this to build an OfferInfo instance when a new OpenOffer is being
|
// Use this to build an OfferInfo instance when a new OpenOffer is being
|
||||||
// prepared, and no valid OpenOffer state (AVAILABLE, DEACTIVATED) exists.
|
// prepared, and no valid OpenOffer state (AVAILABLE, DEACTIVATED) exists.
|
||||||
// It is needed for the CLI's 'createoffer' output, which has a boolean 'ENABLED'
|
// It is needed for the CLI's 'createoffer' output, which has a boolean 'ENABLED'
|
||||||
// column that will show a PENDING value when this.isMyPendingOffer = true.
|
// column that will show a PENDING value when this.isMyPendingOffer = true.
|
||||||
return getOfferInfoBuilder(myNewOffer, true)
|
return getBuilder(myNewOffer, true)
|
||||||
.withIsMyPendingOffer(true)
|
.withIsMyPendingOffer(true)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OfferInfo toOfferInfo(OpenOffer openOffer) {
|
public static OfferInfo toMyOfferInfo(OpenOffer openOffer) {
|
||||||
// An OpenOffer is always my offer.
|
// An OpenOffer is always my offer.
|
||||||
return getOfferInfoBuilder(openOffer.getOffer(), true)
|
return getBuilder(openOffer.getOffer(), true)
|
||||||
.withTriggerPrice(openOffer.getTriggerPrice())
|
.withTriggerPrice(openOffer.getTriggerPrice())
|
||||||
.withIsActivated(!openOffer.isDeactivated())
|
.withIsActivated(!openOffer.isDeactivated())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OfferInfoBuilder getOfferInfoBuilder(Offer offer, boolean isMyOffer) {
|
private static OfferInfoBuilder getBuilder(Offer offer, boolean isMyOffer) {
|
||||||
return new OfferInfoBuilder()
|
return new OfferInfoBuilder()
|
||||||
.withId(offer.getId())
|
.withId(offer.getId())
|
||||||
.withDirection(offer.getDirection().name())
|
.withDirection(offer.getDirection().name())
|
||||||
.withPrice(Objects.requireNonNull(offer.getPrice()).getValue())
|
.withPrice(requireNonNull(offer.getPrice()).getValue())
|
||||||
.withUseMarketBasedPrice(offer.isUseMarketBasedPrice())
|
.withUseMarketBasedPrice(offer.isUseMarketBasedPrice())
|
||||||
.withMarketPriceMargin(offer.getMarketPriceMargin())
|
.withMarketPriceMargin(offer.getMarketPriceMargin())
|
||||||
.withAmount(offer.getAmount().value)
|
.withAmount(offer.getAmount().value)
|
||||||
.withMinAmount(offer.getMinAmount().value)
|
.withMinAmount(offer.getMinAmount().value)
|
||||||
.withVolume(Objects.requireNonNull(offer.getVolume()).getValue())
|
.withVolume(requireNonNull(offer.getVolume()).getValue())
|
||||||
.withMinVolume(Objects.requireNonNull(offer.getMinVolume()).getValue())
|
.withMinVolume(requireNonNull(offer.getMinVolume()).getValue())
|
||||||
.withMakerFee(offer.getMakerFee().value)
|
.withMakerFee(getMakerFee(offer, isMyOffer))
|
||||||
.withTxFee(offer.getTxFee().value)
|
.withTxFee(offer.getTxFee().value)
|
||||||
.withOfferFeePaymentTxId(offer.getOfferFeePaymentTxId())
|
.withOfferFeePaymentTxId(offer.getOfferFeePaymentTxId())
|
||||||
.withBuyerSecurityDeposit(offer.getBuyerSecurityDeposit().value)
|
.withBuyerSecurityDeposit(offer.getBuyerSecurityDeposit().value)
|
||||||
|
@ -148,7 +159,18 @@ public class OfferInfo implements Payload {
|
||||||
.withCounterCurrencyCode(offer.getCounterCurrencyCode())
|
.withCounterCurrencyCode(offer.getCounterCurrencyCode())
|
||||||
.withDate(offer.getDate().getTime())
|
.withDate(offer.getDate().getTime())
|
||||||
.withState(offer.getState().name())
|
.withState(offer.getState().name())
|
||||||
.withIsMyOffer(isMyOffer);
|
.withIsMyOffer(isMyOffer)
|
||||||
|
.withIsBsqSwapOffer(offer.isBsqSwapOffer())
|
||||||
|
.withOwnerNodeAddress(offer.getOfferPayloadBase().getOwnerNodeAddress().getFullAddress())
|
||||||
|
.withPubKeyRing(offer.getOfferPayloadBase().getPubKeyRing().toString())
|
||||||
|
.withVersionNumber(offer.getOfferPayloadBase().getVersionNr())
|
||||||
|
.withProtocolVersion(offer.getOfferPayloadBase().getProtocolVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getMakerFee(Offer offer, boolean isMyOffer) {
|
||||||
|
return isMyOffer
|
||||||
|
? requireNonNull(CoinUtil.getMakerFee(false, offer.getAmount())).value
|
||||||
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -169,7 +191,7 @@ public class OfferInfo implements Payload {
|
||||||
.setMinVolume(minVolume)
|
.setMinVolume(minVolume)
|
||||||
.setMakerFee(makerFee)
|
.setMakerFee(makerFee)
|
||||||
.setTxFee(txFee)
|
.setTxFee(txFee)
|
||||||
.setOfferFeePaymentTxId(offerFeePaymentTxId)
|
.setOfferFeePaymentTxId(isBsqSwapOffer ? "" : offerFeePaymentTxId)
|
||||||
.setBuyerSecurityDeposit(buyerSecurityDeposit)
|
.setBuyerSecurityDeposit(buyerSecurityDeposit)
|
||||||
.setSellerSecurityDeposit(sellerSecurityDeposit)
|
.setSellerSecurityDeposit(sellerSecurityDeposit)
|
||||||
.setTriggerPrice(triggerPrice)
|
.setTriggerPrice(triggerPrice)
|
||||||
|
@ -184,6 +206,11 @@ public class OfferInfo implements Payload {
|
||||||
.setIsActivated(isActivated)
|
.setIsActivated(isActivated)
|
||||||
.setIsMyOffer(isMyOffer)
|
.setIsMyOffer(isMyOffer)
|
||||||
.setIsMyPendingOffer(isMyPendingOffer)
|
.setIsMyPendingOffer(isMyPendingOffer)
|
||||||
|
.setIsBsqSwapOffer(isBsqSwapOffer)
|
||||||
|
.setOwnerNodeAddress(ownerNodeAddress)
|
||||||
|
.setPubKeyRing(pubKeyRing)
|
||||||
|
.setVersionNr(versionNumber)
|
||||||
|
.setProtocolVersion(protocolVersion)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,175 +243,11 @@ public class OfferInfo implements Payload {
|
||||||
.withIsActivated(proto.getIsActivated())
|
.withIsActivated(proto.getIsActivated())
|
||||||
.withIsMyOffer(proto.getIsMyOffer())
|
.withIsMyOffer(proto.getIsMyOffer())
|
||||||
.withIsMyPendingOffer(proto.getIsMyPendingOffer())
|
.withIsMyPendingOffer(proto.getIsMyPendingOffer())
|
||||||
|
.withIsBsqSwapOffer(proto.getIsBsqSwapOffer())
|
||||||
|
.withOwnerNodeAddress(proto.getOwnerNodeAddress())
|
||||||
|
.withPubKeyRing(proto.getPubKeyRing())
|
||||||
|
.withVersionNumber(proto.getVersionNr())
|
||||||
|
.withProtocolVersion(proto.getProtocolVersion())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* OfferInfoBuilder helps avoid bungling use of a large OfferInfo constructor
|
|
||||||
* argument list. If consecutive argument values of the same type are not
|
|
||||||
* ordered correctly, the compiler won't complain but the resulting bugs could
|
|
||||||
* be hard to find and fix.
|
|
||||||
*/
|
|
||||||
public static class OfferInfoBuilder {
|
|
||||||
private String id;
|
|
||||||
private String direction;
|
|
||||||
private long price;
|
|
||||||
private boolean useMarketBasedPrice;
|
|
||||||
private double marketPriceMargin;
|
|
||||||
private long amount;
|
|
||||||
private long minAmount;
|
|
||||||
private long volume;
|
|
||||||
private long minVolume;
|
|
||||||
private long txFee;
|
|
||||||
private long makerFee;
|
|
||||||
private String offerFeePaymentTxId;
|
|
||||||
private long buyerSecurityDeposit;
|
|
||||||
private long sellerSecurityDeposit;
|
|
||||||
private long triggerPrice;
|
|
||||||
private boolean isCurrencyForMakerFeeBtc;
|
|
||||||
private String paymentAccountId;
|
|
||||||
private String paymentMethodId;
|
|
||||||
private String paymentMethodShortName;
|
|
||||||
private String baseCurrencyCode;
|
|
||||||
private String counterCurrencyCode;
|
|
||||||
private long date;
|
|
||||||
private String state;
|
|
||||||
private boolean isActivated;
|
|
||||||
private boolean isMyOffer;
|
|
||||||
private boolean isMyPendingOffer;
|
|
||||||
|
|
||||||
public OfferInfoBuilder withId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withDirection(String direction) {
|
|
||||||
this.direction = direction;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withPrice(long price) {
|
|
||||||
this.price = price;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withUseMarketBasedPrice(boolean useMarketBasedPrice) {
|
|
||||||
this.useMarketBasedPrice = useMarketBasedPrice;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withMarketPriceMargin(double useMarketBasedPrice) {
|
|
||||||
this.marketPriceMargin = useMarketBasedPrice;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withAmount(long amount) {
|
|
||||||
this.amount = amount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withMinAmount(long minAmount) {
|
|
||||||
this.minAmount = minAmount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withVolume(long volume) {
|
|
||||||
this.volume = volume;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withMinVolume(long minVolume) {
|
|
||||||
this.minVolume = minVolume;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withTxFee(long txFee) {
|
|
||||||
this.txFee = txFee;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withMakerFee(long makerFee) {
|
|
||||||
this.makerFee = makerFee;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withOfferFeePaymentTxId(String offerFeePaymentTxId) {
|
|
||||||
this.offerFeePaymentTxId = offerFeePaymentTxId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withBuyerSecurityDeposit(long buyerSecurityDeposit) {
|
|
||||||
this.buyerSecurityDeposit = buyerSecurityDeposit;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withSellerSecurityDeposit(long sellerSecurityDeposit) {
|
|
||||||
this.sellerSecurityDeposit = sellerSecurityDeposit;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withTriggerPrice(long triggerPrice) {
|
|
||||||
this.triggerPrice = triggerPrice;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withIsCurrencyForMakerFeeBtc(boolean isCurrencyForMakerFeeBtc) {
|
|
||||||
this.isCurrencyForMakerFeeBtc = isCurrencyForMakerFeeBtc;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withPaymentAccountId(String paymentAccountId) {
|
|
||||||
this.paymentAccountId = paymentAccountId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withPaymentMethodId(String paymentMethodId) {
|
|
||||||
this.paymentMethodId = paymentMethodId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withPaymentMethodShortName(String paymentMethodShortName) {
|
|
||||||
this.paymentMethodShortName = paymentMethodShortName;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withBaseCurrencyCode(String baseCurrencyCode) {
|
|
||||||
this.baseCurrencyCode = baseCurrencyCode;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withCounterCurrencyCode(String counterCurrencyCode) {
|
|
||||||
this.counterCurrencyCode = counterCurrencyCode;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withDate(long date) {
|
|
||||||
this.date = date;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withState(String state) {
|
|
||||||
this.state = state;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withIsActivated(boolean isActivated) {
|
|
||||||
this.isActivated = isActivated;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withIsMyOffer(boolean isMyOffer) {
|
|
||||||
this.isMyOffer = isMyOffer;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfoBuilder withIsMyPendingOffer(boolean isMyPendingOffer) {
|
|
||||||
this.isMyPendingOffer = isMyPendingOffer;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfferInfo build() {
|
|
||||||
return new OfferInfo(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,18 +17,22 @@
|
||||||
|
|
||||||
package bisq.core.api.model;
|
package bisq.core.api.model;
|
||||||
|
|
||||||
|
import bisq.core.api.model.builder.TradeInfoV1Builder;
|
||||||
|
import bisq.core.trade.model.TradeModel;
|
||||||
import bisq.core.trade.model.bisq_v1.Contract;
|
import bisq.core.trade.model.bisq_v1.Contract;
|
||||||
import bisq.core.trade.model.bisq_v1.Trade;
|
import bisq.core.trade.model.bisq_v1.Trade;
|
||||||
|
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
|
||||||
|
|
||||||
import bisq.common.Payload;
|
import bisq.common.Payload;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import static bisq.core.api.model.BsqSwapTradeInfo.toBsqSwapTradeInfo;
|
||||||
|
import static bisq.core.api.model.OfferInfo.toMyOfferInfo;
|
||||||
import static bisq.core.api.model.OfferInfo.toOfferInfo;
|
import static bisq.core.api.model.OfferInfo.toOfferInfo;
|
||||||
import static bisq.core.api.model.PaymentAccountPayloadInfo.toPaymentAccountPayloadInfo;
|
import static bisq.core.api.model.PaymentAccountPayloadInfo.toPaymentAccountPayloadInfo;
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
@Getter
|
@Getter
|
||||||
|
@ -38,6 +42,7 @@ public class TradeInfo implements Payload {
|
||||||
// lighter weight TradeInfo proto wrapper instead, containing just enough fields to
|
// lighter weight TradeInfo proto wrapper instead, containing just enough fields to
|
||||||
// view and interact with trades.
|
// view and interact with trades.
|
||||||
|
|
||||||
|
// Bisq v1 trade protocol fields (some are in common with the BSQ Swap protocol).
|
||||||
private final OfferInfo offer;
|
private final OfferInfo offer;
|
||||||
private final String tradeId;
|
private final String tradeId;
|
||||||
private final String shortId;
|
private final String shortId;
|
||||||
|
@ -64,41 +69,88 @@ public class TradeInfo implements Payload {
|
||||||
private final boolean isWithdrawn;
|
private final boolean isWithdrawn;
|
||||||
private final String contractAsJson;
|
private final String contractAsJson;
|
||||||
private final ContractInfo contract;
|
private final ContractInfo contract;
|
||||||
|
// Optional BSQ swap trade protocol details (post v1).
|
||||||
|
private BsqSwapTradeInfo bsqSwapTradeInfo;
|
||||||
|
|
||||||
public TradeInfo(TradeInfoBuilder builder) {
|
public TradeInfo(TradeInfoV1Builder builder) {
|
||||||
this.offer = builder.offer;
|
this.offer = builder.getOffer();
|
||||||
this.tradeId = builder.tradeId;
|
this.tradeId = builder.getTradeId();
|
||||||
this.shortId = builder.shortId;
|
this.shortId = builder.getShortId();
|
||||||
this.date = builder.date;
|
this.date = builder.getDate();
|
||||||
this.role = builder.role;
|
this.role = builder.getRole();
|
||||||
this.isCurrencyForTakerFeeBtc = builder.isCurrencyForTakerFeeBtc;
|
this.isCurrencyForTakerFeeBtc = builder.isCurrencyForTakerFeeBtc();
|
||||||
this.txFeeAsLong = builder.txFeeAsLong;
|
this.txFeeAsLong = builder.getTxFeeAsLong();
|
||||||
this.takerFeeAsLong = builder.takerFeeAsLong;
|
this.takerFeeAsLong = builder.getTakerFeeAsLong();
|
||||||
this.takerFeeTxId = builder.takerFeeTxId;
|
this.takerFeeTxId = builder.getTakerFeeTxId();
|
||||||
this.depositTxId = builder.depositTxId;
|
this.depositTxId = builder.getDepositTxId();
|
||||||
this.payoutTxId = builder.payoutTxId;
|
this.payoutTxId = builder.getPayoutTxId();
|
||||||
this.tradeAmountAsLong = builder.tradeAmountAsLong;
|
this.tradeAmountAsLong = builder.getTradeAmountAsLong();
|
||||||
this.tradePrice = builder.tradePrice;
|
this.tradePrice = builder.getTradePrice();
|
||||||
this.tradeVolume = builder.tradeVolume;
|
this.tradeVolume = builder.getTradeVolume();
|
||||||
this.tradingPeerNodeAddress = builder.tradingPeerNodeAddress;
|
this.tradingPeerNodeAddress = builder.getTradingPeerNodeAddress();
|
||||||
this.state = builder.state;
|
this.state = builder.getState();
|
||||||
this.phase = builder.phase;
|
this.phase = builder.getPhase();
|
||||||
this.tradePeriodState = builder.tradePeriodState;
|
this.tradePeriodState = builder.getTradePeriodState();
|
||||||
this.isDepositPublished = builder.isDepositPublished;
|
this.isDepositPublished = builder.isDepositPublished();
|
||||||
this.isDepositConfirmed = builder.isDepositConfirmed;
|
this.isDepositConfirmed = builder.isDepositConfirmed();
|
||||||
this.isFiatSent = builder.isFiatSent;
|
this.isFiatSent = builder.isFiatSent();
|
||||||
this.isFiatReceived = builder.isFiatReceived;
|
this.isFiatReceived = builder.isFiatReceived();
|
||||||
this.isPayoutPublished = builder.isPayoutPublished;
|
this.isPayoutPublished = builder.isPayoutPublished();
|
||||||
this.isWithdrawn = builder.isWithdrawn;
|
this.isWithdrawn = builder.isWithdrawn();
|
||||||
this.contractAsJson = builder.contractAsJson;
|
this.contractAsJson = builder.getContractAsJson();
|
||||||
this.contract = builder.contract;
|
this.contract = builder.getContract();
|
||||||
|
this.bsqSwapTradeInfo = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TradeInfo toNewTradeInfo(BsqSwapTrade trade, String role) {
|
||||||
|
// Always called by the taker, isMyOffer=false.
|
||||||
|
return toTradeInfo(trade, role, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TradeInfo toNewTradeInfo(Trade trade) {
|
public static TradeInfo toNewTradeInfo(Trade trade) {
|
||||||
|
// Always called by the taker, isMyOffer=false.
|
||||||
return toTradeInfo(trade, null, false);
|
return toTradeInfo(trade, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TradeInfo toTradeInfo(Trade trade, String role, boolean isMyOffer) {
|
public static TradeInfo toTradeInfo(TradeModel tradeModel, String role, boolean isMyOffer) {
|
||||||
|
if (tradeModel instanceof Trade)
|
||||||
|
return toTradeInfo((Trade) tradeModel, role, isMyOffer);
|
||||||
|
else if (tradeModel instanceof BsqSwapTrade)
|
||||||
|
return toTradeInfo(tradeModel, role, isMyOffer);
|
||||||
|
else
|
||||||
|
throw new IllegalStateException("unsupported trade type: " + tradeModel.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TradeInfo toTradeInfo(BsqSwapTrade bsqSwapTrade,
|
||||||
|
String role,
|
||||||
|
boolean isMyOffer,
|
||||||
|
int numConfirmations) {
|
||||||
|
OfferInfo offerInfo = isMyOffer ? toMyOfferInfo(bsqSwapTrade.getOffer()) : toOfferInfo(bsqSwapTrade.getOffer());
|
||||||
|
TradeInfo tradeInfo = new TradeInfoV1Builder()
|
||||||
|
.withOffer(offerInfo)
|
||||||
|
.withTradeId(bsqSwapTrade.getId())
|
||||||
|
.withShortId(bsqSwapTrade.getShortId())
|
||||||
|
.withDate(bsqSwapTrade.getDate().getTime())
|
||||||
|
.withRole(role == null ? "" : role)
|
||||||
|
.withIsCurrencyForTakerFeeBtc(false) // BSQ Swap fees always paid in BSQ.
|
||||||
|
.withTxFeeAsLong(bsqSwapTrade.getTxFee().value)
|
||||||
|
.withTakerFeeAsLong(bsqSwapTrade.getTakerFeeAsLong())
|
||||||
|
// N/A: .withTakerFeeTxId(""), .withDepositTxId(""), .withPayoutTxId("")
|
||||||
|
.withTradeAmountAsLong(bsqSwapTrade.getAmountAsLong())
|
||||||
|
.withTradePrice(bsqSwapTrade.getPrice().getValue())
|
||||||
|
.withTradeVolume(bsqSwapTrade.getVolume() == null ? 0 : bsqSwapTrade.getVolume().getValue())
|
||||||
|
.withTradingPeerNodeAddress(requireNonNull(bsqSwapTrade.getTradingPeerNodeAddress().getFullAddress()))
|
||||||
|
.withState(bsqSwapTrade.getTradeState().name())
|
||||||
|
.withPhase(bsqSwapTrade.getTradePhase().name())
|
||||||
|
// N/A: .withTradePeriodState(""), .withIsDepositPublished(false), .withIsDepositConfirmed(false)
|
||||||
|
// N/A: .withIsFiatSent(false), .withIsFiatReceived(false), .withIsPayoutPublished(false)
|
||||||
|
// N/A: .withIsWithdrawn(false), .withContractAsJson(""), .withContract(null)
|
||||||
|
.build();
|
||||||
|
tradeInfo.bsqSwapTradeInfo = toBsqSwapTradeInfo(bsqSwapTrade, isMyOffer, numConfirmations);
|
||||||
|
return tradeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TradeInfo toTradeInfo(Trade trade, String role, boolean isMyOffer) {
|
||||||
ContractInfo contractInfo;
|
ContractInfo contractInfo;
|
||||||
if (trade.getContract() != null) {
|
if (trade.getContract() != null) {
|
||||||
Contract contract = trade.getContract();
|
Contract contract = trade.getContract();
|
||||||
|
@ -118,9 +170,8 @@ public class TradeInfo implements Payload {
|
||||||
contractInfo = ContractInfo.emptyContract.get();
|
contractInfo = ContractInfo.emptyContract.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
OfferInfo offerInfo = toOfferInfo(trade.getOffer());
|
OfferInfo offerInfo = isMyOffer ? toMyOfferInfo(trade.getOffer()) : toOfferInfo(trade.getOffer());
|
||||||
offerInfo.setIsMyOffer(isMyOffer);
|
return new TradeInfoV1Builder()
|
||||||
return new TradeInfoBuilder()
|
|
||||||
.withOffer(offerInfo)
|
.withOffer(offerInfo)
|
||||||
.withTradeId(trade.getId())
|
.withTradeId(trade.getId())
|
||||||
.withShortId(trade.getShortId())
|
.withShortId(trade.getShortId())
|
||||||
|
@ -129,15 +180,13 @@ public class TradeInfo implements Payload {
|
||||||
.withIsCurrencyForTakerFeeBtc(trade.isCurrencyForTakerFeeBtc())
|
.withIsCurrencyForTakerFeeBtc(trade.isCurrencyForTakerFeeBtc())
|
||||||
.withTxFeeAsLong(trade.getTradeTxFeeAsLong())
|
.withTxFeeAsLong(trade.getTradeTxFeeAsLong())
|
||||||
.withTakerFeeAsLong(trade.getTakerFeeAsLong())
|
.withTakerFeeAsLong(trade.getTakerFeeAsLong())
|
||||||
.withTakerFeeAsLong(trade.getTakerFeeAsLong())
|
|
||||||
.withTakerFeeTxId(trade.getTakerFeeTxId())
|
.withTakerFeeTxId(trade.getTakerFeeTxId())
|
||||||
.withDepositTxId(trade.getDepositTxId())
|
.withDepositTxId(trade.getDepositTxId())
|
||||||
.withPayoutTxId(trade.getPayoutTxId())
|
.withPayoutTxId(trade.getPayoutTxId())
|
||||||
.withTradeAmountAsLong(trade.getAmountAsLong())
|
.withTradeAmountAsLong(trade.getAmountAsLong())
|
||||||
.withTradePrice(trade.getPrice().getValue())
|
.withTradePrice(trade.getPrice().getValue())
|
||||||
.withTradeVolume(trade.getVolume() == null ? 0 : trade.getVolume().getValue())
|
.withTradeVolume(trade.getVolume() == null ? 0 : trade.getVolume().getValue())
|
||||||
.withTradingPeerNodeAddress(Objects.requireNonNull(
|
.withTradingPeerNodeAddress(requireNonNull(trade.getTradingPeerNodeAddress().getFullAddress()))
|
||||||
trade.getTradingPeerNodeAddress()).getHostNameWithoutPostFix())
|
|
||||||
.withState(trade.getTradeState().name())
|
.withState(trade.getTradeState().name())
|
||||||
.withPhase(trade.getTradePhase().name())
|
.withPhase(trade.getTradePhase().name())
|
||||||
.withTradePeriodState(trade.getTradePeriodState().name())
|
.withTradePeriodState(trade.getTradePeriodState().name())
|
||||||
|
@ -158,38 +207,45 @@ public class TradeInfo implements Payload {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public bisq.proto.grpc.TradeInfo toProtoMessage() {
|
public bisq.proto.grpc.TradeInfo toProtoMessage() {
|
||||||
return bisq.proto.grpc.TradeInfo.newBuilder()
|
var protoBuilder =
|
||||||
.setOffer(offer.toProtoMessage())
|
bisq.proto.grpc.TradeInfo.newBuilder()
|
||||||
.setTradeId(tradeId)
|
.setOffer(offer.toProtoMessage())
|
||||||
.setShortId(shortId)
|
.setTradeId(tradeId)
|
||||||
.setDate(date)
|
.setShortId(shortId)
|
||||||
.setRole(role)
|
.setDate(date)
|
||||||
.setIsCurrencyForTakerFeeBtc(isCurrencyForTakerFeeBtc)
|
.setRole(role)
|
||||||
.setTxFeeAsLong(txFeeAsLong)
|
.setIsCurrencyForTakerFeeBtc(isCurrencyForTakerFeeBtc)
|
||||||
.setTakerFeeAsLong(takerFeeAsLong)
|
.setTxFeeAsLong(txFeeAsLong)
|
||||||
.setTakerFeeTxId(takerFeeTxId == null ? "" : takerFeeTxId)
|
.setTakerFeeAsLong(takerFeeAsLong)
|
||||||
.setDepositTxId(depositTxId == null ? "" : depositTxId)
|
.setTakerFeeTxId(takerFeeTxId == null ? "" : takerFeeTxId)
|
||||||
.setPayoutTxId(payoutTxId == null ? "" : payoutTxId)
|
.setDepositTxId(depositTxId == null ? "" : depositTxId)
|
||||||
.setTradeAmountAsLong(tradeAmountAsLong)
|
.setPayoutTxId(payoutTxId == null ? "" : payoutTxId)
|
||||||
.setTradePrice(tradePrice)
|
.setTradeAmountAsLong(tradeAmountAsLong)
|
||||||
.setTradeVolume(tradeVolume)
|
.setTradePrice(tradePrice)
|
||||||
.setTradingPeerNodeAddress(tradingPeerNodeAddress)
|
.setTradeVolume(tradeVolume)
|
||||||
.setState(state)
|
.setTradingPeerNodeAddress(tradingPeerNodeAddress)
|
||||||
.setPhase(phase)
|
.setState(state == null ? "" : state)
|
||||||
.setTradePeriodState(tradePeriodState)
|
.setPhase(phase == null ? "" : phase)
|
||||||
.setIsDepositPublished(isDepositPublished)
|
.setTradePeriodState(tradePeriodState == null ? "" : tradePeriodState)
|
||||||
.setIsDepositConfirmed(isDepositConfirmed)
|
.setIsDepositPublished(isDepositPublished)
|
||||||
.setIsFiatSent(isFiatSent)
|
.setIsDepositConfirmed(isDepositConfirmed)
|
||||||
.setIsFiatReceived(isFiatReceived)
|
.setIsFiatSent(isFiatSent)
|
||||||
.setIsPayoutPublished(isPayoutPublished)
|
.setIsFiatReceived(isFiatReceived)
|
||||||
.setIsWithdrawn(isWithdrawn)
|
.setIsPayoutPublished(isPayoutPublished)
|
||||||
.setContractAsJson(contractAsJson == null ? "" : contractAsJson)
|
.setIsWithdrawn(isWithdrawn);
|
||||||
.setContract(contract.toProtoMessage())
|
|
||||||
.build();
|
if (offer.isBsqSwapOffer()) {
|
||||||
|
protoBuilder.setBsqSwapTradeInfo(bsqSwapTradeInfo.toProtoMessage());
|
||||||
|
} else {
|
||||||
|
protoBuilder.setContractAsJson(contractAsJson == null ? "" : contractAsJson);
|
||||||
|
protoBuilder.setContract(contract.toProtoMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return protoBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TradeInfo fromProto(bisq.proto.grpc.TradeInfo proto) {
|
public static TradeInfo fromProto(bisq.proto.grpc.TradeInfo proto) {
|
||||||
return new TradeInfoBuilder()
|
var tradeInfo = new TradeInfoV1Builder()
|
||||||
.withOffer(OfferInfo.fromProto(proto.getOffer()))
|
.withOffer(OfferInfo.fromProto(proto.getOffer()))
|
||||||
.withTradeId(proto.getTradeId())
|
.withTradeId(proto.getTradeId())
|
||||||
.withShortId(proto.getShortId())
|
.withShortId(proto.getShortId())
|
||||||
|
@ -217,175 +273,11 @@ public class TradeInfo implements Payload {
|
||||||
.withContractAsJson(proto.getContractAsJson())
|
.withContractAsJson(proto.getContractAsJson())
|
||||||
.withContract((ContractInfo.fromProto(proto.getContract())))
|
.withContract((ContractInfo.fromProto(proto.getContract())))
|
||||||
.build();
|
.build();
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if (proto.getOffer().getIsBsqSwapOffer())
|
||||||
* TradeInfoBuilder helps avoid bungling use of a large TradeInfo constructor
|
tradeInfo.bsqSwapTradeInfo = BsqSwapTradeInfo.fromProto(proto.getBsqSwapTradeInfo());
|
||||||
* argument list. If consecutive argument values of the same type are not
|
|
||||||
* ordered correctly, the compiler won't complain but the resulting bugs could
|
|
||||||
* be hard to find and fix.
|
|
||||||
*/
|
|
||||||
public static class TradeInfoBuilder {
|
|
||||||
private OfferInfo offer;
|
|
||||||
private String tradeId;
|
|
||||||
private String shortId;
|
|
||||||
private long date;
|
|
||||||
private String role;
|
|
||||||
private boolean isCurrencyForTakerFeeBtc;
|
|
||||||
private long txFeeAsLong;
|
|
||||||
private long takerFeeAsLong;
|
|
||||||
private String takerFeeTxId;
|
|
||||||
private String depositTxId;
|
|
||||||
private String payoutTxId;
|
|
||||||
private long tradeAmountAsLong;
|
|
||||||
private long tradePrice;
|
|
||||||
private long tradeVolume;
|
|
||||||
private String tradingPeerNodeAddress;
|
|
||||||
private String state;
|
|
||||||
private String phase;
|
|
||||||
private String tradePeriodState;
|
|
||||||
private boolean isDepositPublished;
|
|
||||||
private boolean isDepositConfirmed;
|
|
||||||
private boolean isFiatSent;
|
|
||||||
private boolean isFiatReceived;
|
|
||||||
private boolean isPayoutPublished;
|
|
||||||
private boolean isWithdrawn;
|
|
||||||
private String contractAsJson;
|
|
||||||
private ContractInfo contract;
|
|
||||||
|
|
||||||
public TradeInfoBuilder withOffer(OfferInfo offer) {
|
return tradeInfo;
|
||||||
this.offer = offer;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withTradeId(String tradeId) {
|
|
||||||
this.tradeId = tradeId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withShortId(String shortId) {
|
|
||||||
this.shortId = shortId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withDate(long date) {
|
|
||||||
this.date = date;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withRole(String role) {
|
|
||||||
this.role = role;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withIsCurrencyForTakerFeeBtc(boolean isCurrencyForTakerFeeBtc) {
|
|
||||||
this.isCurrencyForTakerFeeBtc = isCurrencyForTakerFeeBtc;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withTxFeeAsLong(long txFeeAsLong) {
|
|
||||||
this.txFeeAsLong = txFeeAsLong;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withTakerFeeAsLong(long takerFeeAsLong) {
|
|
||||||
this.takerFeeAsLong = takerFeeAsLong;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withTakerFeeTxId(String takerFeeTxId) {
|
|
||||||
this.takerFeeTxId = takerFeeTxId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withDepositTxId(String depositTxId) {
|
|
||||||
this.depositTxId = depositTxId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withPayoutTxId(String payoutTxId) {
|
|
||||||
this.payoutTxId = payoutTxId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withTradeAmountAsLong(long tradeAmountAsLong) {
|
|
||||||
this.tradeAmountAsLong = tradeAmountAsLong;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withTradePrice(long tradePrice) {
|
|
||||||
this.tradePrice = tradePrice;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withTradeVolume(long tradeVolume) {
|
|
||||||
this.tradeVolume = tradeVolume;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withTradePeriodState(String tradePeriodState) {
|
|
||||||
this.tradePeriodState = tradePeriodState;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withState(String state) {
|
|
||||||
this.state = state;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withPhase(String phase) {
|
|
||||||
this.phase = phase;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withTradingPeerNodeAddress(String tradingPeerNodeAddress) {
|
|
||||||
this.tradingPeerNodeAddress = tradingPeerNodeAddress;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withIsDepositPublished(boolean isDepositPublished) {
|
|
||||||
this.isDepositPublished = isDepositPublished;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withIsDepositConfirmed(boolean isDepositConfirmed) {
|
|
||||||
this.isDepositConfirmed = isDepositConfirmed;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withIsFiatSent(boolean isFiatSent) {
|
|
||||||
this.isFiatSent = isFiatSent;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withIsFiatReceived(boolean isFiatReceived) {
|
|
||||||
this.isFiatReceived = isFiatReceived;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withIsPayoutPublished(boolean isPayoutPublished) {
|
|
||||||
this.isPayoutPublished = isPayoutPublished;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withIsWithdrawn(boolean isWithdrawn) {
|
|
||||||
this.isWithdrawn = isWithdrawn;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withContractAsJson(String contractAsJson) {
|
|
||||||
this.contractAsJson = contractAsJson;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfoBuilder withContract(ContractInfo contract) {
|
|
||||||
this.contract = contract;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TradeInfo build() {
|
|
||||||
return new TradeInfo(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -417,6 +309,7 @@ public class TradeInfo implements Payload {
|
||||||
", offer=" + offer + "\n" +
|
", offer=" + offer + "\n" +
|
||||||
", contractAsJson=" + contractAsJson + "\n" +
|
", contractAsJson=" + contractAsJson + "\n" +
|
||||||
", contract=" + contract + "\n" +
|
", contract=" + contract + "\n" +
|
||||||
|
", bsqSwapTradeInfo=" + bsqSwapTradeInfo + "\n" +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class TxInfo implements Payload {
|
||||||
private final boolean isPending;
|
private final boolean isPending;
|
||||||
private final String memo;
|
private final String memo;
|
||||||
|
|
||||||
public TxInfo(TxInfoBuilder builder) {
|
public TxInfo(Builder builder) {
|
||||||
this.txId = builder.txId;
|
this.txId = builder.txId;
|
||||||
this.inputSum = builder.inputSum;
|
this.inputSum = builder.inputSum;
|
||||||
this.outputSum = builder.outputSum;
|
this.outputSum = builder.outputSum;
|
||||||
|
@ -61,7 +61,7 @@ public class TxInfo implements Payload {
|
||||||
throw new IllegalStateException("server created a null transaction");
|
throw new IllegalStateException("server created a null transaction");
|
||||||
|
|
||||||
if (transaction.getFee() != null)
|
if (transaction.getFee() != null)
|
||||||
return new TxInfoBuilder()
|
return new Builder()
|
||||||
.withTxId(transaction.getTxId().toString())
|
.withTxId(transaction.getTxId().toString())
|
||||||
.withInputSum(transaction.getInputSum().value)
|
.withInputSum(transaction.getInputSum().value)
|
||||||
.withOutputSum(transaction.getOutputSum().value)
|
.withOutputSum(transaction.getOutputSum().value)
|
||||||
|
@ -71,7 +71,7 @@ public class TxInfo implements Payload {
|
||||||
.withMemo(transaction.getMemo())
|
.withMemo(transaction.getMemo())
|
||||||
.build();
|
.build();
|
||||||
else
|
else
|
||||||
return new TxInfoBuilder()
|
return new Builder()
|
||||||
.withTxId(transaction.getTxId().toString())
|
.withTxId(transaction.getTxId().toString())
|
||||||
.withInputSum(transaction.getInputSum().value)
|
.withInputSum(transaction.getInputSum().value)
|
||||||
.withOutputSum(transaction.getOutputSum().value)
|
.withOutputSum(transaction.getOutputSum().value)
|
||||||
|
@ -101,7 +101,7 @@ public class TxInfo implements Payload {
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static TxInfo fromProto(bisq.proto.grpc.TxInfo proto) {
|
public static TxInfo fromProto(bisq.proto.grpc.TxInfo proto) {
|
||||||
return new TxInfoBuilder()
|
return new Builder()
|
||||||
.withTxId(proto.getTxId())
|
.withTxId(proto.getTxId())
|
||||||
.withInputSum(proto.getInputSum())
|
.withInputSum(proto.getInputSum())
|
||||||
.withOutputSum(proto.getOutputSum())
|
.withOutputSum(proto.getOutputSum())
|
||||||
|
@ -112,7 +112,7 @@ public class TxInfo implements Payload {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TxInfoBuilder {
|
private static class Builder {
|
||||||
private String txId;
|
private String txId;
|
||||||
private long inputSum;
|
private long inputSum;
|
||||||
private long outputSum;
|
private long outputSum;
|
||||||
|
@ -121,37 +121,37 @@ public class TxInfo implements Payload {
|
||||||
private boolean isPending;
|
private boolean isPending;
|
||||||
private String memo;
|
private String memo;
|
||||||
|
|
||||||
public TxInfoBuilder withTxId(String txId) {
|
public Builder withTxId(String txId) {
|
||||||
this.txId = txId;
|
this.txId = txId;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TxInfoBuilder withInputSum(long inputSum) {
|
public Builder withInputSum(long inputSum) {
|
||||||
this.inputSum = inputSum;
|
this.inputSum = inputSum;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TxInfoBuilder withOutputSum(long outputSum) {
|
public Builder withOutputSum(long outputSum) {
|
||||||
this.outputSum = outputSum;
|
this.outputSum = outputSum;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TxInfoBuilder withFee(long fee) {
|
public Builder withFee(long fee) {
|
||||||
this.fee = fee;
|
this.fee = fee;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TxInfoBuilder withSize(int size) {
|
public Builder withSize(int size) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TxInfoBuilder withIsPending(boolean isPending) {
|
public Builder withIsPending(boolean isPending) {
|
||||||
this.isPending = isPending;
|
this.isPending = isPending;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TxInfoBuilder withMemo(String memo) {
|
public Builder withMemo(String memo) {
|
||||||
this.memo = memo;
|
this.memo = memo;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* 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.core.api.model.builder;
|
||||||
|
|
||||||
|
import bisq.core.api.model.BsqSwapTradeInfo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proto wrapper for BSQ swap protocol details not common to Bisq v1
|
||||||
|
* trade protocol details.
|
||||||
|
*
|
||||||
|
* This builder helps avoid bungling use of a large BsqSwapTradeInfo constructor
|
||||||
|
* argument list. If consecutive argument values of the same type are not
|
||||||
|
* ordered correctly, the compiler won't complain but the resulting bugs could
|
||||||
|
* be hard to find and fix.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public final class BsqSwapTradeInfoBuilder {
|
||||||
|
|
||||||
|
private String txId;
|
||||||
|
private long bsqTradeAmount;
|
||||||
|
private long btcTradeAmount;
|
||||||
|
private long bsqMakerTradeFee;
|
||||||
|
private long bsqTakerTradeFee;
|
||||||
|
private long txFeePerVbyte;
|
||||||
|
private String makerBsqAddress;
|
||||||
|
private String makerBtcAddress;
|
||||||
|
private String takerBsqAddress;
|
||||||
|
private String takerBtcAddress;
|
||||||
|
private long numConfirmations;
|
||||||
|
private String errorMessage;
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withTxId(String txId) {
|
||||||
|
this.txId = txId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withBsqTradeAmount(long bsqTradeAmount) {
|
||||||
|
this.bsqTradeAmount = bsqTradeAmount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withBtcTradeAmount(long btcTradeAmount) {
|
||||||
|
this.btcTradeAmount = btcTradeAmount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withBsqMakerTradeFee(long bsqMakerTradeFee) {
|
||||||
|
this.bsqMakerTradeFee = bsqMakerTradeFee;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withBsqTakerTradeFee(long bsqTakerTradeFee) {
|
||||||
|
this.bsqTakerTradeFee = bsqTakerTradeFee;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withTxFeePerVbyte(long txFeePerVbyte) {
|
||||||
|
this.txFeePerVbyte = txFeePerVbyte;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withMakerBsqAddress(String makerBsqAddress) {
|
||||||
|
this.makerBsqAddress = makerBsqAddress;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withMakerBtcAddress(String makerBtcAddress) {
|
||||||
|
this.makerBtcAddress = makerBtcAddress;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withTakerBsqAddress(String takerBsqAddress) {
|
||||||
|
this.takerBsqAddress = takerBsqAddress;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withTakerBtcAddress(String takerBtcAddress) {
|
||||||
|
this.takerBtcAddress = takerBtcAddress;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withNumConfirmations(long numConfirmations) {
|
||||||
|
this.numConfirmations = numConfirmations;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfoBuilder withErrorMessage(String errorMessage) {
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsqSwapTradeInfo build() {
|
||||||
|
return new BsqSwapTradeInfo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,223 @@
|
||||||
|
/*
|
||||||
|
* 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.core.api.model.builder;
|
||||||
|
|
||||||
|
import bisq.core.api.model.OfferInfo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A builder helps avoid bungling use of a large OfferInfo constructor
|
||||||
|
* argument list. If consecutive argument values of the same type are not
|
||||||
|
* ordered correctly, the compiler won't complain but the resulting bugs could
|
||||||
|
* be hard to find and fix.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public final class OfferInfoBuilder {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String direction;
|
||||||
|
private long price;
|
||||||
|
private boolean useMarketBasedPrice;
|
||||||
|
private double marketPriceMargin;
|
||||||
|
private long amount;
|
||||||
|
private long minAmount;
|
||||||
|
private long volume;
|
||||||
|
private long minVolume;
|
||||||
|
private long txFee;
|
||||||
|
private long makerFee;
|
||||||
|
private String offerFeePaymentTxId;
|
||||||
|
private long buyerSecurityDeposit;
|
||||||
|
private long sellerSecurityDeposit;
|
||||||
|
private long triggerPrice;
|
||||||
|
private boolean isCurrencyForMakerFeeBtc;
|
||||||
|
private String paymentAccountId;
|
||||||
|
private String paymentMethodId;
|
||||||
|
private String paymentMethodShortName;
|
||||||
|
private String baseCurrencyCode;
|
||||||
|
private String counterCurrencyCode;
|
||||||
|
private long date;
|
||||||
|
private String state;
|
||||||
|
private boolean isActivated;
|
||||||
|
private boolean isMyOffer;
|
||||||
|
private boolean isMyPendingOffer;
|
||||||
|
private boolean isBsqSwapOffer;
|
||||||
|
private String ownerNodeAddress;
|
||||||
|
private String pubKeyRing;
|
||||||
|
private String versionNumber;
|
||||||
|
private int protocolVersion;
|
||||||
|
|
||||||
|
public OfferInfoBuilder withId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withDirection(String direction) {
|
||||||
|
this.direction = direction;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withPrice(long price) {
|
||||||
|
this.price = price;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withUseMarketBasedPrice(boolean useMarketBasedPrice) {
|
||||||
|
this.useMarketBasedPrice = useMarketBasedPrice;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withMarketPriceMargin(double useMarketBasedPrice) {
|
||||||
|
this.marketPriceMargin = useMarketBasedPrice;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withAmount(long amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withMinAmount(long minAmount) {
|
||||||
|
this.minAmount = minAmount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withVolume(long volume) {
|
||||||
|
this.volume = volume;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withMinVolume(long minVolume) {
|
||||||
|
this.minVolume = minVolume;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withTxFee(long txFee) {
|
||||||
|
this.txFee = txFee;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withMakerFee(long makerFee) {
|
||||||
|
this.makerFee = makerFee;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withOfferFeePaymentTxId(String offerFeePaymentTxId) {
|
||||||
|
this.offerFeePaymentTxId = offerFeePaymentTxId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withBuyerSecurityDeposit(long buyerSecurityDeposit) {
|
||||||
|
this.buyerSecurityDeposit = buyerSecurityDeposit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withSellerSecurityDeposit(long sellerSecurityDeposit) {
|
||||||
|
this.sellerSecurityDeposit = sellerSecurityDeposit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withTriggerPrice(long triggerPrice) {
|
||||||
|
this.triggerPrice = triggerPrice;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withIsCurrencyForMakerFeeBtc(boolean isCurrencyForMakerFeeBtc) {
|
||||||
|
this.isCurrencyForMakerFeeBtc = isCurrencyForMakerFeeBtc;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withPaymentAccountId(String paymentAccountId) {
|
||||||
|
this.paymentAccountId = paymentAccountId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withPaymentMethodId(String paymentMethodId) {
|
||||||
|
this.paymentMethodId = paymentMethodId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withPaymentMethodShortName(String paymentMethodShortName) {
|
||||||
|
this.paymentMethodShortName = paymentMethodShortName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withBaseCurrencyCode(String baseCurrencyCode) {
|
||||||
|
this.baseCurrencyCode = baseCurrencyCode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withCounterCurrencyCode(String counterCurrencyCode) {
|
||||||
|
this.counterCurrencyCode = counterCurrencyCode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withDate(long date) {
|
||||||
|
this.date = date;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withState(String state) {
|
||||||
|
this.state = state;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withIsActivated(boolean isActivated) {
|
||||||
|
this.isActivated = isActivated;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withIsMyOffer(boolean isMyOffer) {
|
||||||
|
this.isMyOffer = isMyOffer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withIsMyPendingOffer(boolean isMyPendingOffer) {
|
||||||
|
this.isMyPendingOffer = isMyPendingOffer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withIsBsqSwapOffer(boolean isBsqSwapOffer) {
|
||||||
|
this.isBsqSwapOffer = isBsqSwapOffer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withOwnerNodeAddress(String ownerNodeAddress) {
|
||||||
|
this.ownerNodeAddress = ownerNodeAddress;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withPubKeyRing(String pubKeyRing) {
|
||||||
|
this.pubKeyRing = pubKeyRing;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withVersionNumber(String versionNumber) {
|
||||||
|
this.versionNumber = versionNumber;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfoBuilder withProtocolVersion(int protocolVersion) {
|
||||||
|
this.protocolVersion = protocolVersion;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferInfo build() {
|
||||||
|
return new OfferInfo(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,195 @@
|
||||||
|
/*
|
||||||
|
* 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.core.api.model.builder;
|
||||||
|
|
||||||
|
import bisq.core.api.model.ContractInfo;
|
||||||
|
import bisq.core.api.model.OfferInfo;
|
||||||
|
import bisq.core.api.model.TradeInfo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder helps avoid bungling use of a large TradeInfo constructor
|
||||||
|
* argument list. If consecutive argument values of the same type are not
|
||||||
|
* ordered correctly, the compiler won't complain but the resulting bugs could
|
||||||
|
* be hard to find and fix.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public final class TradeInfoV1Builder {
|
||||||
|
|
||||||
|
private OfferInfo offer;
|
||||||
|
private String tradeId;
|
||||||
|
private String shortId;
|
||||||
|
private long date;
|
||||||
|
private String role;
|
||||||
|
private boolean isCurrencyForTakerFeeBtc;
|
||||||
|
private long txFeeAsLong;
|
||||||
|
private long takerFeeAsLong;
|
||||||
|
private String takerFeeTxId;
|
||||||
|
private String depositTxId;
|
||||||
|
private String payoutTxId;
|
||||||
|
private long tradeAmountAsLong;
|
||||||
|
private long tradePrice;
|
||||||
|
private long tradeVolume;
|
||||||
|
private String tradingPeerNodeAddress;
|
||||||
|
private String state;
|
||||||
|
private String phase;
|
||||||
|
private String tradePeriodState;
|
||||||
|
private boolean isDepositPublished;
|
||||||
|
private boolean isDepositConfirmed;
|
||||||
|
private boolean isFiatSent;
|
||||||
|
private boolean isFiatReceived;
|
||||||
|
private boolean isPayoutPublished;
|
||||||
|
private boolean isWithdrawn;
|
||||||
|
private String contractAsJson;
|
||||||
|
private ContractInfo contract;
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withOffer(OfferInfo offer) {
|
||||||
|
this.offer = offer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withTradeId(String tradeId) {
|
||||||
|
this.tradeId = tradeId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withShortId(String shortId) {
|
||||||
|
this.shortId = shortId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withDate(long date) {
|
||||||
|
this.date = date;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withRole(String role) {
|
||||||
|
this.role = role;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withIsCurrencyForTakerFeeBtc(boolean isCurrencyForTakerFeeBtc) {
|
||||||
|
this.isCurrencyForTakerFeeBtc = isCurrencyForTakerFeeBtc;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withTxFeeAsLong(long txFeeAsLong) {
|
||||||
|
this.txFeeAsLong = txFeeAsLong;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withTakerFeeAsLong(long takerFeeAsLong) {
|
||||||
|
this.takerFeeAsLong = takerFeeAsLong;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withTakerFeeTxId(String takerFeeTxId) {
|
||||||
|
this.takerFeeTxId = takerFeeTxId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withDepositTxId(String depositTxId) {
|
||||||
|
this.depositTxId = depositTxId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withPayoutTxId(String payoutTxId) {
|
||||||
|
this.payoutTxId = payoutTxId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withTradeAmountAsLong(long tradeAmountAsLong) {
|
||||||
|
this.tradeAmountAsLong = tradeAmountAsLong;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withTradePrice(long tradePrice) {
|
||||||
|
this.tradePrice = tradePrice;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withTradeVolume(long tradeVolume) {
|
||||||
|
this.tradeVolume = tradeVolume;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withTradePeriodState(String tradePeriodState) {
|
||||||
|
this.tradePeriodState = tradePeriodState;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withState(String state) {
|
||||||
|
this.state = state;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withPhase(String phase) {
|
||||||
|
this.phase = phase;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withTradingPeerNodeAddress(String tradingPeerNodeAddress) {
|
||||||
|
this.tradingPeerNodeAddress = tradingPeerNodeAddress;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withIsDepositPublished(boolean isDepositPublished) {
|
||||||
|
this.isDepositPublished = isDepositPublished;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withIsDepositConfirmed(boolean isDepositConfirmed) {
|
||||||
|
this.isDepositConfirmed = isDepositConfirmed;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withIsFiatSent(boolean isFiatSent) {
|
||||||
|
this.isFiatSent = isFiatSent;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withIsFiatReceived(boolean isFiatReceived) {
|
||||||
|
this.isFiatReceived = isFiatReceived;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withIsPayoutPublished(boolean isPayoutPublished) {
|
||||||
|
this.isPayoutPublished = isPayoutPublished;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withIsWithdrawn(boolean isWithdrawn) {
|
||||||
|
this.isWithdrawn = isWithdrawn;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withContractAsJson(String contractAsJson) {
|
||||||
|
this.contractAsJson = contractAsJson;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfoV1Builder withContract(ContractInfo contract) {
|
||||||
|
this.contract = contract;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeInfo build() {
|
||||||
|
return new TradeInfo(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -488,6 +488,14 @@ public class OfferUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isFiatOffer(Offer offer) {
|
||||||
|
return offer.getBaseCurrencyCode().equals("BTC") && !offer.isBsqSwapOffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAltcoinOffer(Offer offer) {
|
||||||
|
return offer.getCounterCurrencyCode().equals("BTC") && !offer.isBsqSwapOffer();
|
||||||
|
}
|
||||||
|
|
||||||
public static Optional<String> getInvalidMakerFeeTxErrorMessage(Offer offer, BtcWalletService btcWalletService) {
|
public static Optional<String> getInvalidMakerFeeTxErrorMessage(Offer offer, BtcWalletService btcWalletService) {
|
||||||
String offerFeePaymentTxId = offer.getOfferFeePaymentTxId();
|
String offerFeePaymentTxId = offer.getOfferFeePaymentTxId();
|
||||||
if (offerFeePaymentTxId == null) {
|
if (offerFeePaymentTxId == null) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import bisq.core.payment.payload.PaymentAccountPayload;
|
||||||
import bisq.core.trade.model.TradeModel;
|
import bisq.core.trade.model.TradeModel;
|
||||||
import bisq.core.trade.model.bisq_v1.Contract;
|
import bisq.core.trade.model.bisq_v1.Contract;
|
||||||
import bisq.core.trade.model.bisq_v1.Trade;
|
import bisq.core.trade.model.bisq_v1.Trade;
|
||||||
|
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
|
||||||
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
import bisq.network.p2p.NodeAddress;
|
||||||
|
|
||||||
|
@ -57,6 +58,8 @@ import static java.lang.String.format;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class TradeUtil {
|
public class TradeUtil {
|
||||||
|
|
||||||
|
// TODO change non-state dependent instance methods to static methods.
|
||||||
|
|
||||||
private final BtcWalletService btcWalletService;
|
private final BtcWalletService btcWalletService;
|
||||||
private final KeyRing keyRing;
|
private final KeyRing keyRing;
|
||||||
|
|
||||||
|
@ -203,6 +206,24 @@ public class TradeUtil {
|
||||||
offer.getCurrencyCode());
|
offer.getCurrencyCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string describing a trader's role for a given bsq swap.
|
||||||
|
* @param trade BsqSwapTrade
|
||||||
|
* @return String describing a trader's role for a given bsq swap
|
||||||
|
*/
|
||||||
|
public String getRole(BsqSwapTrade trade) {
|
||||||
|
Offer offer = trade.getOffer();
|
||||||
|
if (offer == null)
|
||||||
|
throw new IllegalStateException(
|
||||||
|
format("could not get role because no offer was found for bsq swap '%s'",
|
||||||
|
trade.getShortId()));
|
||||||
|
|
||||||
|
KeyRing keyRing = trade.getBsqSwapProtocolModel().getKeyRing();
|
||||||
|
return getRole(offer.isBuyOffer(),
|
||||||
|
offer.isMyOffer(keyRing),
|
||||||
|
offer.getCurrencyCode());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a string describing a trader's role.
|
* Returns a string describing a trader's role.
|
||||||
*
|
*
|
||||||
|
|
|
@ -69,6 +69,7 @@ public class BsqSwapProtocolModel implements ProtocolModel<BsqSwapTradePeer> {
|
||||||
transient private Offer offer;
|
transient private Offer offer;
|
||||||
@Setter
|
@Setter
|
||||||
transient private TradeMessage tradeMessage;
|
transient private TradeMessage tradeMessage;
|
||||||
|
// TODO rename tradingPeerNodeAddress ?
|
||||||
@Nullable
|
@Nullable
|
||||||
@Setter
|
@Setter
|
||||||
transient private NodeAddress tempTradingPeerNodeAddress;
|
transient private NodeAddress tempTradingPeerNodeAddress;
|
||||||
|
|
|
@ -7,38 +7,34 @@ createoffer - create offer to buy or sell BTC
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
createoffer
|
createoffer
|
||||||
--payment-account=<payment-acct-id>
|
|
||||||
--direction=<buy|sell>
|
|
||||||
--currency-code=<eur|usd>
|
|
||||||
--market-price-margin=<percent> | --fixed-price=<btc-price>
|
|
||||||
--amount=<btc-amount>
|
--amount=<btc-amount>
|
||||||
--min-amount=<btc-amount>
|
--min-amount=<btc-amount>
|
||||||
|
--currency-code=<bsq|eur|usd|...>
|
||||||
|
--direction=<buy|sell>
|
||||||
|
--fixed-price=<btc-price> | --market-price-margin=<percent>
|
||||||
|
--payment-account=<payment-acct-id>
|
||||||
--security-deposit=<percent>
|
--security-deposit=<percent>
|
||||||
|
--swap=<true|false>
|
||||||
[--fee-currency=<bsq|btc>]
|
[--fee-currency=<bsq|btc>]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
Create and place an offer to buy or sell BTC using a fiat account.
|
Create and place an offer to buy or sell BTC. There are two types of offers.
|
||||||
|
|
||||||
|
BSQ swap offers
|
||||||
|
|
||||||
|
The createoffer command requires the swap, amount [, optional min-amount], direction,
|
||||||
|
and fixed-price parameters, where --swap=true and the user's wallet contains sufficient
|
||||||
|
BTC and/or BSQ to cover the trade amount and maker fee.
|
||||||
|
|
||||||
|
Version 1 protocol fiat and BSQ offers
|
||||||
|
|
||||||
|
The createoffer command requires the payment-account, amount [,optional min-amount],
|
||||||
|
currency-code, direction, fixed-price or market-price-margin, and security-deposit parameters.
|
||||||
|
The fee-currency parameter can be optionally used to pay the taker fee in BSQ.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
--payment-account
|
|
||||||
The ID of the fiat payment account used to send or receive funds during the trade.
|
|
||||||
|
|
||||||
--direction
|
|
||||||
The direction of the trade (BUY or SELL).
|
|
||||||
|
|
||||||
--currency-code
|
|
||||||
The three letter code for the fiat used to buy or sell BTC, e.g., EUR, USD, BRL, ...
|
|
||||||
|
|
||||||
--market-price-margin
|
|
||||||
The % above or below market BTC price, e.g., 1.00 (1%).
|
|
||||||
If --market-price-margin is not present, --fixed-price must be.
|
|
||||||
|
|
||||||
--fixed-price
|
|
||||||
The fixed BTC price in fiat used to buy or sell BTC, e.g., 34000 (USD).
|
|
||||||
If --fixed-price is not present, --market-price-margin must be.
|
|
||||||
|
|
||||||
--amount
|
--amount
|
||||||
The amount of BTC to buy or sell, e.g., 0.125.
|
The amount of BTC to buy or sell, e.g., 0.125.
|
||||||
|
|
||||||
|
@ -46,15 +42,41 @@ OPTIONS
|
||||||
The minimum amount of BTC to buy or sell, e.g., 0.006.
|
The minimum amount of BTC to buy or sell, e.g., 0.006.
|
||||||
If --min-amount is not present, it defaults to the --amount value.
|
If --min-amount is not present, it defaults to the --amount value.
|
||||||
|
|
||||||
--security-deposit
|
--currency-code
|
||||||
The percentage of the BTC amount being traded for the security deposit, e.g., 60.0 (60%).
|
The three-letter code for the currency used to buy or sell BTC, e.g., BSQ, EUR, USD, BRL, ...
|
||||||
|
|
||||||
|
--direction
|
||||||
|
The direction of the trade (BUY or SELL).
|
||||||
|
|
||||||
--fee-currency
|
--fee-currency
|
||||||
The wallet currency used to pay the Bisq trade maker fee (BSQ|BTC). Default is BTC
|
The wallet currency used to pay the Bisq trade maker fee (BSQ|BTC). Default is BTC
|
||||||
|
|
||||||
|
--fixed-price
|
||||||
|
The fixed BTC price in fiat used to buy or sell BTC, e.g., 34000 (USD).
|
||||||
|
If --fixed-price is not present, --market-price-margin must be.
|
||||||
|
|
||||||
|
--market-price-margin
|
||||||
|
The % above or below market BTC price, e.g., 1.00 (1%).
|
||||||
|
If --market-price-margin is not present, --fixed-price must be.
|
||||||
|
|
||||||
|
--payment-account
|
||||||
|
The ID of the fiat payment account used to send or receive funds during the trade.
|
||||||
|
|
||||||
|
--security-deposit
|
||||||
|
The percentage of the BTC amount being traded for the security deposit, e.g., 60.0 (60%).
|
||||||
|
|
||||||
|
--swap
|
||||||
|
Flag determining whether the offer is a BSQ swap or version 1 protocol offer. Default is false.
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
To create a BUY 0.25 BTC with BSQ swap offer at a fixed BSQ price of 0.00005 BSQ per 1 BTC:
|
||||||
|
$ ./bisq-cli --password=xyz --port=9998 createoffer --swap=true \
|
||||||
|
--direction=buy \
|
||||||
|
--amount=0.25 \
|
||||||
|
--fixed-price=0.00005
|
||||||
|
|
||||||
To create a BUY 0.125 BTC with EUR offer
|
To create a BUY 0.125 BTC with EUR offer
|
||||||
at the current market price,
|
at the current market price,
|
||||||
using a payment account with ID 7413d263-225a-4f1b-837a-1e3094dc0d77,
|
using a payment account with ID 7413d263-225a-4f1b-837a-1e3094dc0d77,
|
||||||
|
|
|
@ -9,11 +9,22 @@ SYNOPSIS
|
||||||
takeoffer
|
takeoffer
|
||||||
--offer-id=<offer-id>
|
--offer-id=<offer-id>
|
||||||
--payment-account=<payment-acct-id>
|
--payment-account=<payment-acct-id>
|
||||||
--fee-currency=<eur|usd>
|
[--fee-currency=<btc|bsq>]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
Take an existing offer using a matching payment method. The Bisq trade fee can be paid in BSQ or BTC.
|
Take an existing offer. There are currently two types offers and trade protocols.
|
||||||
|
|
||||||
|
BSQ swap offers
|
||||||
|
|
||||||
|
The takeoffer command only requires an offer-id parameter, and sufficient BSQ and BTC
|
||||||
|
to cover the trade amount and the taker fee. The trade (swap) will be executed immediately
|
||||||
|
after being successfully taken.
|
||||||
|
|
||||||
|
Version 1 protocol fiat and BSQ offers
|
||||||
|
|
||||||
|
The offer-id and payment-account parameters are required. The fee-currency parameter can
|
||||||
|
be optionally used to pay the taker fee in BSQ.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
|
@ -29,6 +40,9 @@ OPTIONS
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
--------
|
--------
|
||||||
|
To take a BSQ swap offer with ID y3a8b2e2-51b6-4f39-b6c1-3ebd52c22aea;
|
||||||
|
$ ./bisq-cli --password=xyz --port=9998 takeoffer --offer-id=y3a8b2e2-51b6-4f39-b6c1-3ebd52c22aea
|
||||||
|
|
||||||
To take an offer with ID 83e8b2e2-51b6-4f39-a748-3ebd29c22aea
|
To take an offer with ID 83e8b2e2-51b6-4f39-a748-3ebd29c22aea
|
||||||
using a payment account with ID fe20cdbd-22be-4b8a-a4b6-d2608ff09d6e,
|
using a payment account with ID fe20cdbd-22be-4b8a-a4b6-d2608ff09d6e,
|
||||||
and paying the Bisq trading fee in BSQ:
|
and paying the Bisq trading fee in BSQ:
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
package bisq.daemon.grpc;
|
package bisq.daemon.grpc;
|
||||||
|
|
||||||
import bisq.core.api.CoreApi;
|
import bisq.core.api.CoreApi;
|
||||||
import bisq.core.api.model.BsqSwapOfferInfo;
|
|
||||||
import bisq.core.api.model.OfferInfo;
|
import bisq.core.api.model.OfferInfo;
|
||||||
import bisq.core.offer.Offer;
|
import bisq.core.offer.Offer;
|
||||||
import bisq.core.offer.OpenOffer;
|
import bisq.core.offer.OpenOffer;
|
||||||
|
@ -33,12 +32,15 @@ import bisq.proto.grpc.EditOfferReply;
|
||||||
import bisq.proto.grpc.EditOfferRequest;
|
import bisq.proto.grpc.EditOfferRequest;
|
||||||
import bisq.proto.grpc.GetBsqSwapOfferReply;
|
import bisq.proto.grpc.GetBsqSwapOfferReply;
|
||||||
import bisq.proto.grpc.GetBsqSwapOffersReply;
|
import bisq.proto.grpc.GetBsqSwapOffersReply;
|
||||||
|
import bisq.proto.grpc.GetBsqSwapOffersRequest;
|
||||||
import bisq.proto.grpc.GetMyBsqSwapOfferReply;
|
import bisq.proto.grpc.GetMyBsqSwapOfferReply;
|
||||||
import bisq.proto.grpc.GetMyBsqSwapOffersReply;
|
import bisq.proto.grpc.GetMyBsqSwapOffersReply;
|
||||||
import bisq.proto.grpc.GetMyOfferReply;
|
import bisq.proto.grpc.GetMyOfferReply;
|
||||||
import bisq.proto.grpc.GetMyOfferRequest;
|
import bisq.proto.grpc.GetMyOfferRequest;
|
||||||
import bisq.proto.grpc.GetMyOffersReply;
|
import bisq.proto.grpc.GetMyOffersReply;
|
||||||
import bisq.proto.grpc.GetMyOffersRequest;
|
import bisq.proto.grpc.GetMyOffersRequest;
|
||||||
|
import bisq.proto.grpc.GetOfferCategoryReply;
|
||||||
|
import bisq.proto.grpc.GetOfferCategoryRequest;
|
||||||
import bisq.proto.grpc.GetOfferReply;
|
import bisq.proto.grpc.GetOfferReply;
|
||||||
import bisq.proto.grpc.GetOfferRequest;
|
import bisq.proto.grpc.GetOfferRequest;
|
||||||
import bisq.proto.grpc.GetOffersReply;
|
import bisq.proto.grpc.GetOffersReply;
|
||||||
|
@ -56,10 +58,15 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import static bisq.core.api.model.BsqSwapOfferInfo.toBsqSwapOfferInfo;
|
import static bisq.core.api.model.OfferInfo.toMyPendingOfferInfo;
|
||||||
import static bisq.core.api.model.OfferInfo.toOfferInfo;
|
import static bisq.core.api.model.OfferInfo.toOfferInfo;
|
||||||
import static bisq.core.api.model.OfferInfo.toPendingOfferInfo;
|
|
||||||
import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
|
import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
|
||||||
|
import static bisq.proto.grpc.GetOfferCategoryReply.OfferCategory;
|
||||||
|
import static bisq.proto.grpc.GetOfferCategoryReply.OfferCategory.ALTCOIN;
|
||||||
|
import static bisq.proto.grpc.GetOfferCategoryReply.OfferCategory.BSQ_SWAP;
|
||||||
|
import static bisq.proto.grpc.GetOfferCategoryReply.OfferCategory.FIAT;
|
||||||
|
import static bisq.proto.grpc.GetOfferCategoryReply.OfferCategory.UNKNOWN;
|
||||||
|
import static bisq.proto.grpc.GetOfferCategoryReply.newBuilder;
|
||||||
import static bisq.proto.grpc.OffersGrpc.*;
|
import static bisq.proto.grpc.OffersGrpc.*;
|
||||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
@ -81,13 +88,28 @@ class GrpcOffersService extends OffersImplBase {
|
||||||
this.exceptionHandler = exceptionHandler;
|
this.exceptionHandler = exceptionHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getOfferCategory(GetOfferCategoryRequest req,
|
||||||
|
StreamObserver<GetOfferCategoryReply> responseObserver) {
|
||||||
|
try {
|
||||||
|
OfferCategory category = getOfferCategory(req.getId(), req.getIsMyOffer());
|
||||||
|
var reply = newBuilder()
|
||||||
|
.setOfferCategory(category)
|
||||||
|
.build();
|
||||||
|
responseObserver.onNext(reply);
|
||||||
|
responseObserver.onCompleted();
|
||||||
|
} catch (Throwable cause) {
|
||||||
|
exceptionHandler.handleException(log, cause, responseObserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getBsqSwapOffer(GetOfferRequest req,
|
public void getBsqSwapOffer(GetOfferRequest req,
|
||||||
StreamObserver<GetBsqSwapOfferReply> responseObserver) {
|
StreamObserver<GetBsqSwapOfferReply> responseObserver) {
|
||||||
try {
|
try {
|
||||||
Offer offer = coreApi.getOffer(req.getId());
|
Offer offer = coreApi.getOffer(req.getId());
|
||||||
var reply = GetBsqSwapOfferReply.newBuilder()
|
var reply = GetBsqSwapOfferReply.newBuilder()
|
||||||
.setBsqSwapOffer(toBsqSwapOfferInfo(offer).toProtoMessage())
|
.setBsqSwapOffer(toOfferInfo(offer).toProtoMessage())
|
||||||
.build();
|
.build();
|
||||||
responseObserver.onNext(reply);
|
responseObserver.onNext(reply);
|
||||||
responseObserver.onCompleted();
|
responseObserver.onCompleted();
|
||||||
|
@ -117,7 +139,7 @@ class GrpcOffersService extends OffersImplBase {
|
||||||
try {
|
try {
|
||||||
Offer offer = coreApi.getMyBsqSwapOffer(req.getId());
|
Offer offer = coreApi.getMyBsqSwapOffer(req.getId());
|
||||||
var reply = GetMyBsqSwapOfferReply.newBuilder()
|
var reply = GetMyBsqSwapOfferReply.newBuilder()
|
||||||
.setBsqSwapOffer(toBsqSwapOfferInfo(offer /* TODO support triggerPrice */).toProtoMessage())
|
.setBsqSwapOffer(toOfferInfo(offer /* TODO support triggerPrice */).toProtoMessage())
|
||||||
.build();
|
.build();
|
||||||
responseObserver.onNext(reply);
|
responseObserver.onNext(reply);
|
||||||
responseObserver.onCompleted();
|
responseObserver.onCompleted();
|
||||||
|
@ -132,7 +154,7 @@ class GrpcOffersService extends OffersImplBase {
|
||||||
try {
|
try {
|
||||||
OpenOffer openOffer = coreApi.getMyOffer(req.getId());
|
OpenOffer openOffer = coreApi.getMyOffer(req.getId());
|
||||||
var reply = GetMyOfferReply.newBuilder()
|
var reply = GetMyOfferReply.newBuilder()
|
||||||
.setOffer(toOfferInfo(openOffer).toProtoMessage())
|
.setOffer(OfferInfo.toMyOfferInfo(openOffer).toProtoMessage())
|
||||||
.build();
|
.build();
|
||||||
responseObserver.onNext(reply);
|
responseObserver.onNext(reply);
|
||||||
responseObserver.onCompleted();
|
responseObserver.onCompleted();
|
||||||
|
@ -142,15 +164,15 @@ class GrpcOffersService extends OffersImplBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getBsqSwapOffers(GetOffersRequest req,
|
public void getBsqSwapOffers(GetBsqSwapOffersRequest req,
|
||||||
StreamObserver<GetBsqSwapOffersReply> responseObserver) {
|
StreamObserver<GetBsqSwapOffersReply> responseObserver) {
|
||||||
try {
|
try {
|
||||||
List<BsqSwapOfferInfo> result = coreApi.getBsqSwapOffers(req.getDirection())
|
List<OfferInfo> result = coreApi.getBsqSwapOffers(req.getDirection())
|
||||||
.stream().map(BsqSwapOfferInfo::toBsqSwapOfferInfo)
|
.stream().map(OfferInfo::toOfferInfo)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
var reply = GetBsqSwapOffersReply.newBuilder()
|
var reply = GetBsqSwapOffersReply.newBuilder()
|
||||||
.addAllBsqSwapOffers(result.stream()
|
.addAllBsqSwapOffers(result.stream()
|
||||||
.map(BsqSwapOfferInfo::toProtoMessage)
|
.map(OfferInfo::toProtoMessage)
|
||||||
.collect(Collectors.toList()))
|
.collect(Collectors.toList()))
|
||||||
.build();
|
.build();
|
||||||
responseObserver.onNext(reply);
|
responseObserver.onNext(reply);
|
||||||
|
@ -180,15 +202,15 @@ class GrpcOffersService extends OffersImplBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getMyBsqSwapOffers(GetMyOffersRequest req,
|
public void getMyBsqSwapOffers(GetBsqSwapOffersRequest req,
|
||||||
StreamObserver<GetMyBsqSwapOffersReply> responseObserver) {
|
StreamObserver<GetMyBsqSwapOffersReply> responseObserver) {
|
||||||
try {
|
try {
|
||||||
List<BsqSwapOfferInfo> result = coreApi.getMyBsqSwapOffers(req.getDirection())
|
List<OfferInfo> result = coreApi.getMyBsqSwapOffers(req.getDirection())
|
||||||
.stream().map(BsqSwapOfferInfo::toBsqSwapOfferInfo)
|
.stream().map(OfferInfo::toOfferInfo)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
var reply = GetMyBsqSwapOffersReply.newBuilder()
|
var reply = GetMyBsqSwapOffersReply.newBuilder()
|
||||||
.addAllBsqSwapOffers(result.stream()
|
.addAllBsqSwapOffers(result.stream()
|
||||||
.map(BsqSwapOfferInfo::toProtoMessage)
|
.map(OfferInfo::toProtoMessage)
|
||||||
.collect(Collectors.toList()))
|
.collect(Collectors.toList()))
|
||||||
.build();
|
.build();
|
||||||
responseObserver.onNext(reply);
|
responseObserver.onNext(reply);
|
||||||
|
@ -204,7 +226,7 @@ class GrpcOffersService extends OffersImplBase {
|
||||||
try {
|
try {
|
||||||
List<OfferInfo> result = coreApi.getMyOffers(req.getDirection(), req.getCurrencyCode())
|
List<OfferInfo> result = coreApi.getMyOffers(req.getDirection(), req.getCurrencyCode())
|
||||||
.stream()
|
.stream()
|
||||||
.map(OfferInfo::toOfferInfo)
|
.map(OfferInfo::toMyOfferInfo)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
var reply = GetMyOffersReply.newBuilder()
|
var reply = GetMyOffersReply.newBuilder()
|
||||||
.addAllOffers(result.stream()
|
.addAllOffers(result.stream()
|
||||||
|
@ -222,17 +244,15 @@ class GrpcOffersService extends OffersImplBase {
|
||||||
public void createBsqSwapOffer(CreateBsqSwapOfferRequest req,
|
public void createBsqSwapOffer(CreateBsqSwapOfferRequest req,
|
||||||
StreamObserver<CreateBsqSwapOfferReply> responseObserver) {
|
StreamObserver<CreateBsqSwapOfferReply> responseObserver) {
|
||||||
try {
|
try {
|
||||||
//todo PaymentAccount for bsq swap not needed as its just a dummy account
|
|
||||||
coreApi.createAndPlaceBsqSwapOffer(
|
coreApi.createAndPlaceBsqSwapOffer(
|
||||||
req.getDirection(),
|
req.getDirection(),
|
||||||
req.getAmount(),
|
req.getAmount(),
|
||||||
req.getMinAmount(),
|
req.getMinAmount(),
|
||||||
req.getPrice(),
|
req.getPrice(),
|
||||||
/* req.getPaymentAccountId(),*/
|
|
||||||
offer -> {
|
offer -> {
|
||||||
BsqSwapOfferInfo bsqSwapOfferInfo = toBsqSwapOfferInfo(offer);
|
OfferInfo offerInfo = toMyPendingOfferInfo(offer);
|
||||||
CreateBsqSwapOfferReply reply = CreateBsqSwapOfferReply.newBuilder()
|
CreateBsqSwapOfferReply reply = CreateBsqSwapOfferReply.newBuilder()
|
||||||
.setBsqSwapOffer(bsqSwapOfferInfo.toProtoMessage())
|
.setBsqSwapOffer(offerInfo.toProtoMessage())
|
||||||
.build();
|
.build();
|
||||||
responseObserver.onNext(reply);
|
responseObserver.onNext(reply);
|
||||||
responseObserver.onCompleted();
|
responseObserver.onCompleted();
|
||||||
|
@ -261,7 +281,7 @@ class GrpcOffersService extends OffersImplBase {
|
||||||
offer -> {
|
offer -> {
|
||||||
// This result handling consumer's accept operation will return
|
// This result handling consumer's accept operation will return
|
||||||
// the new offer to the gRPC client after async placement is done.
|
// the new offer to the gRPC client after async placement is done.
|
||||||
OfferInfo offerInfo = toPendingOfferInfo(offer);
|
OfferInfo offerInfo = toMyPendingOfferInfo(offer);
|
||||||
CreateOfferReply reply = CreateOfferReply.newBuilder()
|
CreateOfferReply reply = CreateOfferReply.newBuilder()
|
||||||
.setOffer(offerInfo.toProtoMessage())
|
.setOffer(offerInfo.toProtoMessage())
|
||||||
.build();
|
.build();
|
||||||
|
@ -315,6 +335,7 @@ class GrpcOffersService extends OffersImplBase {
|
||||||
return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
|
return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
|
||||||
.or(() -> Optional.of(CallRateMeteringInterceptor.valueOf(
|
.or(() -> Optional.of(CallRateMeteringInterceptor.valueOf(
|
||||||
new HashMap<>() {{
|
new HashMap<>() {{
|
||||||
|
put(getGetOfferCategoryMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
||||||
put(getGetOfferMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
put(getGetOfferMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
||||||
put(getGetMyOfferMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
put(getGetMyOfferMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
||||||
put(getGetOffersMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
put(getGetOffersMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
||||||
|
@ -325,4 +346,15 @@ class GrpcOffersService extends OffersImplBase {
|
||||||
}}
|
}}
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private OfferCategory getOfferCategory(String offerId, boolean isMyOffer) {
|
||||||
|
if (coreApi.isAltcoinOffer(offerId, isMyOffer))
|
||||||
|
return ALTCOIN;
|
||||||
|
else if (coreApi.isFiatOffer(offerId, isMyOffer))
|
||||||
|
return FIAT;
|
||||||
|
else if (coreApi.isBsqSwapOffer(offerId, isMyOffer))
|
||||||
|
return BSQ_SWAP;
|
||||||
|
else
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,21 +18,19 @@
|
||||||
package bisq.daemon.grpc;
|
package bisq.daemon.grpc;
|
||||||
|
|
||||||
import bisq.core.api.CoreApi;
|
import bisq.core.api.CoreApi;
|
||||||
import bisq.core.api.model.BsqSwapTradeInfo;
|
|
||||||
import bisq.core.api.model.TradeInfo;
|
import bisq.core.api.model.TradeInfo;
|
||||||
|
import bisq.core.trade.model.TradeModel;
|
||||||
import bisq.core.trade.model.bisq_v1.Trade;
|
import bisq.core.trade.model.bisq_v1.Trade;
|
||||||
|
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
|
||||||
|
|
||||||
import bisq.proto.grpc.ConfirmPaymentReceivedReply;
|
import bisq.proto.grpc.ConfirmPaymentReceivedReply;
|
||||||
import bisq.proto.grpc.ConfirmPaymentReceivedRequest;
|
import bisq.proto.grpc.ConfirmPaymentReceivedRequest;
|
||||||
import bisq.proto.grpc.ConfirmPaymentStartedReply;
|
import bisq.proto.grpc.ConfirmPaymentStartedReply;
|
||||||
import bisq.proto.grpc.ConfirmPaymentStartedRequest;
|
import bisq.proto.grpc.ConfirmPaymentStartedRequest;
|
||||||
import bisq.proto.grpc.GetBsqSwapTradeReply;
|
|
||||||
import bisq.proto.grpc.GetTradeReply;
|
import bisq.proto.grpc.GetTradeReply;
|
||||||
import bisq.proto.grpc.GetTradeRequest;
|
import bisq.proto.grpc.GetTradeRequest;
|
||||||
import bisq.proto.grpc.KeepFundsReply;
|
import bisq.proto.grpc.KeepFundsReply;
|
||||||
import bisq.proto.grpc.KeepFundsRequest;
|
import bisq.proto.grpc.KeepFundsRequest;
|
||||||
import bisq.proto.grpc.TakeBsqSwapOfferReply;
|
|
||||||
import bisq.proto.grpc.TakeBsqSwapOfferRequest;
|
|
||||||
import bisq.proto.grpc.TakeOfferReply;
|
import bisq.proto.grpc.TakeOfferReply;
|
||||||
import bisq.proto.grpc.TakeOfferRequest;
|
import bisq.proto.grpc.TakeOfferRequest;
|
||||||
import bisq.proto.grpc.WithdrawFundsReply;
|
import bisq.proto.grpc.WithdrawFundsReply;
|
||||||
|
@ -48,7 +46,6 @@ import java.util.Optional;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import static bisq.core.api.model.BsqSwapTradeInfo.toBsqSwapTradeInfo;
|
|
||||||
import static bisq.core.api.model.TradeInfo.toNewTradeInfo;
|
import static bisq.core.api.model.TradeInfo.toNewTradeInfo;
|
||||||
import static bisq.core.api.model.TradeInfo.toTradeInfo;
|
import static bisq.core.api.model.TradeInfo.toTradeInfo;
|
||||||
import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
|
import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
|
||||||
|
@ -74,60 +71,49 @@ class GrpcTradesService extends TradesImplBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getBsqSwapTrade(GetTradeRequest req,
|
public void takeOffer(TakeOfferRequest req,
|
||||||
StreamObserver<GetBsqSwapTradeReply> responseObserver) {
|
StreamObserver<TakeOfferReply> responseObserver) {
|
||||||
try {
|
|
||||||
var bsqSwapTrade = coreApi.getBsqSwapTrade(req.getTradeId());
|
|
||||||
// String role = coreApi.getBsqSwapTradeRole(req.getTradeId());
|
|
||||||
var reply = GetBsqSwapTradeReply.newBuilder()
|
|
||||||
.setBsqSwapTrade(toBsqSwapTradeInfo(bsqSwapTrade).toProtoMessage())
|
|
||||||
.build();
|
|
||||||
responseObserver.onNext(reply);
|
|
||||||
responseObserver.onCompleted();
|
|
||||||
} catch (IllegalArgumentException cause) {
|
|
||||||
// Offer makers may call 'gettrade' many times before a trade exists.
|
|
||||||
// Log a 'trade not found' warning instead of a full stack trace.
|
|
||||||
exceptionHandler.handleExceptionAsWarning(log, "getBsqSwapTrade", cause, responseObserver);
|
|
||||||
} catch (Throwable cause) {
|
|
||||||
exceptionHandler.handleException(log, cause, responseObserver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void takeBsqSwapOffer(TakeBsqSwapOfferRequest req,
|
|
||||||
StreamObserver<TakeBsqSwapOfferReply> responseObserver) {
|
|
||||||
GrpcErrorMessageHandler errorMessageHandler =
|
GrpcErrorMessageHandler errorMessageHandler =
|
||||||
new GrpcErrorMessageHandler(getTakeOfferMethod().getFullMethodName(),
|
new GrpcErrorMessageHandler(getTakeOfferMethod().getFullMethodName(),
|
||||||
responseObserver,
|
responseObserver,
|
||||||
exceptionHandler,
|
exceptionHandler,
|
||||||
log);
|
log);
|
||||||
coreApi.takeBsqSwapOffer(req.getOfferId(),
|
|
||||||
req.getPaymentAccountId(),
|
if (coreApi.isBsqSwapOffer(req.getOfferId(), false)) {
|
||||||
req.getTakerFeeCurrencyCode(),
|
coreApi.takeBsqSwapOffer(req.getOfferId(),
|
||||||
bsqSwapTrade -> {
|
bsqSwapTrade -> {
|
||||||
BsqSwapTradeInfo bsqSwapTradeInfo = toBsqSwapTradeInfo(bsqSwapTrade);
|
var reply = buildTakeOfferReply(bsqSwapTrade);
|
||||||
var reply = TakeBsqSwapOfferReply.newBuilder()
|
responseObserver.onNext(reply);
|
||||||
.setBsqSwapTrade(bsqSwapTradeInfo.toProtoMessage())
|
responseObserver.onCompleted();
|
||||||
.build();
|
},
|
||||||
responseObserver.onNext(reply);
|
errorMessage -> {
|
||||||
responseObserver.onCompleted();
|
if (!errorMessageHandler.isErrorHandled())
|
||||||
},
|
errorMessageHandler.handleErrorMessage(errorMessage);
|
||||||
errorMessage -> {
|
});
|
||||||
if (!errorMessageHandler.isErrorHandled())
|
} else {
|
||||||
errorMessageHandler.handleErrorMessage(errorMessage);
|
coreApi.takeOffer(req.getOfferId(),
|
||||||
});
|
req.getPaymentAccountId(),
|
||||||
|
req.getTakerFeeCurrencyCode(),
|
||||||
|
trade -> {
|
||||||
|
var reply = buildTakeOfferReply(trade);
|
||||||
|
responseObserver.onNext(reply);
|
||||||
|
responseObserver.onCompleted();
|
||||||
|
},
|
||||||
|
errorMessage -> {
|
||||||
|
if (!errorMessageHandler.isErrorHandled())
|
||||||
|
errorMessageHandler.handleErrorMessage(errorMessage);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getTrade(GetTradeRequest req,
|
public void getTrade(GetTradeRequest req,
|
||||||
StreamObserver<GetTradeReply> responseObserver) {
|
StreamObserver<GetTradeReply> responseObserver) {
|
||||||
try {
|
try {
|
||||||
Trade trade = coreApi.getTrade(req.getTradeId());
|
var tradeModel = coreApi.getTradeModel(req.getTradeId());
|
||||||
boolean isMyOffer = coreApi.isMyOffer(trade.getOffer().getId());
|
var reply = tradeModel.getOffer().isBsqSwapOffer()
|
||||||
String role = coreApi.getTradeRole(req.getTradeId());
|
? buildGetTradeReply((BsqSwapTrade) tradeModel)
|
||||||
var reply = GetTradeReply.newBuilder()
|
: buildGetTradeReply((Trade) tradeModel);
|
||||||
.setTrade(toTradeInfo(trade, role, isMyOffer).toProtoMessage())
|
|
||||||
.build();
|
|
||||||
responseObserver.onNext(reply);
|
responseObserver.onNext(reply);
|
||||||
responseObserver.onCompleted();
|
responseObserver.onCompleted();
|
||||||
} catch (IllegalArgumentException cause) {
|
} catch (IllegalArgumentException cause) {
|
||||||
|
@ -139,31 +125,6 @@ class GrpcTradesService extends TradesImplBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void takeOffer(TakeOfferRequest req,
|
|
||||||
StreamObserver<TakeOfferReply> responseObserver) {
|
|
||||||
GrpcErrorMessageHandler errorMessageHandler =
|
|
||||||
new GrpcErrorMessageHandler(getTakeOfferMethod().getFullMethodName(),
|
|
||||||
responseObserver,
|
|
||||||
exceptionHandler,
|
|
||||||
log);
|
|
||||||
coreApi.takeOffer(req.getOfferId(),
|
|
||||||
req.getPaymentAccountId(),
|
|
||||||
req.getTakerFeeCurrencyCode(),
|
|
||||||
trade -> {
|
|
||||||
TradeInfo tradeInfo = toNewTradeInfo(trade);
|
|
||||||
var reply = TakeOfferReply.newBuilder()
|
|
||||||
.setTrade(tradeInfo.toProtoMessage())
|
|
||||||
.build();
|
|
||||||
responseObserver.onNext(reply);
|
|
||||||
responseObserver.onCompleted();
|
|
||||||
},
|
|
||||||
errorMessage -> {
|
|
||||||
if (!errorMessageHandler.isErrorHandled())
|
|
||||||
errorMessageHandler.handleErrorMessage(errorMessage);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void confirmPaymentStarted(ConfirmPaymentStartedRequest req,
|
public void confirmPaymentStarted(ConfirmPaymentStartedRequest req,
|
||||||
StreamObserver<ConfirmPaymentStartedReply> responseObserver) {
|
StreamObserver<ConfirmPaymentStartedReply> responseObserver) {
|
||||||
|
@ -228,6 +189,7 @@ class GrpcTradesService extends TradesImplBase {
|
||||||
new HashMap<>() {{
|
new HashMap<>() {{
|
||||||
put(getGetTradeMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
put(getGetTradeMethod().getFullMethodName(), new GrpcCallRateMeter(1, SECONDS));
|
||||||
put(getTakeOfferMethod().getFullMethodName(), new GrpcCallRateMeter(1, MINUTES));
|
put(getTakeOfferMethod().getFullMethodName(), new GrpcCallRateMeter(1, MINUTES));
|
||||||
|
// put(getTakeBsqSwapOfferMethod().getFullMethodName(), new GrpcCallRateMeter(1, MINUTES));
|
||||||
put(getConfirmPaymentStartedMethod().getFullMethodName(), new GrpcCallRateMeter(1, MINUTES));
|
put(getConfirmPaymentStartedMethod().getFullMethodName(), new GrpcCallRateMeter(1, MINUTES));
|
||||||
put(getConfirmPaymentReceivedMethod().getFullMethodName(), new GrpcCallRateMeter(1, MINUTES));
|
put(getConfirmPaymentReceivedMethod().getFullMethodName(), new GrpcCallRateMeter(1, MINUTES));
|
||||||
put(getKeepFundsMethod().getFullMethodName(), new GrpcCallRateMeter(1, MINUTES));
|
put(getKeepFundsMethod().getFullMethodName(), new GrpcCallRateMeter(1, MINUTES));
|
||||||
|
@ -235,4 +197,49 @@ class GrpcTradesService extends TradesImplBase {
|
||||||
}}
|
}}
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TakeOfferReply buildTakeOfferReply(TradeModel tradeModel) {
|
||||||
|
TradeInfo tradeInfo;
|
||||||
|
if (tradeModel.getOffer().isBsqSwapOffer()) {
|
||||||
|
BsqSwapTrade bsqSwapTrade = (BsqSwapTrade) tradeModel;
|
||||||
|
String role = getMyRole(bsqSwapTrade);
|
||||||
|
tradeInfo = toNewTradeInfo(bsqSwapTrade, role);
|
||||||
|
} else {
|
||||||
|
tradeInfo = toNewTradeInfo((Trade) tradeModel);
|
||||||
|
}
|
||||||
|
return TakeOfferReply.newBuilder()
|
||||||
|
.setTrade(tradeInfo.toProtoMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private GetTradeReply buildGetTradeReply(BsqSwapTrade bsqSwapTrade) {
|
||||||
|
boolean wasMyOffer = wasMyOffer(bsqSwapTrade);
|
||||||
|
String role = getMyRole(bsqSwapTrade);
|
||||||
|
var numConfirmations = coreApi.getTransactionConfirmations(bsqSwapTrade.getTxId());
|
||||||
|
var tradeInfo = toTradeInfo(bsqSwapTrade,
|
||||||
|
role,
|
||||||
|
wasMyOffer,
|
||||||
|
numConfirmations);
|
||||||
|
return GetTradeReply.newBuilder()
|
||||||
|
.setTrade(tradeInfo.toProtoMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private GetTradeReply buildGetTradeReply(Trade trade) {
|
||||||
|
boolean wasMyOffer = wasMyOffer(trade);
|
||||||
|
String role = getMyRole(trade);
|
||||||
|
return GetTradeReply.newBuilder()
|
||||||
|
.setTrade(toTradeInfo(trade, role, wasMyOffer).toProtoMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean wasMyOffer(TradeModel tradeModel) {
|
||||||
|
return coreApi.isMyOffer(tradeModel.getOffer().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMyRole(TradeModel tradeModel) {
|
||||||
|
return tradeModel.getOffer().isBsqSwapOffer()
|
||||||
|
? coreApi.getBsqSwapTradeRole((BsqSwapTrade) tradeModel)
|
||||||
|
: coreApi.getTradeRole(tradeModel.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ message GetMethodHelpReply {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
service Offers {
|
service Offers {
|
||||||
|
rpc GetOfferCategory (GetOfferCategoryRequest) returns (GetOfferCategoryReply) {
|
||||||
|
}
|
||||||
rpc GetBsqSwapOffer (GetOfferRequest) returns (GetBsqSwapOfferReply) {
|
rpc GetBsqSwapOffer (GetOfferRequest) returns (GetBsqSwapOfferReply) {
|
||||||
}
|
}
|
||||||
rpc GetOffer (GetOfferRequest) returns (GetOfferReply) {
|
rpc GetOffer (GetOfferRequest) returns (GetOfferReply) {
|
||||||
|
@ -70,11 +72,11 @@ service Offers {
|
||||||
}
|
}
|
||||||
rpc GetMyOffer (GetMyOfferRequest) returns (GetMyOfferReply) {
|
rpc GetMyOffer (GetMyOfferRequest) returns (GetMyOfferReply) {
|
||||||
}
|
}
|
||||||
rpc GetBsqSwapOffers (GetOffersRequest) returns (GetBsqSwapOffersReply) {
|
rpc GetBsqSwapOffers (GetBsqSwapOffersRequest) returns (GetBsqSwapOffersReply) {
|
||||||
}
|
}
|
||||||
rpc GetOffers (GetOffersRequest) returns (GetOffersReply) {
|
rpc GetOffers (GetOffersRequest) returns (GetOffersReply) {
|
||||||
}
|
}
|
||||||
rpc GetMyBsqSwapOffers (GetMyOffersRequest) returns (GetMyBsqSwapOffersReply) {
|
rpc GetMyBsqSwapOffers (GetBsqSwapOffersRequest) returns (GetMyBsqSwapOffersReply) {
|
||||||
}
|
}
|
||||||
rpc GetMyOffers (GetMyOffersRequest) returns (GetMyOffersReply) {
|
rpc GetMyOffers (GetMyOffersRequest) returns (GetMyOffersReply) {
|
||||||
}
|
}
|
||||||
|
@ -88,8 +90,23 @@ service Offers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GetOfferCategoryRequest {
|
||||||
|
string id = 1;
|
||||||
|
bool isMyOffer = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetOfferCategoryReply {
|
||||||
|
enum OfferCategory {
|
||||||
|
UNKNOWN = 0;
|
||||||
|
FIAT = 1;
|
||||||
|
ALTCOIN = 2;
|
||||||
|
BSQ_SWAP = 3;
|
||||||
|
}
|
||||||
|
OfferCategory offerCategory = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message GetBsqSwapOfferReply {
|
message GetBsqSwapOfferReply {
|
||||||
BsqSwapOfferInfo bsqSwapOffer = 1;
|
OfferInfo bsqSwapOffer = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetOfferRequest {
|
message GetOfferRequest {
|
||||||
|
@ -101,7 +118,7 @@ message GetOfferReply {
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetMyBsqSwapOfferReply {
|
message GetMyBsqSwapOfferReply {
|
||||||
BsqSwapOfferInfo bsqSwapOffer = 1;
|
OfferInfo bsqSwapOffer = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetMyOfferRequest {
|
message GetMyOfferRequest {
|
||||||
|
@ -121,8 +138,12 @@ message GetOffersReply {
|
||||||
repeated OfferInfo offers = 1;
|
repeated OfferInfo offers = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GetBsqSwapOffersRequest {
|
||||||
|
string direction = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message GetBsqSwapOffersReply {
|
message GetBsqSwapOffersReply {
|
||||||
repeated BsqSwapOfferInfo bsqSwapOffers = 1;
|
repeated OfferInfo bsqSwapOffers = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetMyOffersRequest {
|
message GetMyOffersRequest {
|
||||||
|
@ -135,7 +156,7 @@ message GetMyOffersReply {
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetMyBsqSwapOffersReply {
|
message GetMyBsqSwapOffersReply {
|
||||||
repeated BsqSwapOfferInfo bsqSwapOffers = 1;
|
repeated OfferInfo bsqSwapOffers = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateBsqSwapOfferRequest {
|
message CreateBsqSwapOfferRequest {
|
||||||
|
@ -143,11 +164,10 @@ message CreateBsqSwapOfferRequest {
|
||||||
uint64 amount = 2;
|
uint64 amount = 2;
|
||||||
uint64 minAmount = 3;
|
uint64 minAmount = 3;
|
||||||
string price = 4;
|
string price = 4;
|
||||||
string paymentAccountId = 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateBsqSwapOfferReply {
|
message CreateBsqSwapOfferReply {
|
||||||
BsqSwapOfferInfo bsqSwapOffer = 1;
|
OfferInfo bsqSwapOffer = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateOfferRequest {
|
message CreateOfferRequest {
|
||||||
|
@ -204,25 +224,6 @@ message CancelOfferRequest {
|
||||||
message CancelOfferReply {
|
message CancelOfferReply {
|
||||||
}
|
}
|
||||||
|
|
||||||
message BsqSwapOfferInfo {
|
|
||||||
string id = 1;
|
|
||||||
string direction = 2;
|
|
||||||
uint64 amount = 3;
|
|
||||||
uint64 minAmount = 4;
|
|
||||||
uint64 price = 5;
|
|
||||||
string makerPaymentAccountId = 6;
|
|
||||||
string paymentMethodId = 7;
|
|
||||||
string paymentMethodShortName = 8;
|
|
||||||
string baseCurrencyCode = 9;
|
|
||||||
string counterCurrencyCode = 10;
|
|
||||||
uint64 getMakerFee = 11;
|
|
||||||
uint64 date = 12;
|
|
||||||
string ownerNodeAddress = 13;
|
|
||||||
string pubKeyRing = 14;
|
|
||||||
string versionNr = 15;
|
|
||||||
int32 protocolVersion = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
message OfferInfo {
|
message OfferInfo {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
string direction = 2;
|
string direction = 2;
|
||||||
|
@ -250,6 +251,11 @@ message OfferInfo {
|
||||||
bool isActivated = 24;
|
bool isActivated = 24;
|
||||||
bool isMyOffer = 25;
|
bool isMyOffer = 25;
|
||||||
bool isMyPendingOffer = 26;
|
bool isMyPendingOffer = 26;
|
||||||
|
bool isBsqSwapOffer = 27;
|
||||||
|
string ownerNodeAddress = 28;
|
||||||
|
string pubKeyRing = 29;
|
||||||
|
string versionNr = 30;
|
||||||
|
int32 protocolVersion = 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AvailabilityResultWithDescription {
|
message AvailabilityResultWithDescription {
|
||||||
|
@ -377,12 +383,8 @@ message StopReply {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
service Trades {
|
service Trades {
|
||||||
rpc GetBsqSwapTrade (GetTradeRequest) returns (GetBsqSwapTradeReply) {
|
|
||||||
}
|
|
||||||
rpc GetTrade (GetTradeRequest) returns (GetTradeReply) {
|
rpc GetTrade (GetTradeRequest) returns (GetTradeReply) {
|
||||||
}
|
}
|
||||||
rpc TakeBsqSwapOffer (TakeBsqSwapOfferRequest) returns (TakeBsqSwapOfferReply) {
|
|
||||||
}
|
|
||||||
rpc TakeOffer (TakeOfferRequest) returns (TakeOfferReply) {
|
rpc TakeOffer (TakeOfferRequest) returns (TakeOfferReply) {
|
||||||
}
|
}
|
||||||
rpc ConfirmPaymentStarted (ConfirmPaymentStartedRequest) returns (ConfirmPaymentStartedReply) {
|
rpc ConfirmPaymentStarted (ConfirmPaymentStartedRequest) returns (ConfirmPaymentStartedReply) {
|
||||||
|
@ -395,17 +397,6 @@ service Trades {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message TakeBsqSwapOfferRequest {
|
|
||||||
string offerId = 1;
|
|
||||||
string paymentAccountId = 2;
|
|
||||||
string takerFeeCurrencyCode = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TakeBsqSwapOfferReply {
|
|
||||||
BsqSwapTradeInfo bsqSwapTrade = 1;
|
|
||||||
AvailabilityResultWithDescription failureReason = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TakeOfferRequest {
|
message TakeOfferRequest {
|
||||||
string offerId = 1;
|
string offerId = 1;
|
||||||
string paymentAccountId = 2;
|
string paymentAccountId = 2;
|
||||||
|
@ -431,10 +422,6 @@ message ConfirmPaymentReceivedRequest {
|
||||||
message ConfirmPaymentReceivedReply {
|
message ConfirmPaymentReceivedReply {
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetBsqSwapTradeReply {
|
|
||||||
BsqSwapTradeInfo bsqSwapTrade = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetTradeRequest {
|
message GetTradeRequest {
|
||||||
string tradeId = 1;
|
string tradeId = 1;
|
||||||
}
|
}
|
||||||
|
@ -459,37 +446,8 @@ message WithdrawFundsRequest {
|
||||||
message WithdrawFundsReply {
|
message WithdrawFundsReply {
|
||||||
}
|
}
|
||||||
|
|
||||||
message BsqSwapTradeInfo {
|
|
||||||
BsqSwapOfferInfo bsqSwapOfferInfo = 1;
|
|
||||||
string tradeId = 2;
|
|
||||||
string tempTradingPeerNodeAddress = 3;
|
|
||||||
string peerNodeAddress = 4;
|
|
||||||
string txId = 5;
|
|
||||||
uint64 bsqTradeAmount = 6;
|
|
||||||
uint64 bsqMaxTradeAmount = 7;
|
|
||||||
uint64 bsqMinTradeAmount = 8;
|
|
||||||
uint64 btcTradeAmount = 9;
|
|
||||||
uint64 btcMaxTradeAmount = 10;
|
|
||||||
uint64 btcMinTradeAmount = 11;
|
|
||||||
uint64 tradePrice = 12;
|
|
||||||
bool isCurrencyForMakerFeeBtc = 13;
|
|
||||||
bool isCurrencyForTakerFeeBtc = 14;
|
|
||||||
uint64 bsqMakerTradeFee = 15;
|
|
||||||
uint64 btcMakerTradeFee = 16;
|
|
||||||
uint64 bsqTakerTradeFee = 17;
|
|
||||||
uint64 btcTakerTradeFee = 18;
|
|
||||||
uint64 txFeePerVbyte = 19;
|
|
||||||
uint64 txFee = 20;
|
|
||||||
string makerBsqAddress = 21;
|
|
||||||
string makerBtcAddress = 22;
|
|
||||||
string takerBsqAddress = 23;
|
|
||||||
string takerBtcAddress = 24;
|
|
||||||
uint64 takeOfferDate = 25;
|
|
||||||
string state = 26;
|
|
||||||
string errorMessage = 27;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TradeInfo {
|
message TradeInfo {
|
||||||
|
// Bisq v1 trade protocol fields.
|
||||||
OfferInfo offer = 1;
|
OfferInfo offer = 1;
|
||||||
string tradeId = 2;
|
string tradeId = 2;
|
||||||
string shortId = 3;
|
string shortId = 3;
|
||||||
|
@ -516,6 +474,8 @@ message TradeInfo {
|
||||||
string contractAsJson = 24;
|
string contractAsJson = 24;
|
||||||
ContractInfo contract = 25;
|
ContractInfo contract = 25;
|
||||||
uint64 tradeVolume = 26;
|
uint64 tradeVolume = 26;
|
||||||
|
// Optional Bisq v2+ trade protocol fields.
|
||||||
|
BsqSwapTradeInfo bsqSwapTradeInfo = 28;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ContractInfo {
|
message ContractInfo {
|
||||||
|
@ -533,6 +493,22 @@ message ContractInfo {
|
||||||
uint64 lockTime = 12;
|
uint64 lockTime = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message BsqSwapTradeInfo {
|
||||||
|
// BSQ Swap protocol specific fields not common to Bisq v1 trade protocol fields.
|
||||||
|
string txId = 1;
|
||||||
|
uint64 bsqTradeAmount = 2;
|
||||||
|
uint64 btcTradeAmount = 3;
|
||||||
|
uint64 bsqMakerTradeFee = 4;
|
||||||
|
uint64 bsqTakerTradeFee = 5;
|
||||||
|
uint64 txFeePerVbyte = 6;
|
||||||
|
string makerBsqAddress = 7;
|
||||||
|
string makerBtcAddress = 8;
|
||||||
|
string takerBsqAddress = 9;
|
||||||
|
string takerBtcAddress = 10;
|
||||||
|
uint64 numConfirmations = 11;
|
||||||
|
string errorMessage = 12;
|
||||||
|
}
|
||||||
|
|
||||||
message PaymentAccountPayloadInfo {
|
message PaymentAccountPayloadInfo {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
string paymentMethodId = 2;
|
string paymentMethodId = 2;
|
||||||
|
|
Loading…
Add table
Reference in a new issue