diff --git a/apitest/src/test/java/bisq/apitest/method/MethodTest.java b/apitest/src/test/java/bisq/apitest/method/MethodTest.java index a90e9cd06c..f4fd94b517 100644 --- a/apitest/src/test/java/bisq/apitest/method/MethodTest.java +++ b/apitest/src/test/java/bisq/apitest/method/MethodTest.java @@ -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) { diff --git a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java index cd9a5771a8..530675f181 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java @@ -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 getOffersSortedByDate(GrpcStubs grpcStubs, String direction, String currencyCode) { + protected final List 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 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 sortOffersByDate(List offerInfoList) { return offerInfoList.stream() .sorted(comparing(OfferInfo::getDate)) diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java index 8ec90aedad..9be112e16b 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java @@ -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 offers = getOffersSortedByDate(aliceStubs, "buy", "cad"); + List 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()); } } diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java index daa85d5e8e..8f43660914 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java @@ -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()); diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java index dbf712c935..30dfaca4ac 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java @@ -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()); diff --git a/apitest/src/test/java/bisq/apitest/method/offer/ValidateCreateOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/ValidateCreateOfferTest.java index 0225238b6a..14b935abe4 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/ValidateCreateOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/ValidateCreateOfferTest.java @@ -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") diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java index 51c80392bf..9fc3acbb47 100644 --- a/cli/src/main/java/bisq/cli/CliMain.java +++ b/cli/src/main/java/bisq/cli/CliMain.java @@ -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 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"); diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java index 4dffaee976..6c57f20c7f 100644 --- a/core/src/main/java/bisq/core/api/CoreApi.java +++ b/core/src/main/java/bisq/core/api/CoreApi.java @@ -108,10 +108,18 @@ public class CoreApi { return coreOffersService.getOffer(id); } + public Offer getMyOffer(String id) { + return coreOffersService.getMyOffer(id); + } + public List getOffers(String direction, String currencyCode) { return coreOffersService.getOffers(direction, currencyCode); } + public List getMyOffers(String direction, String currencyCode) { + return coreOffersService.getMyOffers(direction, currencyCode); + } + public void createAnPlaceOffer(String currencyCode, String directionAsString, String priceAsString, diff --git a/core/src/main/java/bisq/core/api/CoreOffersService.java b/core/src/main/java/bisq/core/api/CoreOffersService.java index 0764d33f07..5b04d8c858 100644 --- a/core/src/main/java/bisq/core/api/CoreOffersService.java +++ b/core/src/main/java/bisq/core/api/CoreOffersService.java @@ -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 getOffers(String direction, String currencyCode) { List 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 getMyOffers(String direction, String currencyCode) { + List 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 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(); diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java index 9b6690864f..e92d05863f 100644 --- a/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java +++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java @@ -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 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 responseObserver) { @@ -88,6 +107,25 @@ class GrpcOffersService extends OffersGrpc.OffersImplBase { } } + @Override + public void getMyOffers(GetMyOffersRequest req, + StreamObserver responseObserver) { + try { + List 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 responseObserver) { diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index df37f08fd8..b2532d8b48 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -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;