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

Feat: OCO Offers #6605

Closed
wants to merge 5 commits into from
Closed

Feat: OCO Offers #6605

wants to merge 5 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Mar 13, 2023

OCO (One cancels other) offers as defined by @apemithrandir
Ref: bisq-network/proposals#402. Demo here.

Features:

  • Offers can be cloned using context menu ("Duplicate as OCO").
  • Cloning allows the reserved amount to be shared amongst multiple offers.
  • Cloned offers can be switched to different markets or payment methods using the existing "Edit Offer" functionality.
  • Spam is prevented by requiring cloned offers be on different payment methods or markets before they can be enabled.
  • Number of clones is limited to 10 per reserved UTXO.
  • Offer clones are recognizable by a group ID in portfolio view.
  • When an OCO offer is taken, all its clones are automatically removed (hence the name OCO).

@ripcurlx
Copy link
Contributor

As this is a high impact PR I'd like to see som ACK from core contributors like @HenrikJannsen,...

@ripcurlx ripcurlx added this to the v1.9.10 milestone Mar 27, 2023
@ghost ghost marked this pull request as draft March 31, 2023 03:21
jmacxx added 2 commits April 2, 2023 18:30
Pick a more user friendly name instead of OCO.
Clean up code.
@alejandrogarcia83 alejandrogarcia83 modified the milestones: v1.9.10, v1.9.11 Apr 15, 2023
@ghost ghost marked this pull request as ready for review May 2, 2023 16:28
@ghost ghost requested a review from HenrikJannsen May 2, 2023 16:28
@HenrikJannsen
Copy link
Collaborator

HenrikJannsen commented May 4, 2023

After the cloned offers have been created it is unclear what need to be edited to allow activation. There is no feedback at clicking activate and changing the price does not enable it as well, so a user not familiar with the feature would be confused.
We need to shop popups when activating but not permitted to give info whats needed. Also after having created then we should show a popup with info why they are deactivated and what need to be done (e.g. change payment method).

There should be an icon as well next to edit and duplicate offer. Not sure if the 5x option is needed. There will not be that many users who have that many payment methods and its just a simple click to clone. The right click context menu is not a standard UX feature Bisq uses so it would be hidden to most users.

@ghost
Copy link
Author

ghost commented May 4, 2023

I don't think there should be another icon next to edit and duplicate offer - that crowds the screen and confuses casual users. This feature is not for casual users, it is for advanced market makers. As such I expect the people using this feature would be the ones who requested it and/or read about it in the forums or bisq.wiki. Those users being experienced I think they do not need to be spoon fed by popups either.


// check if the ADDRESS still has any existing entries, only if not do the add to available.
boolean entryWithSameContextAlreadyExist = entrySet.stream().anyMatch(e -> {
if (entrySet.remove(addressEntry)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to remove the address entry if entryWithSameContextStillExists is true?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked closer into that now. The check with entryWithSameContextAlreadyExist is not needed and we can revert it as we have a hashset and the add will not add if we try to add the same entry.

addressEntryList.addAddressEntry(newEntry);
return newEntry;
// when a new offer needs to share the reserved amount info from parent offer's address entry
public AddressEntry getOrCreateAddressEntry(AddressEntry orgAddressEntry, String offerId) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The param name orgAddressEntry is unclear. If it means original better spell it out.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better name the method getOrCreateSharedAddressEntry

for (TransactionOutput output : txn.getOutputs()) {
if (walletService.isTransactionOutputMine(output) && WalletService.isOutputScriptConvertibleToAddress(output)) {
String addressString = WalletService.getAddressStringFromOutput(output);
assert addressString != null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not use assert but checkNotNull.

String addressString = WalletService.getAddressStringFromOutput(output);
assert addressString != null;
// make sure the output is still unspent
if (addressString.equalsIgnoreCase(address.toString()) && output.getSpentBy() == null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why equalsIgnoreCase?

return openOffers.stream().filter(e -> !e.getOffer().isBsqSwapOffer() && e.getOffer().getOfferFeePaymentTxId().equals(safeSearch)).collect(Collectors.toList());
return openOffers.stream()
.filter(e -> !e.getOffer().isBsqSwapOffer() && e.getOffer().getOfferFeePaymentTxId()
.equals(makerFeeTxId == null ? "" : makerFeeTxId))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right side of equals can be null.

!e.isDeactivated() &&
!e.getId().equals(newOffer.getId()) &&
e.getOffer().getOfferFeePaymentTxId().equals(newOffer.getOfferFeePaymentTxId()) &&
e.getOffer().getPaymentMethodId().equalsIgnoreCase(newOffer.getPaymentMethodId()) &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to use equalsIgnoreCase. It suggests that the strings do not have a defined case, but those data have not arbitrary upper/lower case.

@apemithrandir
Copy link

Has this feature been included in any of the recent releases? @jmacxx

@MwithM
Copy link
Contributor

MwithM commented Jul 2, 2023

Yes. #6675
https://bisq.wiki/Cloning_an_offer

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants