Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Build out 'createoffer' API method #4559

Merged
merged 52 commits into from Oct 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
9132722
Replace hardcoded version with Version.java value
ghubstan Sep 22, 2020
34cfe95
Remove comment
ghubstan Sep 22, 2020
8896372
Move test dispute agent type constants to core
ghubstan Sep 22, 2020
1f307c8
Fix indentation
ghubstan Sep 22, 2020
6a50402
Add simple create payment acct test
ghubstan Sep 22, 2020
1d88d27
Remove final modifiers
ghubstan Sep 22, 2020
c4dd041
Don't use static boilerplate helpers if not necessary
ghubstan Sep 22, 2020
e63a6c5
Remove comment
ghubstan Sep 22, 2020
92f36ed
Add get default payment acct helper
ghubstan Sep 23, 2020
2b68e57
Stub out createoffer method in CLI
ghubstan Sep 23, 2020
3c0c443
Change API's createoffer return value from bool to Offer
ghubstan Sep 23, 2020
70e3be0
Add API CreateOfferTest case
ghubstan Sep 23, 2020
fc1f0ba
Fix imports
ghubstan Sep 23, 2020
d190d09
Fix unnecessary use of fully qualified name
ghubstan Sep 23, 2020
adb175c
Add options helper for handling negative number CLI params
ghubstan Sep 23, 2020
1431a07
Add license comment
ghubstan Sep 23, 2020
d5b8800
Add license comment and btc-string to satoshi converter
ghubstan Sep 23, 2020
c8a7fe4
Print createoffer's reply in the CLI's console
ghubstan Sep 23, 2020
a6048a4
Add comment to empty catch block for codacy
ghubstan Sep 23, 2020
ec9c1b0
Uppercase direction & ccy-code CLI arguments in core
ghubstan Sep 24, 2020
9999c95
Change 'createoffer' argument order
ghubstan Sep 24, 2020
942a6f2
Scale & convert (double) fixed price input to long
ghubstan Sep 24, 2020
6cdbc13
Move 'createoffer' price arg transform to server & test it
ghubstan Sep 24, 2020
96278b9
Push currencyCode.toUpperCase conversion below CoreApi
ghubstan Sep 25, 2020
995af0d
Convert mktPriceMargin to %, make createAndPlaceOffer private
ghubstan Sep 25, 2020
6cf9bbb
Minor createoffer test changes
ghubstan Sep 25, 2020
3b51824
Do not reassign currencyCode parameter
ghubstan Sep 25, 2020
82ce864
Delete trailing spaces from blank line for codacy
ghubstan Sep 25, 2020
2f3e3a3
Add simple mkt-price service & test calculated offer prices
ghubstan Sep 25, 2020
18df1e2
Fix abs(dbl) comparison
ghubstan Sep 25, 2020
92042d7
Remove unused import
ghubstan Sep 25, 2020
de3105a
Add license comment
ghubstan Sep 25, 2020
96abda4
Tidy up create offer using mkt price margin % test
ghubstan Sep 26, 2020
35a77be
Redefine DisputeAgentType REFUNDAGENT as REFUND_AGENT
ghubstan Sep 27, 2020
7053169
Fix asserts
ghubstan Sep 27, 2020
82b7b79
Factor out duplicated OfferInfo wrapping
ghubstan Sep 27, 2020
50d4b9f
Fix 'switch statements should have a default label' codacy problem
ghubstan Sep 27, 2020
d9ece9f
Revert "Fix 'switch statements should have a default label' codacy pr…
ghubstan Sep 27, 2020
f376153
Codacy requires default label in switch
ghubstan Sep 28, 2020
94996a5
Fix tx result handling in GrpcOffersService
ghubstan Sep 28, 2020
fa5c21c
Fix BitcoinCli wrapper create bug
ghubstan Sep 28, 2020
fc94b97
Throw exception to CLI if attempted offer placement fails
ghubstan Sep 28, 2020
cfe22c3
Make task handler's error msg CLI friendly (needs review)
ghubstan Sep 28, 2020
23a677d
Use list.set, not list.remove, list.add
ghubstan Oct 2, 2020
e09b821
Explain use of args clone index (i-1)
ghubstan Oct 2, 2020
628c557
Revert "Make task handler's error msg CLI friendly (needs review)"
ghubstan Oct 2, 2020
631c3f4
Log provenance of Task error on server, but pass only exception msg t…
ghubstan Oct 2, 2020
0332711
Ignore codacy complaint about (dead) default switch labels
ghubstan Oct 2, 2020
f1693a6
Add switch statement break to make codacy happy
ghubstan Oct 2, 2020
c71ad84
Change 'break' to 'return' at end of switch.
ghubstan Oct 2, 2020
723fc8f
Skip over method name in args loop, start at i=1
ghubstan Oct 2, 2020
d3d6d98
Revert all changes since commit d55114e
ghubstan Oct 3, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions apitest/scripts/mainnet-test.sh
Expand Up @@ -45,17 +45,19 @@
}

@test "test getversion call with quoted password" {
load 'version-parser'
run ./bisq-cli --password="xyz" getversion
[ "$status" -eq 0 ]
echo "actual output: $output" >&2
[ "$output" = "1.3.9" ]
[ "$output" = "$CURRENT_VERSION" ]
}

@test "test getversion" {
load 'version-parser'
run ./bisq-cli --password=xyz getversion
[ "$status" -eq 0 ]
echo "actual output: $output" >&2
[ "$output" = "1.3.9" ]
[ "$output" = "$CURRENT_VERSION" ]
}

@test "test setwalletpassword \"a b c\"" {
Expand Down
5 changes: 5 additions & 0 deletions apitest/scripts/version-parser.bash
@@ -0,0 +1,5 @@
#!/bin/bash

# Bats helper script for parsing current version from Version.java.

export CURRENT_VERSION=$(grep "String VERSION =" common/src/main/java/bisq/common/app/Version.java | sed 's/[^0-9.]*//g')
1 change: 1 addition & 0 deletions apitest/src/test/java/bisq/apitest/ApiTestCase.java
Expand Up @@ -87,6 +87,7 @@ public static void setUpScaffold(String[] params)
// delimited app list value, e.g., "bitcoind,seednode,arbdaemon".
scaffold = new Scaffold(params).setUp();
config = scaffold.config;
bitcoinCli = new BitcoinCliHelper((config));
}

public static void tearDownScaffold() {
Expand Down
@@ -0,0 +1,98 @@
/*
* 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.apitest.method;

import bisq.proto.grpc.GetPaymentAccountsRequest;

import protobuf.PaymentAccount;
import protobuf.PerfectMoneyAccountPayload;

import java.util.List;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

import static bisq.apitest.Scaffold.BitcoinCoreApp.bitcoind;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static java.util.Comparator.comparing;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation;


@Slf4j
@TestMethodOrder(OrderAnnotation.class)
public class CreatePaymentAccountTest extends MethodTest {

static final String PERFECT_MONEY_ACCT_NAME = "Perfect Money USD";
static final String PERFECT_MONEY_ACCT_NUMBER = "0123456789";

@BeforeAll
public static void setUp() {
try {
setUpScaffold(bitcoind, alicedaemon);
} catch (Exception ex) {
fail(ex);
}
}

@Test
@Order(1)
public void testCreatePerfectMoneyUSDPaymentAccount() {
var perfectMoneyPaymentAccountRequest = createCreatePerfectMoneyPaymentAccountRequest(
PERFECT_MONEY_ACCT_NAME,
PERFECT_MONEY_ACCT_NUMBER,
"USD");
//noinspection ResultOfMethodCallIgnored
grpcStubs(alicedaemon).paymentAccountsService.createPaymentAccount(perfectMoneyPaymentAccountRequest);

var getPaymentAccountsRequest = GetPaymentAccountsRequest.newBuilder().build();
var reply = grpcStubs(alicedaemon).paymentAccountsService.getPaymentAccounts(getPaymentAccountsRequest);

// The daemon is running against the regtest/dao setup files, and was set up with
// two dummy accounts ("PerfectMoney dummy", "ETH dummy") before any tests ran.
// We just added 1 test account, making 3 total.
assertEquals(3, reply.getPaymentAccountsCount());

// Sort the returned list by creation date; the last item in the sorted
// list will be the payment acct we just created.
List<PaymentAccount> paymentAccountList = reply.getPaymentAccountsList().stream()
.sorted(comparing(PaymentAccount::getCreationDate))
.collect(Collectors.toList());
PaymentAccount paymentAccount = paymentAccountList.get(2);
PerfectMoneyAccountPayload perfectMoneyAccount = paymentAccount
.getPaymentAccountPayload()
.getPerfectMoneyAccountPayload();

assertEquals(PERFECT_MONEY_ACCT_NAME, paymentAccount.getAccountName());
assertEquals("USD",
paymentAccount.getSelectedTradeCurrency().getFiatCurrency().getCurrency().getCurrencyCode());
assertEquals(PERFECT_MONEY_ACCT_NUMBER, perfectMoneyAccount.getAccountNr());
}

@AfterAll
public static void tearDown() {
tearDownScaffold();
}
}
62 changes: 58 additions & 4 deletions apitest/src/test/java/bisq/apitest/method/MethodTest.java
Expand Up @@ -17,15 +17,27 @@

package bisq.apitest.method;

import bisq.proto.grpc.CreatePaymentAccountRequest;
import bisq.proto.grpc.GetBalanceRequest;
import bisq.proto.grpc.GetFundingAddressesRequest;
import bisq.proto.grpc.GetPaymentAccountsRequest;
import bisq.proto.grpc.LockWalletRequest;
import bisq.proto.grpc.MarketPriceRequest;
import bisq.proto.grpc.RegisterDisputeAgentRequest;
import bisq.proto.grpc.RemoveWalletPasswordRequest;
import bisq.proto.grpc.SetWalletPasswordRequest;
import bisq.proto.grpc.UnlockWalletRequest;

import protobuf.PaymentAccount;

import java.util.stream.Collectors;

import static bisq.common.app.DevEnv.DEV_PRIVILEGE_PRIV_KEY;
import static bisq.core.payment.payload.PaymentMethod.PERFECT_MONEY;
import static bisq.core.support.dispute.agent.DisputeAgent.DisputeAgentType.MEDIATOR;
import static bisq.core.support.dispute.agent.DisputeAgent.DisputeAgentType.REFUND_AGENT;
import static java.util.Comparator.comparing;
import static org.junit.jupiter.api.Assertions.assertEquals;



Expand Down Expand Up @@ -64,10 +76,8 @@ protected final GetFundingAddressesRequest createGetFundingAddressesRequest() {
return GetFundingAddressesRequest.newBuilder().build();
}

protected final RegisterDisputeAgentRequest createRegisterDisputeAgentRequest(String disputeAgentType) {
return RegisterDisputeAgentRequest.newBuilder()
.setDisputeAgentType(disputeAgentType)
.setRegistrationKey(DEV_PRIVILEGE_PRIV_KEY).build();
protected final MarketPriceRequest createMarketPriceRequest(String currencyCode) {
return MarketPriceRequest.newBuilder().setCurrencyCode(currencyCode).build();
}

// Convenience methods for calling frequently used & thoroughly tested gRPC services.
Expand Down Expand Up @@ -96,4 +106,48 @@ protected final String getUnusedBtcAddress(BisqAppConfig bisqAppConfig) {
.get()
.getAddress();
}

protected final CreatePaymentAccountRequest createCreatePerfectMoneyPaymentAccountRequest(
String accountName,
String accountNumber,
String currencyCode) {
return CreatePaymentAccountRequest.newBuilder()
.setPaymentMethodId(PERFECT_MONEY.getId())
.setAccountName(accountName)
.setAccountNumber(accountNumber)
.setCurrencyCode(currencyCode)
.build();
}

protected final PaymentAccount getDefaultPerfectDummyPaymentAccount(BisqAppConfig bisqAppConfig) {
var req = GetPaymentAccountsRequest.newBuilder().build();
var paymentAccountsService = grpcStubs(bisqAppConfig).paymentAccountsService;
PaymentAccount paymentAccount = paymentAccountsService.getPaymentAccounts(req)
.getPaymentAccountsList()
.stream()
.sorted(comparing(PaymentAccount::getCreationDate))
.collect(Collectors.toList()).get(0);
assertEquals("PerfectMoney dummy", paymentAccount.getAccountName());
return paymentAccount;
}

protected final double getMarketPrice(BisqAppConfig bisqAppConfig, String currencyCode) {
var req = createMarketPriceRequest(currencyCode);
return grpcStubs(bisqAppConfig).priceService.getMarketPrice(req).getPrice();
}

// Static conveniences for test methods and test case fixture setups.

protected static RegisterDisputeAgentRequest createRegisterDisputeAgentRequest(String disputeAgentType) {
return RegisterDisputeAgentRequest.newBuilder()
.setDisputeAgentType(disputeAgentType.toLowerCase())
.setRegistrationKey(DEV_PRIVILEGE_PRIV_KEY).build();
}

@SuppressWarnings("ResultOfMethodCallIgnored")
protected static void registerDisputeAgents(BisqAppConfig bisqAppConfig) {
var disputeAgentsService = grpcStubs(bisqAppConfig).disputeAgentsService;
disputeAgentsService.registerDisputeAgent(createRegisterDisputeAgentRequest(MEDIATOR.name()));
disputeAgentsService.registerDisputeAgent(createRegisterDisputeAgentRequest(REFUND_AGENT.name()));
}
}
Expand Up @@ -33,6 +33,9 @@
import static bisq.apitest.config.BisqAppConfig.arbdaemon;
import static bisq.apitest.config.BisqAppConfig.seednode;
import static bisq.common.app.DevEnv.DEV_PRIVILEGE_PRIV_KEY;
import static bisq.core.support.dispute.agent.DisputeAgent.DisputeAgentType.ARBITRATOR;
import static bisq.core.support.dispute.agent.DisputeAgent.DisputeAgentType.MEDIATOR;
import static bisq.core.support.dispute.agent.DisputeAgent.DisputeAgentType.REFUND_AGENT;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
Expand All @@ -44,10 +47,6 @@
@TestMethodOrder(OrderAnnotation.class)
public class RegisterDisputeAgentsTest extends MethodTest {

private static final String ARBITRATOR = "arbitrator";
private static final String MEDIATOR = "mediator";
private static final String REFUNDAGENT = "refundagent";

@BeforeAll
public static void setUp() {
try {
Expand All @@ -61,7 +60,7 @@ public static void setUp() {
@Order(1)
public void testRegisterArbitratorShouldThrowException() {
var req =
createRegisterDisputeAgentRequest(ARBITRATOR);
createRegisterDisputeAgentRequest(ARBITRATOR.name());
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req));
assertEquals("INVALID_ARGUMENT: arbitrators must be registered in a Bisq UI",
Expand All @@ -83,7 +82,7 @@ public void testInvalidDisputeAgentTypeArgShouldThrowException() {
@Order(3)
public void testInvalidRegistrationKeyArgShouldThrowException() {
var req = RegisterDisputeAgentRequest.newBuilder()
.setDisputeAgentType(REFUNDAGENT)
.setDisputeAgentType(REFUND_AGENT.name().toLowerCase())
.setRegistrationKey("invalid" + DEV_PRIVILEGE_PRIV_KEY).build();
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req));
Expand All @@ -95,15 +94,15 @@ public void testInvalidRegistrationKeyArgShouldThrowException() {
@Order(4)
public void testRegisterMediator() {
var req =
createRegisterDisputeAgentRequest(MEDIATOR);
createRegisterDisputeAgentRequest(MEDIATOR.name());
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req);
}

@Test
@Order(5)
public void testRegisterRefundAgent() {
var req =
createRegisterDisputeAgentRequest(REFUNDAGENT);
createRegisterDisputeAgentRequest(REFUND_AGENT.name());
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req);
}

Expand Down