Skip to content

Commit

Permalink
support additional info on all offers
Browse files Browse the repository at this point in the history
  • Loading branch information
woodser committed Jan 25, 2025
1 parent a6af155 commit 2370145
Show file tree
Hide file tree
Showing 45 changed files with 369 additions and 204 deletions.
8 changes: 6 additions & 2 deletions core/src/main/java/haveno/core/api/CoreApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ public void postOffer(String currencyCode,
String paymentAccountId,
boolean isPrivateOffer,
boolean buyerAsTakerWithoutDeposit,
String extraInfo,
Consumer<Offer> resultHandler,
ErrorMessageHandler errorMessageHandler) {
coreOffersService.postOffer(currencyCode,
Expand All @@ -440,6 +441,7 @@ public void postOffer(String currencyCode,
paymentAccountId,
isPrivateOffer,
buyerAsTakerWithoutDeposit,
extraInfo,
resultHandler,
errorMessageHandler);
}
Expand All @@ -455,7 +457,8 @@ public Offer editOffer(String offerId,
double securityDepositPct,
PaymentAccount paymentAccount,
boolean isPrivateOffer,
boolean buyerAsTakerWithoutDeposit) {
boolean buyerAsTakerWithoutDeposit,
String extraInfo) {
return coreOffersService.editOffer(offerId,
currencyCode,
direction,
Expand All @@ -467,7 +470,8 @@ public Offer editOffer(String offerId,
securityDepositPct,
paymentAccount,
isPrivateOffer,
buyerAsTakerWithoutDeposit);
buyerAsTakerWithoutDeposit,
extraInfo);
}

public void cancelOffer(String id, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
Expand Down
10 changes: 7 additions & 3 deletions core/src/main/java/haveno/core/api/CoreOffersService.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ void postOffer(String currencyCode,
String paymentAccountId,
boolean isPrivateOffer,
boolean buyerAsTakerWithoutDeposit,
String extraInfo,
Consumer<Offer> resultHandler,
ErrorMessageHandler errorMessageHandler) {
coreWalletsService.verifyWalletsAreAvailable();
Expand All @@ -204,7 +205,8 @@ void postOffer(String currencyCode,
securityDepositPct,
paymentAccount,
isPrivateOffer,
buyerAsTakerWithoutDeposit);
buyerAsTakerWithoutDeposit,
extraInfo);

verifyPaymentAccountIsValidForNewOffer(offer, paymentAccount);

Expand All @@ -230,7 +232,8 @@ Offer editOffer(String offerId,
double securityDepositPct,
PaymentAccount paymentAccount,
boolean isPrivateOffer,
boolean buyerAsTakerWithoutDeposit) {
boolean buyerAsTakerWithoutDeposit,
String extraInfo) {
return createOfferService.createAndGetOffer(offerId,
direction,
currencyCode.toUpperCase(),
Expand All @@ -242,7 +245,8 @@ Offer editOffer(String offerId,
securityDepositPct,
paymentAccount,
isPrivateOffer,
buyerAsTakerWithoutDeposit);
buyerAsTakerWithoutDeposit,
extraInfo);
}

void cancelOffer(String id, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
Expand Down
9 changes: 7 additions & 2 deletions core/src/main/java/haveno/core/api/model/OfferInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -115,6 +116,7 @@ public OfferInfo(OfferInfoBuilder builder) {
this.splitOutputTxFee = builder.getSplitOutputTxFee();
this.isPrivateOffer = builder.isPrivateOffer();
this.challenge = builder.getChallenge();
this.extraInfo = builder.getExtraInfo();
}

public static OfferInfo toOfferInfo(Offer offer) {
Expand All @@ -128,7 +130,7 @@ public static OfferInfo toMyOfferInfo(OpenOffer openOffer) {
// An OpenOffer is always my offer.
var offer = openOffer.getOffer();
var currencyCode = offer.getCurrencyCode();
var isActivated = !openOffer.isDeactivated();
var isActivated = !openOffer.isDeactivated();
Optional<Price> optionalTriggerPrice = openOffer.getTriggerPrice() > 0
? Optional.of(Price.valueOf(currencyCode, openOffer.getTriggerPrice()))
: Optional.empty();
Expand Down Expand Up @@ -184,7 +186,8 @@ private static OfferInfoBuilder getBuilder(Offer offer) {
.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());
}

///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -227,6 +230,7 @@ public haveno.proto.grpc.OfferInfo toProtoMessage() {
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();
}

Expand Down Expand Up @@ -266,6 +270,7 @@ public static OfferInfo fromProto(haveno.proto.grpc.OfferInfo proto) {
.withSplitOutputTxFee(proto.getSplitOutputTxFee())
.withIsPrivateOffer(proto.getIsPrivateOffer())
.withChallenge(proto.getChallenge())
.withExtraInfo(proto.getExtraInfo())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -246,6 +247,11 @@ public OfferInfoBuilder withChallenge(String challenge) {
return this;
}

public OfferInfoBuilder withExtraInfo(String extraInfo) {
this.extraInfo = extraInfo;
return this;
}

public OfferInfo build() {
return new OfferInfo(this);
}
Expand Down
12 changes: 8 additions & 4 deletions core/src/main/java/haveno/core/offer/CreateOfferService.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ public Offer createAndGetOffer(String offerId,
double securityDepositPct,
PaymentAccount paymentAccount,
boolean isPrivateOffer,
boolean buyerAsTakerWithoutDeposit) {
boolean buyerAsTakerWithoutDeposit,
String extraInfo) {
log.info("create and get offer with offerId={}, " +
"currencyCode={}, " +
"direction={}, " +
Expand All @@ -114,7 +115,8 @@ public Offer createAndGetOffer(String offerId,
"minAmount={}, " +
"securityDepositPct={}, " +
"isPrivateOffer={}, " +
"buyerAsTakerWithoutDeposit={}",
"buyerAsTakerWithoutDeposit={}, " +
"extraInfo={}",
offerId,
currencyCode,
direction,
Expand All @@ -125,7 +127,8 @@ public Offer createAndGetOffer(String offerId,
minAmount,
securityDepositPct,
isPrivateOffer,
buyerAsTakerWithoutDeposit);
buyerAsTakerWithoutDeposit,
extraInfo);

// verify buyer as taker security deposit
boolean isBuyerMaker = offerUtil.isBuyOffer(direction);
Expand Down Expand Up @@ -225,7 +228,8 @@ public Offer createAndGetOffer(String offerId,
Version.TRADE_PROTOCOL_VERSION,
null,
null,
null);
null,
extraInfo);
Offer offer = new Offer(offerPayload);
offer.setPriceFeedService(priceFeedService);
offer.setChallenge(challenge);
Expand Down
18 changes: 17 additions & 1 deletion core/src/main/java/haveno/core/offer/Offer.java
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,23 @@ public String getF2FCity() {
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))
Expand Down
23 changes: 17 additions & 6 deletions core/src/main/java/haveno/core/offer/OfferPayload.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;


///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -201,7 +203,8 @@ public OfferPayload(String id,
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;
Expand Down Expand Up @@ -240,6 +243,7 @@ public OfferPayload(String id,
this.upperClosePrice = upperClosePrice;
this.isPrivateOffer = isPrivateOffer;
this.challengeHash = challengeHash;
this.extraInfo = extraInfo;
}

public byte[] getHash() {
Expand Down Expand Up @@ -290,7 +294,8 @@ public byte[] getSignatureHash() {
protocolVersion,
arbitratorSigner,
null,
reserveTxKeyImages
reserveTxKeyImages,
null
);

return signee.getHash();
Expand Down Expand Up @@ -387,6 +392,7 @@ public protobuf.StoragePayload toProtoMessage() {
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();
}
Expand All @@ -398,7 +404,6 @@ public static OfferPayload fromProto(protobuf.OfferPayload proto) {
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();

Expand Down Expand Up @@ -434,12 +439,13 @@ public static OfferPayload fromProto(protobuf.OfferPayload proto) {
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
Expand Down Expand Up @@ -481,9 +487,10 @@ public String toString() {
",\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} ";
}

Expand Down Expand Up @@ -525,6 +532,10 @@ public JsonElement serialize(OfferPayload offerPayload, Type type, JsonSerializa
object.add("protocolVersion", context.serialize(offerPayload.getProtocolVersion()));
object.add("arbitratorSigner", context.serialize(offerPayload.getArbitratorSigner()));
object.add("arbitratorSignature", context.serialize(offerPayload.getArbitratorSignature()));
object.add("reserveTxKeyImages", context.serialize(offerPayload.getReserveTxKeyImages()));
object.add("isPrivateOffer", context.serialize(offerPayload.isPrivateOffer()));
object.add("challengeHash", context.serialize(offerPayload.getChallengeHash()));
object.add("extraInfo", context.serialize(offerPayload.getExtraInfo()));
return object;
}
}
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/haveno/core/offer/OpenOfferManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -1788,7 +1788,8 @@ private void maybeUpdatePersistedOffers() {
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();
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/haveno/core/payment/F2FAccount.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ protected PaymentAccountFormField getEmptyFormField(PaymentAccountFormField.Fiel
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;
}
}
7 changes: 5 additions & 2 deletions core/src/main/resources/i18n/displayStrings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3028,7 +3028,10 @@ payment.f2f.city=City for 'Face to face' meeting
payment.f2f.city.prompt=The city will be displayed with the offer
payment.shared.optionalExtra=Optional additional information
payment.shared.extraInfo=Additional information
payment.shared.extraInfo.prompt=Define any special terms, conditions, or details you would like to be displayed with your offers for this payment account (users will see this info before accepting offers).
payment.shared.extraInfo.offer=Additional offer information
payment.shared.extraInfo.prompt.paymentAccount=Define any special terms, conditions, or details you would like to be displayed with your offers for this payment account (users will see this info before accepting offers).
payment.shared.extraInfo.prompt.offer=Define any special terms, conditions, or details you would like to be displayed with your offer.
payment.shared.extraInfo.noDeposit=Contact details and offer terms
payment.f2f.info='Face to Face' trades have different rules and come with different risks than online transactions.\n\n\
The main differences are:\n\
● The trading peers need to exchange information about the meeting location and time by using their provided contact details.\n\
Expand All @@ -3042,7 +3045,7 @@ payment.f2f.info='Face to Face' trades have different rules and come with differ
recommendations at: [HYPERLINK:https://docs.haveno.exchange/the-project/payment_methods/F2F]
payment.f2f.info.openURL=Open web page
payment.f2f.offerbook.tooltip.countryAndCity=Country and city: {0} / {1}
payment.f2f.offerbook.tooltip.extra=Additional information: {0}
payment.shared.extraInfo.tooltip=Additional information: {0}
payment.ifsc=IFS Code
payment.ifsc.validation=IFSC format: XXXX0999999

Expand Down
7 changes: 5 additions & 2 deletions core/src/main/resources/i18n/displayStrings_cs.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3028,7 +3028,10 @@ payment.f2f.city=Město pro setkání 'tváří v tvář'
payment.f2f.city.prompt=Město se zobrazí s nabídkou
payment.shared.optionalExtra=Volitelné další informace
payment.shared.extraInfo=Další informace
payment.shared.extraInfo.prompt=Uveďte jakékoli speciální požadavky, podmínky a detaily, které chcete zobrazit u vašich nabídek s tímto platebním účtem. (Uživatelé uvidí tyto informace předtím, než akceptují vaši nabídku.)
payment.shared.extraInfo.offer=Další informace o nabídce
payment.shared.extraInfo.prompt.paymentAccount=Uveďte jakékoli speciální požadavky, podmínky a detaily, které chcete zobrazit u vašich nabídek s tímto platebním účtem. (Uživatelé uvidí tyto informace předtím, než akceptují vaši nabídku.)
payment.shared.extraInfo.prompt.offer=Definujte jakékoli speciální podmínky, podmínky nebo detaily, které chcete zobrazit u své nabídky.
payment.shared.extraInfo.noDeposit=Kontaktní údaje a podmínky nabídky
payment.f2f.info=Obchody 'tváří v tvář' mají různá pravidla a přicházejí s jinými riziky než online transakce.\n\n\
Hlavní rozdíly jsou:\n\
● Obchodní partneři si musí vyměňovat informace o místě a čase schůzky pomocí poskytnutých kontaktních údajů.\n\
Expand All @@ -3042,7 +3045,7 @@ payment.f2f.info=Obchody 'tváří v tvář' mají různá pravidla a přicháze
na adrese: [HYPERLINK:https://docs.haveno.exchange/the-project/payment_methods/F2F]
payment.f2f.info.openURL=Otevřít webovou stránku
payment.f2f.offerbook.tooltip.countryAndCity=Země a město: {0} / {1}
payment.f2f.offerbook.tooltip.extra=Další informace: {0}
payment.shared.extraInfo.tooltip=Další informace: {0}
payment.ifsc=IFS kód
payment.ifsc.validation=IFSC formát: XXXX0999999

Expand Down
Loading

0 comments on commit 2370145

Please sign in to comment.