mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-27 00:45:23 -04:00
support additional info on all offers
This commit is contained in:
parent
a6af1550a4
commit
6c6c6e2dd5
45 changed files with 367 additions and 204 deletions
|
@ -425,6 +425,7 @@ public class CoreApi {
|
|||
String paymentAccountId,
|
||||
boolean isPrivateOffer,
|
||||
boolean buyerAsTakerWithoutDeposit,
|
||||
String extraInfo,
|
||||
Consumer<Offer> resultHandler,
|
||||
ErrorMessageHandler errorMessageHandler) {
|
||||
coreOffersService.postOffer(currencyCode,
|
||||
|
@ -440,6 +441,7 @@ public class CoreApi {
|
|||
paymentAccountId,
|
||||
isPrivateOffer,
|
||||
buyerAsTakerWithoutDeposit,
|
||||
extraInfo,
|
||||
resultHandler,
|
||||
errorMessageHandler);
|
||||
}
|
||||
|
@ -455,7 +457,8 @@ public class CoreApi {
|
|||
double securityDepositPct,
|
||||
PaymentAccount paymentAccount,
|
||||
boolean isPrivateOffer,
|
||||
boolean buyerAsTakerWithoutDeposit) {
|
||||
boolean buyerAsTakerWithoutDeposit,
|
||||
String extraInfo) {
|
||||
return coreOffersService.editOffer(offerId,
|
||||
currencyCode,
|
||||
direction,
|
||||
|
@ -467,7 +470,8 @@ public class CoreApi {
|
|||
securityDepositPct,
|
||||
paymentAccount,
|
||||
isPrivateOffer,
|
||||
buyerAsTakerWithoutDeposit);
|
||||
buyerAsTakerWithoutDeposit,
|
||||
extraInfo);
|
||||
}
|
||||
|
||||
public void cancelOffer(String id, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||
|
|
|
@ -178,6 +178,7 @@ public class CoreOffersService {
|
|||
String paymentAccountId,
|
||||
boolean isPrivateOffer,
|
||||
boolean buyerAsTakerWithoutDeposit,
|
||||
String extraInfo,
|
||||
Consumer<Offer> resultHandler,
|
||||
ErrorMessageHandler errorMessageHandler) {
|
||||
coreWalletsService.verifyWalletsAreAvailable();
|
||||
|
@ -204,7 +205,8 @@ public class CoreOffersService {
|
|||
securityDepositPct,
|
||||
paymentAccount,
|
||||
isPrivateOffer,
|
||||
buyerAsTakerWithoutDeposit);
|
||||
buyerAsTakerWithoutDeposit,
|
||||
extraInfo);
|
||||
|
||||
verifyPaymentAccountIsValidForNewOffer(offer, paymentAccount);
|
||||
|
||||
|
@ -230,7 +232,8 @@ public class CoreOffersService {
|
|||
double securityDepositPct,
|
||||
PaymentAccount paymentAccount,
|
||||
boolean isPrivateOffer,
|
||||
boolean buyerAsTakerWithoutDeposit) {
|
||||
boolean buyerAsTakerWithoutDeposit,
|
||||
String extraInfo) {
|
||||
return createOfferService.createAndGetOffer(offerId,
|
||||
direction,
|
||||
currencyCode.toUpperCase(),
|
||||
|
@ -242,7 +245,8 @@ public class CoreOffersService {
|
|||
securityDepositPct,
|
||||
paymentAccount,
|
||||
isPrivateOffer,
|
||||
buyerAsTakerWithoutDeposit);
|
||||
buyerAsTakerWithoutDeposit,
|
||||
extraInfo);
|
||||
}
|
||||
|
||||
void cancelOffer(String id, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||
|
|
|
@ -80,6 +80,7 @@ public class OfferInfo implements Payload {
|
|||
private final long splitOutputTxFee;
|
||||
private final boolean isPrivateOffer;
|
||||
private final String challenge;
|
||||
private final String extraInfo;
|
||||
|
||||
public OfferInfo(OfferInfoBuilder builder) {
|
||||
this.id = builder.getId();
|
||||
|
@ -115,6 +116,7 @@ public class OfferInfo implements Payload {
|
|||
this.splitOutputTxFee = builder.getSplitOutputTxFee();
|
||||
this.isPrivateOffer = builder.isPrivateOffer();
|
||||
this.challenge = builder.getChallenge();
|
||||
this.extraInfo = builder.getExtraInfo();
|
||||
}
|
||||
|
||||
public static OfferInfo toOfferInfo(Offer offer) {
|
||||
|
@ -184,7 +186,8 @@ public class OfferInfo implements Payload {
|
|||
.withProtocolVersion(offer.getOfferPayload().getProtocolVersion())
|
||||
.withArbitratorSigner(offer.getOfferPayload().getArbitratorSigner() == null ? null : offer.getOfferPayload().getArbitratorSigner().getFullAddress())
|
||||
.withIsPrivateOffer(offer.isPrivateOffer())
|
||||
.withChallenge(offer.getChallenge());
|
||||
.withChallenge(offer.getChallenge())
|
||||
.withExtraInfo(offer.getCombinedExtraInfo());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -227,6 +230,7 @@ public class OfferInfo implements Payload {
|
|||
Optional.ofNullable(arbitratorSigner).ifPresent(builder::setArbitratorSigner);
|
||||
Optional.ofNullable(splitOutputTxHash).ifPresent(builder::setSplitOutputTxHash);
|
||||
Optional.ofNullable(challenge).ifPresent(builder::setChallenge);
|
||||
Optional.ofNullable(extraInfo).ifPresent(builder::setExtraInfo);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
@ -266,6 +270,7 @@ public class OfferInfo implements Payload {
|
|||
.withSplitOutputTxFee(proto.getSplitOutputTxFee())
|
||||
.withIsPrivateOffer(proto.getIsPrivateOffer())
|
||||
.withChallenge(proto.getChallenge())
|
||||
.withExtraInfo(proto.getExtraInfo())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ public final class OfferInfoBuilder {
|
|||
private long splitOutputTxFee;
|
||||
private boolean isPrivateOffer;
|
||||
private String challenge;
|
||||
private String extraInfo;
|
||||
|
||||
public OfferInfoBuilder withId(String id) {
|
||||
this.id = id;
|
||||
|
@ -246,6 +247,11 @@ public final class OfferInfoBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public OfferInfoBuilder withExtraInfo(String extraInfo) {
|
||||
this.extraInfo = extraInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OfferInfo build() {
|
||||
return new OfferInfo(this);
|
||||
}
|
||||
|
|
|
@ -103,7 +103,8 @@ public class CreateOfferService {
|
|||
double securityDepositPct,
|
||||
PaymentAccount paymentAccount,
|
||||
boolean isPrivateOffer,
|
||||
boolean buyerAsTakerWithoutDeposit) {
|
||||
boolean buyerAsTakerWithoutDeposit,
|
||||
String extraInfo) {
|
||||
log.info("create and get offer with offerId={}, " +
|
||||
"currencyCode={}, " +
|
||||
"direction={}, " +
|
||||
|
@ -114,7 +115,8 @@ public class CreateOfferService {
|
|||
"minAmount={}, " +
|
||||
"securityDepositPct={}, " +
|
||||
"isPrivateOffer={}, " +
|
||||
"buyerAsTakerWithoutDeposit={}",
|
||||
"buyerAsTakerWithoutDeposit={}, " +
|
||||
"extraInfo={}",
|
||||
offerId,
|
||||
currencyCode,
|
||||
direction,
|
||||
|
@ -125,7 +127,8 @@ public class CreateOfferService {
|
|||
minAmount,
|
||||
securityDepositPct,
|
||||
isPrivateOffer,
|
||||
buyerAsTakerWithoutDeposit);
|
||||
buyerAsTakerWithoutDeposit,
|
||||
extraInfo);
|
||||
|
||||
// verify buyer as taker security deposit
|
||||
boolean isBuyerMaker = offerUtil.isBuyOffer(direction);
|
||||
|
@ -225,7 +228,8 @@ public class CreateOfferService {
|
|||
Version.TRADE_PROTOCOL_VERSION,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
null,
|
||||
extraInfo);
|
||||
Offer offer = new Offer(offerPayload);
|
||||
offer.setPriceFeedService(priceFeedService);
|
||||
offer.setChallenge(challenge);
|
||||
|
|
|
@ -421,7 +421,23 @@ public class Offer implements NetworkPayload, PersistablePayload {
|
|||
return "";
|
||||
}
|
||||
|
||||
public String getExtraInfo() {
|
||||
public String getCombinedExtraInfo() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (getOfferExtraInfo() != null && !getOfferExtraInfo().isEmpty()) {
|
||||
sb.append(getOfferExtraInfo());
|
||||
}
|
||||
if (getPaymentAccountExtraInfo() != null && !getPaymentAccountExtraInfo().isEmpty()) {
|
||||
if (sb.length() > 0) sb.append("\n\n");
|
||||
sb.append(getPaymentAccountExtraInfo());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getOfferExtraInfo() {
|
||||
return offerPayload.getExtraInfo();
|
||||
}
|
||||
|
||||
public String getPaymentAccountExtraInfo() {
|
||||
if (getExtraDataMap() != null && getExtraDataMap().containsKey(OfferPayload.F2F_EXTRA_INFO))
|
||||
return getExtraDataMap().get(OfferPayload.F2F_EXTRA_INFO);
|
||||
else if (getExtraDataMap() != null && getExtraDataMap().containsKey(OfferPayload.PAY_BY_MAIL_EXTRA_INFO))
|
||||
|
|
|
@ -158,6 +158,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
|||
private final boolean isPrivateOffer;
|
||||
@Nullable
|
||||
private final String challengeHash;
|
||||
@Nullable
|
||||
private final String extraInfo;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -201,7 +203,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
|||
int protocolVersion,
|
||||
@Nullable NodeAddress arbitratorSigner,
|
||||
@Nullable byte[] arbitratorSignature,
|
||||
@Nullable List<String> reserveTxKeyImages) {
|
||||
@Nullable List<String> reserveTxKeyImages,
|
||||
@Nullable String extraInfo) {
|
||||
this.id = id;
|
||||
this.date = date;
|
||||
this.ownerNodeAddress = ownerNodeAddress;
|
||||
|
@ -240,6 +243,7 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
|||
this.upperClosePrice = upperClosePrice;
|
||||
this.isPrivateOffer = isPrivateOffer;
|
||||
this.challengeHash = challengeHash;
|
||||
this.extraInfo = extraInfo;
|
||||
}
|
||||
|
||||
public byte[] getHash() {
|
||||
|
@ -290,7 +294,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
|||
protocolVersion,
|
||||
arbitratorSigner,
|
||||
null,
|
||||
reserveTxKeyImages
|
||||
reserveTxKeyImages,
|
||||
null
|
||||
);
|
||||
|
||||
return signee.getHash();
|
||||
|
@ -387,6 +392,7 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
|||
Optional.ofNullable(arbitratorSigner).ifPresent(e -> builder.setArbitratorSigner(arbitratorSigner.toProtoMessage()));
|
||||
Optional.ofNullable(arbitratorSignature).ifPresent(e -> builder.setArbitratorSignature(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(reserveTxKeyImages).ifPresent(builder::addAllReserveTxKeyImages);
|
||||
Optional.ofNullable(extraInfo).ifPresent(builder::setExtraInfo);
|
||||
|
||||
return protobuf.StoragePayload.newBuilder().setOfferPayload(builder).build();
|
||||
}
|
||||
|
@ -398,7 +404,6 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
|||
null : new ArrayList<>(proto.getAcceptedCountryCodesList());
|
||||
List<String> reserveTxKeyImages = proto.getReserveTxKeyImagesList().isEmpty() ?
|
||||
null : new ArrayList<>(proto.getReserveTxKeyImagesList());
|
||||
String challengeHash = ProtoUtil.stringOrNullFromProto(proto.getChallengeHash());
|
||||
Map<String, String> extraDataMapMap = CollectionUtils.isEmpty(proto.getExtraDataMap()) ?
|
||||
null : proto.getExtraDataMap();
|
||||
|
||||
|
@ -434,12 +439,13 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
|||
proto.getLowerClosePrice(),
|
||||
proto.getUpperClosePrice(),
|
||||
proto.getIsPrivateOffer(),
|
||||
challengeHash,
|
||||
ProtoUtil.stringOrNullFromProto(proto.getChallengeHash()),
|
||||
extraDataMapMap,
|
||||
proto.getProtocolVersion(),
|
||||
proto.hasArbitratorSigner() ? NodeAddress.fromProto(proto.getArbitratorSigner()) : null,
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getArbitratorSignature()),
|
||||
reserveTxKeyImages);
|
||||
reserveTxKeyImages,
|
||||
ProtoUtil.stringOrNullFromProto(proto.getExtraInfo()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -481,14 +487,15 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
|||
",\r\n lowerClosePrice=" + lowerClosePrice +
|
||||
",\r\n upperClosePrice=" + upperClosePrice +
|
||||
",\r\n isPrivateOffer=" + isPrivateOffer +
|
||||
",\r\n challengeHash='" + challengeHash + '\'' +
|
||||
",\r\n challengeHash='" + challengeHash +
|
||||
",\r\n arbitratorSigner=" + arbitratorSigner +
|
||||
",\r\n arbitratorSignature=" + Utilities.bytesAsHexString(arbitratorSignature) +
|
||||
",\r\n extraInfo='" + extraInfo +
|
||||
"\r\n} ";
|
||||
}
|
||||
|
||||
// For backward compatibility we need to ensure same order for json fields as with 1.7.5. and earlier versions.
|
||||
// The json is used for the hash in the contract and change of oder would cause a different hash and
|
||||
// The json is used for the hash in the contract and change of order would cause a different hash and
|
||||
// therefore a failure during trade.
|
||||
public static class JsonSerializer implements com.google.gson.JsonSerializer<OfferPayload> {
|
||||
@Override
|
||||
|
@ -525,6 +532,8 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
|||
object.add("protocolVersion", context.serialize(offerPayload.getProtocolVersion()));
|
||||
object.add("arbitratorSigner", context.serialize(offerPayload.getArbitratorSigner()));
|
||||
object.add("arbitratorSignature", context.serialize(offerPayload.getArbitratorSignature()));
|
||||
object.add("extraInfo", context.serialize(offerPayload.getExtraInfo()));
|
||||
// reserveTxKeyImages and challengeHash are purposely excluded because they are not relevant to existing trades and would break existing contracts
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1788,7 +1788,8 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||
protocolVersion,
|
||||
originalOfferPayload.getArbitratorSigner(),
|
||||
originalOfferPayload.getArbitratorSignature(),
|
||||
originalOfferPayload.getReserveTxKeyImages());
|
||||
originalOfferPayload.getReserveTxKeyImages(),
|
||||
originalOfferPayload.getExtraInfo());
|
||||
|
||||
// Save states from original data to use for the updated
|
||||
Offer.State originalOfferState = originalOffer.getState();
|
||||
|
|
|
@ -93,7 +93,7 @@ public final class F2FAccount extends CountryBasedPaymentAccount {
|
|||
if (field.getId() == PaymentAccountFormField.FieldId.TRADE_CURRENCIES) field.setComponent(PaymentAccountFormField.Component.SELECT_ONE);
|
||||
if (field.getId() == PaymentAccountFormField.FieldId.CITY) field.setLabel(Res.get("payment.f2f.city"));
|
||||
if (field.getId() == PaymentAccountFormField.FieldId.CONTACT) field.setLabel(Res.get("payment.f2f.contact"));
|
||||
if (field.getId() == PaymentAccountFormField.FieldId.EXTRA_INFO) field.setLabel(Res.get("payment.shared.extraInfo.prompt"));
|
||||
if (field.getId() == PaymentAccountFormField.FieldId.EXTRA_INFO) field.setLabel(Res.get("payment.shared.extraInfo.prompt.paymentAccount"));
|
||||
return field;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue