Add new api methods 'getmyoffers' and 'getmyoffer'

Similar to 'getoffers' and 'getoffer', but filters out offers not
created by the user.  The new methods are so similar some offer list
filtering and sorting was refactored in CoreOffersService.

Also fixed some createoffer apitest cases in anticipation of a new OfferFilter,
which will filter out offers not matching any user payment account.
This commit is contained in:
ghubstan 2021-01-04 21:43:34 -03:00
parent 6fc9ad4c9b
commit 18de222d38
No known key found for this signature in database
GPG Key ID: E35592D6800A861E
11 changed files with 272 additions and 72 deletions

View File

@ -19,6 +19,7 @@ package bisq.apitest.method;
import bisq.core.api.model.PaymentAccountForm;
import bisq.core.api.model.TxFeeRateInfo;
import bisq.core.payment.F2FAccount;
import bisq.core.proto.CoreProtoResolver;
import bisq.common.util.Utilities;
@ -34,6 +35,7 @@ import bisq.proto.grpc.CreatePaymentAccountRequest;
import bisq.proto.grpc.GetAddressBalanceRequest;
import bisq.proto.grpc.GetBalancesRequest;
import bisq.proto.grpc.GetFundingAddressesRequest;
import bisq.proto.grpc.GetMyOfferRequest;
import bisq.proto.grpc.GetOfferRequest;
import bisq.proto.grpc.GetPaymentAccountFormRequest;
import bisq.proto.grpc.GetPaymentAccountsRequest;
@ -134,8 +136,8 @@ public class MethodTest extends ApiTestCase {
}
protected static void doPostStartup(boolean registerDisputeAgents,
boolean generateBtcBlock,
Enum<?>... supportingApps) {
boolean generateBtcBlock,
Enum<?>... supportingApps) {
if (registerDisputeAgents) {
registerDisputeAgents(arbdaemon);
}
@ -223,6 +225,10 @@ public class MethodTest extends ApiTestCase {
return GetOfferRequest.newBuilder().setId(offerId).build();
}
protected final GetMyOfferRequest createGetMyOfferRequest(String offerId) {
return GetMyOfferRequest.newBuilder().setId(offerId).build();
}
protected final CancelOfferRequest createCancelOfferRequest(String offerId) {
return CancelOfferRequest.newBuilder().setId(offerId).build();
}
@ -401,6 +407,11 @@ public class MethodTest extends ApiTestCase {
return grpcStubs(bisqAppConfig).offersService.getOffer(req).getOffer();
}
protected final OfferInfo getMyOffer(BisqAppConfig bisqAppConfig, String offerId) {
var req = createGetMyOfferRequest(offerId);
return grpcStubs(bisqAppConfig).offersService.getMyOffer(req).getOffer();
}
@SuppressWarnings("ResultOfMethodCallIgnored")
protected final void cancelOffer(BisqAppConfig bisqAppConfig, String offerId) {
var req = createCancelOfferRequest(offerId);
@ -464,6 +475,21 @@ public class MethodTest extends ApiTestCase {
return grpcStubs(bisqAppConfig).walletsService.getTransaction(req).getTxInfo();
}
public bisq.core.payment.PaymentAccount createDummyF2FAccount(BisqAppConfig bisqAppConfig,
String countryCode) {
String f2fAccountJsonString = "{\n" +
" \"_COMMENTS_\": \"This is a dummy account.\",\n" +
" \"paymentMethodId\": \"F2F\",\n" +
" \"accountName\": \"Dummy " + countryCode.toUpperCase() + " F2F Account\",\n" +
" \"city\": \"Anytown\",\n" +
" \"contact\": \"Morse Code\",\n" +
" \"country\": \"" + countryCode.toUpperCase() + "\",\n" +
" \"extraInfo\": \"Salt Lick #213\"\n" +
"}\n";
F2FAccount f2FAccount = (F2FAccount) createPaymentAccount(bisqAppConfig, f2fAccountJsonString);
return f2FAccount;
}
// Static conveniences for test methods and test case fixture setups.
protected static RegisterDisputeAgentRequest createRegisterDisputeAgentRequest(String disputeAgentType) {

View File

@ -20,6 +20,7 @@ package bisq.apitest.method.offer;
import bisq.core.monetary.Altcoin;
import bisq.proto.grpc.CreateOfferRequest;
import bisq.proto.grpc.GetMyOffersRequest;
import bisq.proto.grpc.GetOffersRequest;
import bisq.proto.grpc.OfferInfo;
@ -121,6 +122,10 @@ public abstract class AbstractOfferTest extends MethodTest {
return aliceStubs.offersService.getOffer(createGetOfferRequest(offerId)).getOffer();
}
protected final OfferInfo getMyOffer(String offerId) {
return aliceStubs.offersService.getMyOffer(createGetMyOfferRequest(offerId)).getOffer();
}
@SuppressWarnings("ResultOfMethodCallIgnored")
protected final void cancelOffer(GrpcStubs grpcStubs, String offerId) {
grpcStubs.offersService.cancelOffer(createCancelOfferRequest(offerId));
@ -138,7 +143,9 @@ public abstract class AbstractOfferTest extends MethodTest {
return getOffersSortedByDate(grpcStubs, direction, currencyCode).size();
}
protected final List<OfferInfo> getOffersSortedByDate(GrpcStubs grpcStubs, String direction, String currencyCode) {
protected final List<OfferInfo> getOffersSortedByDate(GrpcStubs grpcStubs,
String direction,
String currencyCode) {
var req = GetOffersRequest.newBuilder()
.setDirection(direction)
.setCurrencyCode(currencyCode).build();
@ -146,6 +153,16 @@ public abstract class AbstractOfferTest extends MethodTest {
return sortOffersByDate(reply.getOffersList());
}
protected final List<OfferInfo> getMyOffersSortedByDate(GrpcStubs grpcStubs,
String direction,
String currencyCode) {
var req = GetMyOffersRequest.newBuilder()
.setDirection(direction)
.setCurrencyCode(currencyCode).build();
var reply = grpcStubs.offersService.getMyOffers(req);
return sortOffersByDate(reply.getOffersList());
}
protected final List<OfferInfo> sortOffersByDate(List<OfferInfo> offerInfoList) {
return offerInfoList.stream()
.sorted(comparing(OfferInfo::getDate))

View File

@ -18,6 +18,7 @@
package bisq.apitest.method.offer;
import bisq.core.btc.wallet.Restrictions;
import bisq.core.payment.PaymentAccount;
import bisq.proto.grpc.CreateOfferRequest;
import bisq.proto.grpc.OfferInfo;
@ -32,6 +33,7 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static org.junit.jupiter.api.Assertions.assertEquals;
@Disabled
@ -39,15 +41,18 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class CancelOfferTest extends AbstractOfferTest {
private static final String DIRECTION = "buy";
private static final String CURRENCY_CODE = "cad";
private static final int MAX_OFFERS = 3;
@Test
@Order(1)
public void testCancelOffer() {
PaymentAccount cadAccount = createDummyF2FAccount(alicedaemon, "CA");
var req = CreateOfferRequest.newBuilder()
.setPaymentAccountId(alicesDummyAcct.getId())
.setDirection("buy")
.setCurrencyCode("cad")
.setPaymentAccountId(cadAccount.getId())
.setDirection(DIRECTION)
.setCurrencyCode(CURRENCY_CODE)
.setAmount(10000000)
.setMinAmount(10000000)
.setUseMarketBasedPrice(true)
@ -66,18 +71,19 @@ public class CancelOfferTest extends AbstractOfferTest {
sleep(2500);
}
List<OfferInfo> offers = getOffersSortedByDate(aliceStubs, "buy", "cad");
List<OfferInfo> offers = getMyOffersSortedByDate(aliceStubs, DIRECTION, CURRENCY_CODE);
assertEquals(MAX_OFFERS, offers.size());
// Cancel the offers, checking the open offer count after each offer removal.
for (int i = 1; i <= MAX_OFFERS; i++) {
cancelOffer(aliceStubs, offers.remove(0).getId());
assertEquals(MAX_OFFERS - i, getOpenOffersCount(aliceStubs, "buy", "cad"));
offers = getMyOffersSortedByDate(aliceStubs, DIRECTION, CURRENCY_CODE);
assertEquals(MAX_OFFERS - i, offers.size());
}
sleep(1000); // wait for offer removal
offers = getOffersSortedByDate(aliceStubs, "buy", "cad");
offers = getMyOffersSortedByDate(aliceStubs, DIRECTION, CURRENCY_CODE);
assertEquals(0, offers.size());
}
}

View File

@ -17,7 +17,7 @@
package bisq.apitest.method.offer;
import bisq.core.btc.wallet.Restrictions;
import bisq.core.payment.PaymentAccount;
import bisq.proto.grpc.CreateOfferRequest;
@ -29,6 +29,8 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
@ -43,16 +45,17 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
@Test
@Order(1)
public void testCreateAUDBTCBuyOfferUsingFixedPrice16000() {
PaymentAccount audAccount = createDummyF2FAccount(alicedaemon, "AU");
var req = CreateOfferRequest.newBuilder()
.setPaymentAccountId(alicesDummyAcct.getId())
.setPaymentAccountId(audAccount.getId())
.setDirection("buy")
.setCurrencyCode("aud")
.setAmount(10000000)
.setMinAmount(10000000)
.setUseMarketBasedPrice(false)
.setMarketPriceMargin(0.00)
.setPrice("16000")
.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent())
.setPrice("36000")
.setBuyerSecurityDeposit(getDefaultBuyerSecurityDepositAsPercent())
.setMakerFeeCurrencyCode(MAKER_FEE_CURRENCY_CODE)
.build();
var newOffer = aliceStubs.offersService.createOffer(req).getOffer();
@ -60,24 +63,24 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
assertNotEquals("", newOfferId);
assertEquals("BUY", newOffer.getDirection());
assertFalse(newOffer.getUseMarketBasedPrice());
assertEquals(160000000, newOffer.getPrice());
assertEquals(360000000, newOffer.getPrice());
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(audAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("AUD", newOffer.getCounterCurrencyCode());
assertFalse(newOffer.getIsCurrencyForMakerFeeBtc());
newOffer = getOffer(newOfferId);
newOffer = getMyOffer(newOfferId);
assertEquals(newOfferId, newOffer.getId());
assertEquals("BUY", newOffer.getDirection());
assertFalse(newOffer.getUseMarketBasedPrice());
assertEquals(160000000, newOffer.getPrice());
assertEquals(360000000, newOffer.getPrice());
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(audAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("AUD", newOffer.getCounterCurrencyCode());
assertFalse(newOffer.getIsCurrencyForMakerFeeBtc());
@ -86,16 +89,17 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
@Test
@Order(2)
public void testCreateUSDBTCBuyOfferUsingFixedPrice100001234() {
PaymentAccount usdAccount = createDummyF2FAccount(alicedaemon, "US");
var req = CreateOfferRequest.newBuilder()
.setPaymentAccountId(alicesDummyAcct.getId())
.setPaymentAccountId(usdAccount.getId())
.setDirection("buy")
.setCurrencyCode("usd")
.setAmount(10000000)
.setMinAmount(10000000)
.setUseMarketBasedPrice(false)
.setMarketPriceMargin(0.00)
.setPrice("10000.1234")
.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent())
.setPrice("30000.1234")
.setBuyerSecurityDeposit(getDefaultBuyerSecurityDepositAsPercent())
.setMakerFeeCurrencyCode(MAKER_FEE_CURRENCY_CODE)
.build();
var newOffer = aliceStubs.offersService.createOffer(req).getOffer();
@ -103,24 +107,24 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
assertNotEquals("", newOfferId);
assertEquals("BUY", newOffer.getDirection());
assertFalse(newOffer.getUseMarketBasedPrice());
assertEquals(100001234, newOffer.getPrice());
assertEquals(300001234, newOffer.getPrice());
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("USD", newOffer.getCounterCurrencyCode());
assertFalse(newOffer.getIsCurrencyForMakerFeeBtc());
newOffer = getOffer(newOfferId);
newOffer = getMyOffer(newOfferId);
assertEquals(newOfferId, newOffer.getId());
assertEquals("BUY", newOffer.getDirection());
assertFalse(newOffer.getUseMarketBasedPrice());
assertEquals(100001234, newOffer.getPrice());
assertEquals(300001234, newOffer.getPrice());
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("USD", newOffer.getCounterCurrencyCode());
assertFalse(newOffer.getIsCurrencyForMakerFeeBtc());
@ -129,16 +133,17 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
@Test
@Order(3)
public void testCreateEURBTCSellOfferUsingFixedPrice95001234() {
PaymentAccount eurAccount = createDummyF2FAccount(alicedaemon, "FR");
var req = CreateOfferRequest.newBuilder()
.setPaymentAccountId(alicesDummyAcct.getId())
.setPaymentAccountId(eurAccount.getId())
.setDirection("sell")
.setCurrencyCode("eur")
.setAmount(10000000)
.setMinAmount(10000000)
.setUseMarketBasedPrice(false)
.setMarketPriceMargin(0.00)
.setPrice("9500.1234")
.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent())
.setPrice("29500.1234")
.setBuyerSecurityDeposit(getDefaultBuyerSecurityDepositAsPercent())
.setMakerFeeCurrencyCode(MAKER_FEE_CURRENCY_CODE)
.build();
var newOffer = aliceStubs.offersService.createOffer(req).getOffer();
@ -146,24 +151,24 @@ public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
assertNotEquals("", newOfferId);
assertEquals("SELL", newOffer.getDirection());
assertFalse(newOffer.getUseMarketBasedPrice());
assertEquals(95001234, newOffer.getPrice());
assertEquals(295001234, newOffer.getPrice());
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(eurAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("EUR", newOffer.getCounterCurrencyCode());
assertFalse(newOffer.getIsCurrencyForMakerFeeBtc());
newOffer = getOffer(newOfferId);
newOffer = getMyOffer(newOfferId);
assertEquals(newOfferId, newOffer.getId());
assertEquals("SELL", newOffer.getDirection());
assertFalse(newOffer.getUseMarketBasedPrice());
assertEquals(95001234, newOffer.getPrice());
assertEquals(295001234, newOffer.getPrice());
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(eurAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("EUR", newOffer.getCounterCurrencyCode());
assertFalse(newOffer.getIsCurrencyForMakerFeeBtc());

View File

@ -17,7 +17,7 @@
package bisq.apitest.method.offer;
import bisq.core.btc.wallet.Restrictions;
import bisq.core.payment.PaymentAccount;
import bisq.proto.grpc.CreateOfferRequest;
import bisq.proto.grpc.OfferInfo;
@ -32,8 +32,10 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.common.util.MathUtils.scaleDownByPowerOf10;
import static bisq.common.util.MathUtils.scaleUpByPowerOf10;
import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent;
import static java.lang.Math.abs;
import static java.lang.String.format;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -55,9 +57,10 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
@Test
@Order(1)
public void testCreateUSDBTCBuyOffer5PctPriceMargin() {
PaymentAccount usdAccount = createDummyF2FAccount(alicedaemon, "US");
double priceMarginPctInput = 5.00;
var req = CreateOfferRequest.newBuilder()
.setPaymentAccountId(alicesDummyAcct.getId())
.setPaymentAccountId(usdAccount.getId())
.setDirection("buy")
.setCurrencyCode("usd")
.setAmount(10000000)
@ -65,7 +68,7 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
.setUseMarketBasedPrice(true)
.setMarketPriceMargin(priceMarginPctInput)
.setPrice("0")
.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent())
.setBuyerSecurityDeposit(getDefaultBuyerSecurityDepositAsPercent())
.setMakerFeeCurrencyCode(MAKER_FEE_CURRENCY_CODE)
.build();
var newOffer = aliceStubs.offersService.createOffer(req).getOffer();
@ -76,19 +79,19 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("USD", newOffer.getCounterCurrencyCode());
assertTrue(newOffer.getIsCurrencyForMakerFeeBtc());
newOffer = getOffer(newOfferId);
newOffer = getMyOffer(newOfferId);
assertEquals(newOfferId, newOffer.getId());
assertEquals("BUY", newOffer.getDirection());
assertTrue(newOffer.getUseMarketBasedPrice());
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("USD", newOffer.getCounterCurrencyCode());
assertTrue(newOffer.getIsCurrencyForMakerFeeBtc());
@ -99,9 +102,10 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
@Test
@Order(2)
public void testCreateNZDBTCBuyOfferMinus2PctPriceMargin() {
PaymentAccount nzdAccount = createDummyF2FAccount(alicedaemon, "NZ");
double priceMarginPctInput = -2.00;
var req = CreateOfferRequest.newBuilder()
.setPaymentAccountId(alicesDummyAcct.getId())
.setPaymentAccountId(nzdAccount.getId())
.setDirection("buy")
.setCurrencyCode("nzd")
.setAmount(10000000)
@ -109,7 +113,7 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
.setUseMarketBasedPrice(true)
.setMarketPriceMargin(priceMarginPctInput)
.setPrice("0")
.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent())
.setBuyerSecurityDeposit(getDefaultBuyerSecurityDepositAsPercent())
.setMakerFeeCurrencyCode(MAKER_FEE_CURRENCY_CODE)
.build();
var newOffer = aliceStubs.offersService.createOffer(req).getOffer();
@ -120,19 +124,19 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(nzdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("NZD", newOffer.getCounterCurrencyCode());
assertTrue(newOffer.getIsCurrencyForMakerFeeBtc());
newOffer = getOffer(newOfferId);
newOffer = getMyOffer(newOfferId);
assertEquals(newOfferId, newOffer.getId());
assertEquals("BUY", newOffer.getDirection());
assertTrue(newOffer.getUseMarketBasedPrice());
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(nzdAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("NZD", newOffer.getCounterCurrencyCode());
assertTrue(newOffer.getIsCurrencyForMakerFeeBtc());
@ -143,9 +147,10 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
@Test
@Order(3)
public void testCreateGBPBTCSellOfferMinus1Point5PctPriceMargin() {
PaymentAccount gbpAccount = createDummyF2FAccount(alicedaemon, "GB");
double priceMarginPctInput = -1.5;
var req = CreateOfferRequest.newBuilder()
.setPaymentAccountId(alicesDummyAcct.getId())
.setPaymentAccountId(gbpAccount.getId())
.setDirection("sell")
.setCurrencyCode("gbp")
.setAmount(10000000)
@ -153,7 +158,7 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
.setUseMarketBasedPrice(true)
.setMarketPriceMargin(priceMarginPctInput)
.setPrice("0")
.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent())
.setBuyerSecurityDeposit(getDefaultBuyerSecurityDepositAsPercent())
.setMakerFeeCurrencyCode(MAKER_FEE_CURRENCY_CODE)
.build();
var newOffer = aliceStubs.offersService.createOffer(req).getOffer();
@ -165,19 +170,19 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(gbpAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("GBP", newOffer.getCounterCurrencyCode());
assertTrue(newOffer.getIsCurrencyForMakerFeeBtc());
newOffer = getOffer(newOfferId);
newOffer = getMyOffer(newOfferId);
assertEquals(newOfferId, newOffer.getId());
assertEquals("SELL", newOffer.getDirection());
assertTrue(newOffer.getUseMarketBasedPrice());
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(gbpAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("GBP", newOffer.getCounterCurrencyCode());
assertTrue(newOffer.getIsCurrencyForMakerFeeBtc());
@ -188,9 +193,10 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
@Test
@Order(4)
public void testCreateBRLBTCSellOffer6Point55PctPriceMargin() {
PaymentAccount brlAccount = createDummyF2FAccount(alicedaemon, "BR");
double priceMarginPctInput = 6.55;
var req = CreateOfferRequest.newBuilder()
.setPaymentAccountId(alicesDummyAcct.getId())
.setPaymentAccountId(brlAccount.getId())
.setDirection("sell")
.setCurrencyCode("brl")
.setAmount(10000000)
@ -198,7 +204,7 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
.setUseMarketBasedPrice(true)
.setMarketPriceMargin(priceMarginPctInput)
.setPrice("0")
.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent())
.setBuyerSecurityDeposit(getDefaultBuyerSecurityDepositAsPercent())
.setMakerFeeCurrencyCode(MAKER_FEE_CURRENCY_CODE)
.build();
var newOffer = aliceStubs.offersService.createOffer(req).getOffer();
@ -210,19 +216,19 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(brlAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("BRL", newOffer.getCounterCurrencyCode());
assertTrue(newOffer.getIsCurrencyForMakerFeeBtc());
newOffer = getOffer(newOfferId);
newOffer = getMyOffer(newOfferId);
assertEquals(newOfferId, newOffer.getId());
assertEquals("SELL", newOffer.getDirection());
assertTrue(newOffer.getUseMarketBasedPrice());
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals(brlAccount.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("BRL", newOffer.getCounterCurrencyCode());
assertTrue(newOffer.getIsCurrencyForMakerFeeBtc());

View File

@ -17,7 +17,7 @@
package bisq.apitest.method.offer;
import bisq.core.btc.wallet.Restrictions;
import bisq.core.payment.PaymentAccount;
import bisq.proto.grpc.CreateOfferRequest;
@ -31,6 +31,8 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ -42,8 +44,9 @@ public class ValidateCreateOfferTest extends AbstractOfferTest {
@Test
@Order(1)
public void testAmtTooLargeShouldThrowException() {
PaymentAccount usdAccount = createDummyF2FAccount(alicedaemon, "US");
var req = CreateOfferRequest.newBuilder()
.setPaymentAccountId(alicesDummyAcct.getId())
.setPaymentAccountId(usdAccount.getId())
.setDirection("buy")
.setCurrencyCode("usd")
.setAmount(100000000000L)
@ -51,7 +54,7 @@ public class ValidateCreateOfferTest extends AbstractOfferTest {
.setUseMarketBasedPrice(false)
.setMarketPriceMargin(0.00)
.setPrice("10000.0000")
.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent())
.setBuyerSecurityDeposit(getDefaultBuyerSecurityDepositAsPercent())
.setMakerFeeCurrencyCode("bsq")
.build();
@SuppressWarnings("ResultOfMethodCallIgnored")

View File

@ -25,6 +25,8 @@ import bisq.proto.grpc.CreatePaymentAccountRequest;
import bisq.proto.grpc.GetAddressBalanceRequest;
import bisq.proto.grpc.GetBalancesRequest;
import bisq.proto.grpc.GetFundingAddressesRequest;
import bisq.proto.grpc.GetMyOfferRequest;
import bisq.proto.grpc.GetMyOffersRequest;
import bisq.proto.grpc.GetOfferRequest;
import bisq.proto.grpc.GetOffersRequest;
import bisq.proto.grpc.GetPaymentAccountFormRequest;
@ -96,7 +98,9 @@ public class CliMain {
createoffer,
canceloffer,
getoffer,
getmyoffer,
getoffers,
getmyoffers,
takeoffer,
gettrade,
confirmpaymentstarted,
@ -418,6 +422,19 @@ public class CliMain {
reply.getOffer().getCounterCurrencyCode()));
return;
}
case getmyoffer: {
if (nonOptionArgs.size() < 2)
throw new IllegalArgumentException("incorrect parameter count, expecting offer id");
var offerId = nonOptionArgs.get(1);
var request = GetMyOfferRequest.newBuilder()
.setId(offerId)
.build();
var reply = offersService.getMyOffer(request);
out.println(formatOfferTable(singletonList(reply.getOffer()),
reply.getOffer().getCounterCurrencyCode()));
return;
}
case getoffers: {
if (nonOptionArgs.size() < 3)
throw new IllegalArgumentException("incorrect parameter count,"
@ -440,6 +457,28 @@ public class CliMain {
return;
}
case getmyoffers: {
if (nonOptionArgs.size() < 3)
throw new IllegalArgumentException("incorrect parameter count,"
+ " expecting direction (buy|sell), currency code");
var direction = nonOptionArgs.get(1);
var currencyCode = nonOptionArgs.get(2);
var request = GetMyOffersRequest.newBuilder()
.setDirection(direction)
.setCurrencyCode(currencyCode)
.build();
var reply = offersService.getMyOffers(request);
List<OfferInfo> offers = reply.getOffersList();
if (offers.isEmpty())
out.printf("no %s %s offers found%n", direction, currencyCode);
else
out.println(formatOfferTable(reply.getOffersList(), currencyCode));
return;
}
case takeoffer: {
if (nonOptionArgs.size() < 3)
throw new IllegalArgumentException("incorrect parameter count, " +
@ -747,7 +786,9 @@ public class CliMain {
stream.format(rowFormat, "", "[,maker fee currency code = bsq|btc]", "");
stream.format(rowFormat, "canceloffer", "offer id", "Cancel offer with id");
stream.format(rowFormat, "getoffer", "offer id", "Get current offer with id");
stream.format(rowFormat, "getmyoffer", "offer id", "Get my current offer with id");
stream.format(rowFormat, "getoffers", "buy | sell, currency code", "Get current offers");
stream.format(rowFormat, "getmyoffers", "buy | sell, currency code", "Get my current offers");
stream.format(rowFormat, "takeoffer", "offer id [,taker fee currency code = bsq|btc]", "Take offer with id");
stream.format(rowFormat, "gettrade", "trade id [,showcontract = true|false]", "Get trade summary or full contract");
stream.format(rowFormat, "confirmpaymentstarted", "trade id", "Confirm payment started");

View File

@ -108,10 +108,18 @@ public class CoreApi {
return coreOffersService.getOffer(id);
}
public Offer getMyOffer(String id) {
return coreOffersService.getMyOffer(id);
}
public List<Offer> getOffers(String direction, String currencyCode) {
return coreOffersService.getOffers(direction, currencyCode);
}
public List<Offer> getMyOffers(String direction, String currencyCode) {
return coreOffersService.getMyOffers(direction, currencyCode);
}
public void createAnPlaceOffer(String currencyCode,
String directionAsString,
String priceAsString,

View File

@ -27,6 +27,8 @@ import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.PaymentAccount;
import bisq.core.user.User;
import bisq.common.crypto.KeyRing;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.utils.Fiat;
@ -53,6 +55,7 @@ import static java.lang.String.format;
@Slf4j
class CoreOffersService {
private final KeyRing keyRing;
private final CreateOfferService createOfferService;
private final OfferBookService offerBookService;
private final OpenOfferManager openOfferManager;
@ -60,11 +63,13 @@ class CoreOffersService {
private final User user;
@Inject
public CoreOffersService(CreateOfferService createOfferService,
public CoreOffersService(KeyRing keyRing,
CreateOfferService createOfferService,
OfferBookService offerBookService,
OpenOfferManager openOfferManager,
OfferUtil offerUtil,
User user) {
this.keyRing = keyRing;
this.createOfferService = createOfferService;
this.offerBookService = offerBookService;
this.openOfferManager = openOfferManager;
@ -79,23 +84,28 @@ class CoreOffersService {
new IllegalStateException(format("offer with id '%s' not found", id)));
}
Offer getMyOffer(String id) {
return offerBookService.getOffers().stream()
.filter(o -> o.getId().equals(id))
.filter(o -> o.isMyOffer(keyRing))
.findAny().orElseThrow(() ->
new IllegalStateException(format("offer with id '%s' not found", id)));
}
List<Offer> getOffers(String direction, String currencyCode) {
List<Offer> offers = offerBookService.getOffers().stream()
.filter(o -> {
var offerOfWantedDirection = o.getDirection().name().equalsIgnoreCase(direction);
var offerInWantedCurrency = o.getOfferPayload().getCounterCurrencyCode()
.equalsIgnoreCase(currencyCode);
return offerOfWantedDirection && offerInWantedCurrency;
})
.filter(o -> offerMatchesDirectionAndCurrency(o, direction, currencyCode))
.collect(Collectors.toList());
sortOffers(offers, direction);
return offers;
}
// A buyer probably wants to see sell orders in price ascending order.
// A seller probably wants to see buy orders in price descending order.
if (direction.equalsIgnoreCase(BUY.name()))
offers.sort(Comparator.comparing(Offer::getPrice).reversed());
else
offers.sort(Comparator.comparing(Offer::getPrice));
List<Offer> getMyOffers(String direction, String currencyCode) {
List<Offer> offers = offerBookService.getOffers().stream()
.filter(o -> o.isMyOffer(keyRing))
.filter(o -> offerMatchesDirectionAndCurrency(o, direction, currencyCode))
.collect(Collectors.toList());
sortOffers(offers, direction);
return offers;
}
@ -194,6 +204,24 @@ class CoreOffersService {
throw new IllegalStateException(offer.getErrorMessage());
}
private boolean offerMatchesDirectionAndCurrency(Offer offer,
String direction,
String currencyCode) {
var offerOfWantedDirection = offer.getDirection().name().equalsIgnoreCase(direction);
var offerInWantedCurrency = offer.getOfferPayload().getCounterCurrencyCode()
.equalsIgnoreCase(currencyCode);
return offerOfWantedDirection && offerInWantedCurrency;
}
private void sortOffers(List<Offer> offers, String direction) {
// A buyer probably wants to see sell orders in price ascending order.
// A seller probably wants to see buy orders in price descending order.
if (direction.equalsIgnoreCase(BUY.name()))
offers.sort(Comparator.comparing(Offer::getPrice).reversed());
else
offers.sort(Comparator.comparing(Offer::getPrice));
}
private long priceStringToLong(String priceAsString, String currencyCode) {
int precision = isCryptoCurrency(currencyCode) ? Altcoin.SMALLEST_UNIT_EXPONENT : Fiat.SMALLEST_UNIT_EXPONENT;
double priceAsDouble = new BigDecimal(priceAsString).doubleValue();

View File

@ -25,6 +25,10 @@ import bisq.proto.grpc.CancelOfferReply;
import bisq.proto.grpc.CancelOfferRequest;
import bisq.proto.grpc.CreateOfferReply;
import bisq.proto.grpc.CreateOfferRequest;
import bisq.proto.grpc.GetMyOfferReply;
import bisq.proto.grpc.GetMyOfferRequest;
import bisq.proto.grpc.GetMyOffersReply;
import bisq.proto.grpc.GetMyOffersRequest;
import bisq.proto.grpc.GetOfferReply;
import bisq.proto.grpc.GetOfferRequest;
import bisq.proto.grpc.GetOffersReply;
@ -69,6 +73,21 @@ class GrpcOffersService extends OffersGrpc.OffersImplBase {
}
}
@Override
public void getMyOffer(GetMyOfferRequest req,
StreamObserver<GetMyOfferReply> responseObserver) {
try {
Offer offer = coreApi.getMyOffer(req.getId());
var reply = GetMyOfferReply.newBuilder()
.setOffer(toOfferInfo(offer).toProtoMessage())
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} catch (Throwable cause) {
exceptionHandler.handleException(cause, responseObserver);
}
}
@Override
public void getOffers(GetOffersRequest req,
StreamObserver<GetOffersReply> responseObserver) {
@ -88,6 +107,25 @@ class GrpcOffersService extends OffersGrpc.OffersImplBase {
}
}
@Override
public void getMyOffers(GetMyOffersRequest req,
StreamObserver<GetMyOffersReply> responseObserver) {
try {
List<OfferInfo> result = coreApi.getMyOffers(req.getDirection(), req.getCurrencyCode())
.stream().map(OfferInfo::toOfferInfo)
.collect(Collectors.toList());
var reply = GetMyOffersReply.newBuilder()
.addAllOffers(result.stream()
.map(OfferInfo::toProtoMessage)
.collect(Collectors.toList()))
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} catch (Throwable cause) {
exceptionHandler.handleException(cause, responseObserver);
}
}
@Override
public void createOffer(CreateOfferRequest req,
StreamObserver<CreateOfferReply> responseObserver) {

View File

@ -47,8 +47,12 @@ message RegisterDisputeAgentReply {
service Offers {
rpc GetOffer (GetOfferRequest) returns (GetOfferReply) {
}
rpc GetMyOffer (GetMyOfferRequest) returns (GetMyOfferReply) {
}
rpc GetOffers (GetOffersRequest) returns (GetOffersReply) {
}
rpc GetMyOffers (GetMyOffersRequest) returns (GetMyOffersReply) {
}
rpc CreateOffer (CreateOfferRequest) returns (CreateOfferReply) {
}
rpc CancelOffer (CancelOfferRequest) returns (CancelOfferReply) {
@ -62,6 +66,15 @@ message GetOfferRequest {
message GetOfferReply {
OfferInfo offer = 1;
}
message GetMyOfferRequest {
string id = 1;
}
message GetMyOfferReply {
OfferInfo offer = 1;
}
message GetOffersRequest {
string direction = 1;
string currencyCode = 2;
@ -71,6 +84,15 @@ message GetOffersReply {
repeated OfferInfo offers = 1;
}
message GetMyOffersRequest {
string direction = 1;
string currencyCode = 2;
}
message GetMyOffersReply {
repeated OfferInfo offers = 1;
}
message CreateOfferRequest {
string currencyCode = 1;
string direction = 2;