mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-22 22:45:21 +01:00
Add rpc method 'createpaymentacct'
This addresses task 4 in issue 4257. https://github.com/bisq-network/bisq/issues/4257 This PR should be reviewed/merged after PR 4304. https://github.com/bisq-network/bisq/pull/4304 This new gRPC PaymentAccounts service method creates a dummy PerfectMoney payment account for the given name, number and fiat currency code, as part of the required "simplest possible trading API" (for demo). An implementation supporting all payment methods is not in the scope. Changes specific to the new rpc method implementation follow: * New createpaymentacct method + help text was added to CliMain. Help text formatting was also changed to make room for larger method names and argument lists. * The PaymentAccount proto service def was renamed PaymentAccounts to avoid a name collision, and the new rpc CreatePaymentAccount was made part of the newly named PaymentAccounts service def. * New GrpcPaymentAccountsService (gRPC boilerplate) and CorePaymentAccountsService (method implementations) classes were added. * The gRPC GetPaymentAccountsService stub was moved from GrpcServer to the new GrpcPaymentAccountsService class, and GrpcPaymentAccountsService is injected into GrpcServer. * A new createpaymentacct unit test was added to the bats test suite (checks for successful return status code). Maybe bit out of scope, some small changes were made towards making sure the entire API is defined in CoreApi, which is used as a pass-through object to the new CorePaymentAccountsService. In the next PR, similar refactoring will be done to make CoreApi the pass-through object for all of the existing CoreWalletsService methods. (CoreWalletsService will be injected into CoreApi.) In the future, all Grpc*Service implementations will call core services through CoreApi, for the sake of consistency.
This commit is contained in:
parent
b1228e5ea7
commit
a7542e98bf
7 changed files with 173 additions and 34 deletions
|
@ -17,12 +17,14 @@
|
|||
|
||||
package bisq.cli;
|
||||
|
||||
import bisq.proto.grpc.CreatePaymentAccountRequest;
|
||||
import bisq.proto.grpc.GetAddressBalanceRequest;
|
||||
import bisq.proto.grpc.GetBalanceRequest;
|
||||
import bisq.proto.grpc.GetFundingAddressesRequest;
|
||||
import bisq.proto.grpc.GetVersionGrpc;
|
||||
import bisq.proto.grpc.GetVersionRequest;
|
||||
import bisq.proto.grpc.LockWalletRequest;
|
||||
import bisq.proto.grpc.PaymentAccountsGrpc;
|
||||
import bisq.proto.grpc.RemoveWalletPasswordRequest;
|
||||
import bisq.proto.grpc.SetWalletPasswordRequest;
|
||||
import bisq.proto.grpc.UnlockWalletRequest;
|
||||
|
@ -58,6 +60,7 @@ import static java.lang.System.out;
|
|||
public class CliMain {
|
||||
|
||||
private enum Method {
|
||||
createpaymentacct,
|
||||
getversion,
|
||||
getbalance,
|
||||
getaddressbalance,
|
||||
|
@ -135,6 +138,7 @@ public class CliMain {
|
|||
}));
|
||||
|
||||
var versionService = GetVersionGrpc.newBlockingStub(channel).withCallCredentials(credentials);
|
||||
var paymentAccountsService = PaymentAccountsGrpc.newBlockingStub(channel).withCallCredentials(credentials);
|
||||
var walletService = WalletGrpc.newBlockingStub(channel).withCallCredentials(credentials);
|
||||
|
||||
try {
|
||||
|
@ -172,6 +176,30 @@ public class CliMain {
|
|||
out.println(reply.getFundingAddressesInfo());
|
||||
return;
|
||||
}
|
||||
case createpaymentacct: {
|
||||
if (nonOptionArgs.size() < 2)
|
||||
throw new IllegalArgumentException("no account name specified");
|
||||
|
||||
var accountName = nonOptionArgs.get(1);
|
||||
|
||||
if (nonOptionArgs.size() < 3)
|
||||
throw new IllegalArgumentException("no account number specified");
|
||||
|
||||
var accountNumber = nonOptionArgs.get(2);
|
||||
|
||||
if (nonOptionArgs.size() < 4)
|
||||
throw new IllegalArgumentException("no fiat currency specified");
|
||||
|
||||
var fiatCurrencyCode = nonOptionArgs.get(3).toUpperCase();
|
||||
|
||||
var request = CreatePaymentAccountRequest.newBuilder()
|
||||
.setAccountName(accountName)
|
||||
.setAccountNumber(accountNumber)
|
||||
.setFiatCurrencyCode(fiatCurrencyCode).build();
|
||||
paymentAccountsService.createPaymentAccount(request);
|
||||
out.println(format("payment account %s saved", accountName));
|
||||
return;
|
||||
}
|
||||
case lockwallet: {
|
||||
var request = LockWalletRequest.newBuilder().build();
|
||||
walletService.lockWallet(request);
|
||||
|
@ -238,16 +266,17 @@ public class CliMain {
|
|||
stream.println();
|
||||
parser.printHelpOn(stream);
|
||||
stream.println();
|
||||
stream.format("%-19s%-30s%s%n", "Method", "Params", "Description");
|
||||
stream.format("%-19s%-30s%s%n", "------", "------", "------------");
|
||||
stream.format("%-19s%-30s%s%n", "getversion", "", "Get server version");
|
||||
stream.format("%-19s%-30s%s%n", "getbalance", "", "Get server wallet balance");
|
||||
stream.format("%-19s%-30s%s%n", "getaddressbalance", "", "Get server wallet address balance");
|
||||
stream.format("%-19s%-30s%s%n", "getfundingaddresses", "", "Get BTC funding addresses");
|
||||
stream.format("%-19s%-30s%s%n", "lockwallet", "", "Remove wallet password from memory, locking the wallet");
|
||||
stream.format("%-19s%-30s%s%n", "unlockwallet", "password timeout",
|
||||
stream.format("%-22s%-50s%s%n", "Method", "Params", "Description");
|
||||
stream.format("%-22s%-50s%s%n", "------", "------", "------------");
|
||||
stream.format("%-22s%-50s%s%n", "getversion", "", "Get server version");
|
||||
stream.format("%-22s%-50s%s%n", "getbalance", "", "Get server wallet balance");
|
||||
stream.format("%-22s%-50s%s%n", "getaddressbalance", "address", "Get server wallet address balance");
|
||||
stream.format("%-22s%-50s%s%n", "getfundingaddresses", "", "Get BTC funding addresses");
|
||||
stream.format("%-22s%-50s%s%n", "createpaymentacct", "account name, account number, currency code", "Create PerfectMoney dummy account");
|
||||
stream.format("%-22s%-50s%s%n", "lockwallet", "", "Remove wallet password from memory, locking the wallet");
|
||||
stream.format("%-22s%-50s%s%n", "unlockwallet", "password timeout",
|
||||
"Store wallet password in memory for timeout seconds");
|
||||
stream.format("%-19s%-30s%s%n", "setwalletpassword", "password [newpassword]",
|
||||
stream.format("%-22s%-50s%s%n", "setwalletpassword", "password [newpassword]",
|
||||
"Encrypt wallet with password, or set new password on encrypted wallet");
|
||||
stream.println();
|
||||
} catch (IOException ex) {
|
||||
|
|
|
@ -166,6 +166,11 @@
|
|||
[ "$output" = "Error: address bogus not found in wallet" ]
|
||||
}
|
||||
|
||||
@test "test createpaymentacct PerfectMoneyDummy 0123456789 USD" {
|
||||
run ./bisq-cli --password=xyz createpaymentacct PerfectMoneyDummy 0123456789 USD
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "test help displayed on stderr if no options or arguments" {
|
||||
run ./bisq-cli
|
||||
[ "$status" -eq 1 ]
|
||||
|
|
|
@ -47,6 +47,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
*/
|
||||
@Slf4j
|
||||
public class CoreApi {
|
||||
private final CorePaymentAccountsService paymentAccountsService;
|
||||
private final OfferBookService offerBookService;
|
||||
private final TradeStatisticsManager tradeStatisticsManager;
|
||||
private final CreateOfferService createOfferService;
|
||||
|
@ -54,11 +55,13 @@ public class CoreApi {
|
|||
private final User user;
|
||||
|
||||
@Inject
|
||||
public CoreApi(OfferBookService offerBookService,
|
||||
public CoreApi(CorePaymentAccountsService paymentAccountsService,
|
||||
OfferBookService offerBookService,
|
||||
TradeStatisticsManager tradeStatisticsManager,
|
||||
CreateOfferService createOfferService,
|
||||
OpenOfferManager openOfferManager,
|
||||
User user) {
|
||||
this.paymentAccountsService = paymentAccountsService;
|
||||
this.offerBookService = offerBookService;
|
||||
this.tradeStatisticsManager = tradeStatisticsManager;
|
||||
this.createOfferService = createOfferService;
|
||||
|
@ -78,8 +81,12 @@ public class CoreApi {
|
|||
return offerBookService.getOffers();
|
||||
}
|
||||
|
||||
public void createPaymentAccount(String accountName, String accountNumber, String fiatCurrencyCode) {
|
||||
paymentAccountsService.createPaymentAccount(accountName, accountNumber, fiatCurrencyCode);
|
||||
}
|
||||
|
||||
public Set<PaymentAccount> getPaymentAccounts() {
|
||||
return user.getPaymentAccounts();
|
||||
return paymentAccountsService.getPaymentAccounts();
|
||||
}
|
||||
|
||||
public void placeOffer(String currencyCode,
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package bisq.core.grpc;
|
||||
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
import bisq.core.locale.FiatCurrency;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.payment.PaymentAccountFactory;
|
||||
import bisq.core.payment.PerfectMoneyAccount;
|
||||
import bisq.core.payment.payload.PaymentMethod;
|
||||
import bisq.core.user.User;
|
||||
|
||||
import bisq.common.config.Config;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class CorePaymentAccountsService {
|
||||
|
||||
private final Config config;
|
||||
private final AccountAgeWitnessService accountAgeWitnessService;
|
||||
private final User user;
|
||||
|
||||
@Inject
|
||||
public CorePaymentAccountsService(Config config,
|
||||
AccountAgeWitnessService accountAgeWitnessService,
|
||||
User user) {
|
||||
this.config = config;
|
||||
this.accountAgeWitnessService = accountAgeWitnessService;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public void createPaymentAccount(String accountName, String accountNumber, String fiatCurrencyCode) {
|
||||
// Create and persist a PerfectMoney dummy payment account. There is no guard
|
||||
// against creating accounts with duplicate names & numbers, only the uuid and
|
||||
// creation date are unique.
|
||||
PaymentMethod dummyPaymentMethod = PaymentMethod.getDummyPaymentMethod(PaymentMethod.PERFECT_MONEY_ID);
|
||||
PaymentAccount paymentAccount = PaymentAccountFactory.getPaymentAccount(dummyPaymentMethod);
|
||||
paymentAccount.init();
|
||||
paymentAccount.setAccountName(accountName);
|
||||
((PerfectMoneyAccount) paymentAccount).setAccountNr(accountNumber);
|
||||
paymentAccount.setSingleTradeCurrency(new FiatCurrency(fiatCurrencyCode));
|
||||
user.addPaymentAccount(paymentAccount);
|
||||
|
||||
// Don't do this on mainnet until thoroughly tested.
|
||||
if (config.baseCurrencyNetwork.isRegtest())
|
||||
accountAgeWitnessService.publishMyAccountAgeWitness(paymentAccount.getPaymentAccountPayload());
|
||||
|
||||
log.info("Payment account {} saved", paymentAccount.getId());
|
||||
}
|
||||
|
||||
public Set<PaymentAccount> getPaymentAccounts() {
|
||||
return user.getPaymentAccounts();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package bisq.core.grpc;
|
||||
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
|
||||
import bisq.proto.grpc.CreatePaymentAccountReply;
|
||||
import bisq.proto.grpc.CreatePaymentAccountRequest;
|
||||
import bisq.proto.grpc.GetPaymentAccountsReply;
|
||||
import bisq.proto.grpc.GetPaymentAccountsRequest;
|
||||
import bisq.proto.grpc.PaymentAccountsGrpc;
|
||||
|
||||
import io.grpc.stub.StreamObserver;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public class GrpcPaymentAccountsService extends PaymentAccountsGrpc.PaymentAccountsImplBase {
|
||||
|
||||
private final CoreApi coreApi;
|
||||
|
||||
@Inject
|
||||
public GrpcPaymentAccountsService(CoreApi coreApi) {
|
||||
this.coreApi = coreApi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPaymentAccount(CreatePaymentAccountRequest req,
|
||||
StreamObserver<CreatePaymentAccountReply> responseObserver) {
|
||||
coreApi.createPaymentAccount(req.getAccountName(), req.getAccountNumber(), req.getFiatCurrencyCode());
|
||||
var reply = CreatePaymentAccountReply.newBuilder().build();
|
||||
responseObserver.onNext(reply);
|
||||
responseObserver.onCompleted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPaymentAccounts(GetPaymentAccountsRequest req,
|
||||
StreamObserver<GetPaymentAccountsReply> responseObserver) {
|
||||
var tradeStatistics = coreApi.getPaymentAccounts().stream()
|
||||
.map(PaymentAccount::toProtoMessage)
|
||||
.collect(Collectors.toList());
|
||||
var reply = GetPaymentAccountsReply.newBuilder().addAllPaymentAccounts(tradeStatistics).build();
|
||||
responseObserver.onNext(reply);
|
||||
responseObserver.onCompleted();
|
||||
}
|
||||
}
|
|
@ -18,7 +18,6 @@
|
|||
package bisq.core.grpc;
|
||||
|
||||
import bisq.core.offer.Offer;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.trade.handlers.TransactionResultHandler;
|
||||
import bisq.core.trade.statistics.TradeStatistics2;
|
||||
|
||||
|
@ -27,9 +26,6 @@ import bisq.common.config.Config;
|
|||
import bisq.proto.grpc.GetOffersGrpc;
|
||||
import bisq.proto.grpc.GetOffersReply;
|
||||
import bisq.proto.grpc.GetOffersRequest;
|
||||
import bisq.proto.grpc.GetPaymentAccountsGrpc;
|
||||
import bisq.proto.grpc.GetPaymentAccountsReply;
|
||||
import bisq.proto.grpc.GetPaymentAccountsRequest;
|
||||
import bisq.proto.grpc.GetTradeStatisticsGrpc;
|
||||
import bisq.proto.grpc.GetTradeStatisticsReply;
|
||||
import bisq.proto.grpc.GetTradeStatisticsRequest;
|
||||
|
@ -60,14 +56,17 @@ public class GrpcServer {
|
|||
private final Server server;
|
||||
|
||||
@Inject
|
||||
public GrpcServer(Config config, CoreApi coreApi, GrpcWalletService walletService) {
|
||||
public GrpcServer(Config config,
|
||||
CoreApi coreApi,
|
||||
GrpcPaymentAccountsService paymentAccountsService,
|
||||
GrpcWalletService walletService) {
|
||||
this.coreApi = coreApi;
|
||||
this.server = ServerBuilder.forPort(config.apiPort)
|
||||
.addService(new GetVersionService())
|
||||
.addService(new GetTradeStatisticsService())
|
||||
.addService(new GetOffersService())
|
||||
.addService(new GetPaymentAccountsService())
|
||||
.addService(new PlaceOfferService())
|
||||
.addService(paymentAccountsService)
|
||||
.addService(walletService)
|
||||
.intercept(new PasswordAuthInterceptor(config.apiPassword))
|
||||
.build();
|
||||
|
@ -125,21 +124,6 @@ public class GrpcServer {
|
|||
}
|
||||
}
|
||||
|
||||
class GetPaymentAccountsService extends GetPaymentAccountsGrpc.GetPaymentAccountsImplBase {
|
||||
@Override
|
||||
public void getPaymentAccounts(GetPaymentAccountsRequest req,
|
||||
StreamObserver<GetPaymentAccountsReply> responseObserver) {
|
||||
|
||||
var tradeStatistics = coreApi.getPaymentAccounts().stream()
|
||||
.map(PaymentAccount::toProtoMessage)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
var reply = GetPaymentAccountsReply.newBuilder().addAllPaymentAccounts(tradeStatistics).build();
|
||||
responseObserver.onNext(reply);
|
||||
responseObserver.onCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
class PlaceOfferService extends PlaceOfferGrpc.PlaceOfferImplBase {
|
||||
@Override
|
||||
public void placeOffer(PlaceOfferRequest req, StreamObserver<PlaceOfferReply> responseObserver) {
|
||||
|
|
|
@ -72,14 +72,25 @@ message GetOffersReply {
|
|||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PaymentAccount
|
||||
// PaymentAccounts
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
service GetPaymentAccounts {
|
||||
service PaymentAccounts {
|
||||
rpc CreatePaymentAccount (CreatePaymentAccountRequest) returns (CreatePaymentAccountReply) {
|
||||
}
|
||||
rpc GetPaymentAccounts (GetPaymentAccountsRequest) returns (GetPaymentAccountsReply) {
|
||||
}
|
||||
}
|
||||
|
||||
message CreatePaymentAccountRequest {
|
||||
string accountName = 1;
|
||||
string accountNumber = 2;
|
||||
string fiatCurrencyCode = 3;
|
||||
}
|
||||
|
||||
message CreatePaymentAccountReply {
|
||||
}
|
||||
|
||||
message GetPaymentAccountsRequest {
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue