mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-20 10:22:18 +01:00
Add support for referrer IDs at offers and trades
See: https://github.com/bisq-network/proposals/issues/28
This commit is contained in:
parent
28a5d82fd0
commit
808915ec82
@ -248,7 +248,6 @@ public class BisqApp extends Application implements UncaughtExceptionHandler {
|
||||
|
||||
private void addSceneKeyEventHandler(Scene scene, Injector injector) {
|
||||
scene.addEventHandler(KeyEvent.KEY_RELEASED, keyEvent -> {
|
||||
Utilities.isAltOrCtrlPressed(KeyCode.W, keyEvent);
|
||||
if (Utilities.isCtrlPressed(KeyCode.W, keyEvent) ||
|
||||
Utilities.isCtrlPressed(KeyCode.Q, keyEvent)) {
|
||||
stop();
|
||||
|
@ -28,31 +28,62 @@ import bisq.desktop.main.MainView;
|
||||
import bisq.desktop.main.market.offerbook.OfferBookChartView;
|
||||
import bisq.desktop.main.market.spread.SpreadView;
|
||||
import bisq.desktop.main.market.trades.TradesChartsView;
|
||||
import bisq.desktop.main.offer.offerbook.OfferBook;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.util.BSFormatter;
|
||||
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.offer.OfferPayload;
|
||||
import bisq.core.trade.statistics.TradeStatistics2;
|
||||
|
||||
import bisq.network.p2p.P2PService;
|
||||
|
||||
import bisq.common.util.Utilities;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TabPane;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
|
||||
import javafx.beans.value.ChangeListener;
|
||||
|
||||
import javafx.event.EventHandler;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@FxmlView
|
||||
public class MarketView extends ActivatableViewAndModel<TabPane, Activatable> {
|
||||
@FXML
|
||||
Tab offerBookTab, tradesTab, spreadTab;
|
||||
private final ViewLoader viewLoader;
|
||||
private final P2PService p2PService;
|
||||
private final OfferBook offerBook;
|
||||
private final BSFormatter formatter;
|
||||
private final Navigation navigation;
|
||||
private Navigation.Listener navigationListener;
|
||||
private ChangeListener<Tab> tabChangeListener;
|
||||
private EventHandler<KeyEvent> keyEventEventHandler;
|
||||
private Scene scene;
|
||||
|
||||
|
||||
@Inject
|
||||
public MarketView(CachingViewLoader viewLoader, Navigation navigation) {
|
||||
public MarketView(CachingViewLoader viewLoader, P2PService p2PService, OfferBook offerBook, BSFormatter formatter,
|
||||
Navigation navigation) {
|
||||
this.viewLoader = viewLoader;
|
||||
this.p2PService = p2PService;
|
||||
this.offerBook = offerBook;
|
||||
this.formatter = formatter;
|
||||
this.navigation = navigation;
|
||||
}
|
||||
|
||||
@ -78,6 +109,22 @@ public class MarketView extends ActivatableViewAndModel<TabPane, Activatable> {
|
||||
//noinspection unchecked
|
||||
navigation.navigateTo(MainView.class, MarketView.class, SpreadView.class);
|
||||
};
|
||||
|
||||
keyEventEventHandler = keyEvent -> {
|
||||
if (Utilities.isCtrlPressed(KeyCode.T, keyEvent)) {
|
||||
String allTradesWithReferralId = getAllTradesWithReferralId();
|
||||
new Popup<>().message(StringUtils.abbreviate(allTradesWithReferralId, 600))
|
||||
.actionButtonText(Res.get("shared.copyToClipboard"))
|
||||
.onAction(() -> Utilities.copyToClipboard(allTradesWithReferralId))
|
||||
.show();
|
||||
} else if (Utilities.isCtrlPressed(KeyCode.O, keyEvent)) {
|
||||
String allOffersWithReferralId = getAllOffersWithReferralId();
|
||||
new Popup<>().message(StringUtils.abbreviate(allOffersWithReferralId, 600))
|
||||
.actionButtonText(Res.get("shared.copyToClipboard"))
|
||||
.onAction(() -> Utilities.copyToClipboard(allOffersWithReferralId))
|
||||
.show();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,12 +141,21 @@ public class MarketView extends ActivatableViewAndModel<TabPane, Activatable> {
|
||||
else
|
||||
//noinspection unchecked
|
||||
navigation.navigateTo(MainView.class, MarketView.class, SpreadView.class);
|
||||
|
||||
if (root.getScene() != null) {
|
||||
scene = root.getScene();
|
||||
scene.addEventHandler(KeyEvent.KEY_RELEASED, keyEventEventHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
root.getSelectionModel().selectedItemProperty().removeListener(tabChangeListener);
|
||||
navigation.removeListener(navigationListener);
|
||||
|
||||
// root.getScene() is null already so we used a field property
|
||||
if (scene != null)
|
||||
scene.removeEventHandler(KeyEvent.KEY_RELEASED, keyEventEventHandler);
|
||||
}
|
||||
|
||||
private void loadView(Class<? extends View> viewClass) {
|
||||
@ -119,4 +175,49 @@ public class MarketView extends ActivatableViewAndModel<TabPane, Activatable> {
|
||||
root.getSelectionModel().select(tab);
|
||||
}
|
||||
|
||||
private String getAllTradesWithReferralId() {
|
||||
// We don't use the list from the tradeStatisticsManager as that has filtered the duplicates but we want to get
|
||||
// all items of both traders in case the referral ID was only set by one trader.
|
||||
// If both traders had set it the tradeStatistics is only delivered once.
|
||||
// If both traders used a differnet refferral ID then we would get 2 objects.
|
||||
List<String> list = p2PService.getP2PDataStorage().getPersistableNetworkPayloadList().getMap().values().stream()
|
||||
.filter(e -> e instanceof TradeStatistics2)
|
||||
.map(e -> (TradeStatistics2) e)
|
||||
.filter(tradeStatistics2 -> tradeStatistics2.getExtraDataMap() != null)
|
||||
.filter(tradeStatistics2 -> tradeStatistics2.getExtraDataMap().get(OfferPayload.REFERRAL_ID) != null)
|
||||
.map(trade -> {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Trade ID: ").append(trade.getOfferId()).append("\n")
|
||||
.append("Date: ").append(formatter.formatDateTime(trade.getTradeDate())).append("\n")
|
||||
.append("Market: ").append(formatter.getCurrencyPair(trade.getCurrencyCode())).append("\n")
|
||||
.append("Price: ").append(formatter.formatPrice(trade.getTradePrice())).append("\n")
|
||||
.append("Amount: ").append(formatter.formatCoin(trade.getTradeAmount())).append("\n")
|
||||
.append("Volume: ").append(formatter.formatVolume(trade.getTradeVolume())).append("\n")
|
||||
.append("Payment method: ").append(Res.get(trade.getOfferPaymentMethod())).append("\n")
|
||||
.append("ReferralID: ").append(trade.getExtraDataMap().get(OfferPayload.REFERRAL_ID));
|
||||
return sb.toString();
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
return Joiner.on("\n\n").join(list);
|
||||
}
|
||||
|
||||
private String getAllOffersWithReferralId() {
|
||||
List<String> list = offerBook.getOfferBookListItems().stream()
|
||||
.map(offerBookListItem -> offerBookListItem.getOffer())
|
||||
.filter(offer -> offer.getOfferPayload().getExtraDataMap() != null)
|
||||
.filter(offer -> offer.getOfferPayload().getExtraDataMap().get(OfferPayload.REFERRAL_ID) != null)
|
||||
.map(offer -> {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Offer ID: ").append(offer.getId()).append("\n")
|
||||
.append("Type: ").append(offer.getDirection().name()).append("\n")
|
||||
.append("Market: ").append(formatter.getCurrencyPair(offer.getCurrencyCode())).append("\n")
|
||||
.append("Price: ").append(formatter.formatPrice(offer.getPrice())).append("\n")
|
||||
.append("Amount: ").append(formatter.formatAmount(offer)).append(" BTC\n")
|
||||
.append("Payment method: ").append(Res.get(offer.getPaymentMethod().getId())).append("\n")
|
||||
.append("ReferralID: ").append(offer.getOfferPayload().getExtraDataMap().get(OfferPayload.REFERRAL_ID));
|
||||
return sb.toString();
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
return Joiner.on("\n\n").join(list);
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ import bisq.core.payment.SpecificBanksAccount;
|
||||
import bisq.core.provider.fee.FeeService;
|
||||
import bisq.core.provider.price.PriceFeedService;
|
||||
import bisq.core.trade.handlers.TransactionResultHandler;
|
||||
import bisq.core.trade.statistics.ReferralIdService;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.user.User;
|
||||
|
||||
@ -86,6 +87,7 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -107,6 +109,7 @@ public abstract class EditableOfferDataModel extends OfferDataModel implements B
|
||||
private final AccountAgeWitnessService accountAgeWitnessService;
|
||||
private final TradeWalletService tradeWalletService;
|
||||
private final FeeService feeService;
|
||||
private final ReferralIdService referralIdService;
|
||||
private final BSFormatter formatter;
|
||||
private final String offerId;
|
||||
private final BalanceListener btcBalanceListener;
|
||||
@ -147,7 +150,7 @@ public abstract class EditableOfferDataModel extends OfferDataModel implements B
|
||||
Preferences preferences, User user, KeyRing keyRing, P2PService p2PService,
|
||||
PriceFeedService priceFeedService, FilterManager filterManager,
|
||||
AccountAgeWitnessService accountAgeWitnessService, TradeWalletService tradeWalletService,
|
||||
FeeService feeService, BSFormatter formatter) {
|
||||
FeeService feeService, ReferralIdService referralIdService, BSFormatter formatter) {
|
||||
super(btcWalletService);
|
||||
|
||||
this.openOfferManager = openOfferManager;
|
||||
@ -161,6 +164,7 @@ public abstract class EditableOfferDataModel extends OfferDataModel implements B
|
||||
this.accountAgeWitnessService = accountAgeWitnessService;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
this.feeService = feeService;
|
||||
this.referralIdService = referralIdService;
|
||||
this.formatter = formatter;
|
||||
|
||||
offerId = Utilities.getRandomPrefix(5, 8) + "-" +
|
||||
@ -357,13 +361,19 @@ public abstract class EditableOfferDataModel extends OfferDataModel implements B
|
||||
long lowerClosePrice = 0;
|
||||
long upperClosePrice = 0;
|
||||
String hashOfChallenge = null;
|
||||
HashMap<String, String> extraDataMap = null;
|
||||
Map<String, String> extraDataMap = null;
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode)) {
|
||||
extraDataMap = new HashMap<>();
|
||||
final String myWitnessHashAsHex = accountAgeWitnessService.getMyWitnessHashAsHex(paymentAccount.getPaymentAccountPayload());
|
||||
extraDataMap.put(OfferPayload.ACCOUNT_AGE_WITNESS_HASH, myWitnessHashAsHex);
|
||||
}
|
||||
|
||||
if (referralIdService.getOptionalReferralId().isPresent()) {
|
||||
if (extraDataMap == null)
|
||||
extraDataMap = new HashMap<>();
|
||||
extraDataMap.put(OfferPayload.REFERRAL_ID, referralIdService.getOptionalReferralId().get());
|
||||
}
|
||||
|
||||
Coin buyerSecurityDepositAsCoin = buyerSecurityDeposit.get();
|
||||
checkArgument(buyerSecurityDepositAsCoin.compareTo(Restrictions.getMaxBuyerSecurityDeposit()) <= 0,
|
||||
"securityDeposit must be not exceed " +
|
||||
|
@ -28,6 +28,7 @@ import bisq.core.offer.OpenOfferManager;
|
||||
import bisq.core.payment.AccountAgeWitnessService;
|
||||
import bisq.core.provider.fee.FeeService;
|
||||
import bisq.core.provider.price.PriceFeedService;
|
||||
import bisq.core.trade.statistics.ReferralIdService;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.user.User;
|
||||
|
||||
@ -45,7 +46,7 @@ import com.google.inject.Inject;
|
||||
class CreateOfferDataModel extends EditableOfferDataModel {
|
||||
|
||||
@Inject
|
||||
public CreateOfferDataModel(OpenOfferManager openOfferManager, BtcWalletService btcWalletService, BsqWalletService bsqWalletService, Preferences preferences, User user, KeyRing keyRing, P2PService p2PService, PriceFeedService priceFeedService, FilterManager filterManager, AccountAgeWitnessService accountAgeWitnessService, TradeWalletService tradeWalletService, FeeService feeService, BSFormatter formatter) {
|
||||
super(openOfferManager, btcWalletService, bsqWalletService, preferences, user, keyRing, p2PService, priceFeedService, filterManager, accountAgeWitnessService, tradeWalletService, feeService, formatter);
|
||||
public CreateOfferDataModel(OpenOfferManager openOfferManager, BtcWalletService btcWalletService, BsqWalletService bsqWalletService, Preferences preferences, User user, KeyRing keyRing, P2PService p2PService, PriceFeedService priceFeedService, FilterManager filterManager, AccountAgeWitnessService accountAgeWitnessService, TradeWalletService tradeWalletService, FeeService feeService, ReferralIdService referralIdService, BSFormatter formatter) {
|
||||
super(openOfferManager, btcWalletService, bsqWalletService, preferences, user, keyRing, p2PService, priceFeedService, filterManager, accountAgeWitnessService, tradeWalletService, feeService, referralIdService, formatter);
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import bisq.core.payment.AccountAgeWitnessService;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.provider.fee.FeeService;
|
||||
import bisq.core.provider.price.PriceFeedService;
|
||||
import bisq.core.trade.statistics.ReferralIdService;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.user.User;
|
||||
|
||||
@ -52,8 +53,8 @@ class EditOpenOfferDataModel extends EditableOfferDataModel {
|
||||
private OpenOffer.State initialState;
|
||||
|
||||
@Inject
|
||||
EditOpenOfferDataModel(OpenOfferManager openOfferManager, BtcWalletService btcWalletService, BsqWalletService bsqWalletService, Preferences preferences, User user, KeyRing keyRing, P2PService p2PService, PriceFeedService priceFeedService, FilterManager filterManager, AccountAgeWitnessService accountAgeWitnessService, TradeWalletService tradeWalletService, FeeService feeService, BSFormatter formatter) {
|
||||
super(openOfferManager, btcWalletService, bsqWalletService, preferences, user, keyRing, p2PService, priceFeedService, filterManager, accountAgeWitnessService, tradeWalletService, feeService, formatter);
|
||||
EditOpenOfferDataModel(OpenOfferManager openOfferManager, BtcWalletService btcWalletService, BsqWalletService bsqWalletService, Preferences preferences, User user, KeyRing keyRing, P2PService p2PService, PriceFeedService priceFeedService, FilterManager filterManager, AccountAgeWitnessService accountAgeWitnessService, TradeWalletService tradeWalletService, FeeService feeService, ReferralIdService referralIdService, BSFormatter formatter) {
|
||||
super(openOfferManager, btcWalletService, bsqWalletService, preferences, user, keyRing, p2PService, priceFeedService, filterManager, accountAgeWitnessService, tradeWalletService, feeService, referralIdService, formatter);
|
||||
}
|
||||
|
||||
public void initWithData(OpenOffer openOffer) {
|
||||
|
@ -40,6 +40,7 @@ import bisq.core.locale.LanguageUtil;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.locale.TradeCurrency;
|
||||
import bisq.core.provider.fee.FeeService;
|
||||
import bisq.core.trade.statistics.ReferralIdService;
|
||||
import bisq.core.user.BlockChainExplorer;
|
||||
import bisq.core.user.Preferences;
|
||||
|
||||
@ -95,11 +96,11 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
||||
|
||||
private CheckBox useAnimationsCheckBox, autoSelectArbitratorsCheckBox, showOwnOffersInOfferBook, sortMarketCurrenciesNumericallyCheckBox, useCustomFeeCheckbox;
|
||||
private int gridRow = 0;
|
||||
private InputTextField transactionFeeInputTextField, ignoreTradersListInputTextField;
|
||||
private InputTextField transactionFeeInputTextField, ignoreTradersListInputTextField, referralIdInputTextField;
|
||||
private ChangeListener<Boolean> transactionFeeFocusedListener;
|
||||
private final Preferences preferences;
|
||||
private final FeeService feeService;
|
||||
private final BisqEnvironment bisqEnvironment;
|
||||
private final ReferralIdService referralIdService;
|
||||
private final BSFormatter formatter;
|
||||
|
||||
private ListView<FiatCurrency> fiatCurrenciesListView;
|
||||
@ -117,7 +118,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
||||
private ObservableList<CryptoCurrency> allCryptoCurrencies;
|
||||
private ObservableList<TradeCurrency> tradeCurrencies;
|
||||
private InputTextField deviationInputTextField;
|
||||
private ChangeListener<String> deviationListener, ignoreTradersListListener;
|
||||
private ChangeListener<String> deviationListener, ignoreTradersListListener, referralIdListener;
|
||||
private ChangeListener<Boolean> deviationFocusedListener;
|
||||
private ChangeListener<Boolean> useCustomFeeCheckboxListener;
|
||||
private ChangeListener<Number> transactionFeeChangeListener;
|
||||
@ -127,12 +128,12 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public PreferencesView(Preferences preferences, FeeService feeService,
|
||||
BisqEnvironment bisqEnvironment, BSFormatter formatter) {
|
||||
public PreferencesView(Preferences preferences, FeeService feeService, ReferralIdService referralIdService,
|
||||
BSFormatter formatter) {
|
||||
super();
|
||||
this.preferences = preferences;
|
||||
this.feeService = feeService;
|
||||
this.bisqEnvironment = bisqEnvironment;
|
||||
this.referralIdService = referralIdService;
|
||||
this.formatter = formatter;
|
||||
}
|
||||
|
||||
@ -176,7 +177,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void initializeGeneralOptions() {
|
||||
TitledGroupBg titledGroupBg = addTitledGroupBg(root, gridRow, 7, Res.get("setting.preferences.general"));
|
||||
TitledGroupBg titledGroupBg = addTitledGroupBg(root, gridRow, 8, Res.get("setting.preferences.general"));
|
||||
GridPane.setColumnSpan(titledGroupBg, 4);
|
||||
|
||||
// selectBaseCurrencyNetwork
|
||||
@ -298,6 +299,13 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
||||
preferences.setIgnoreTradersList(Arrays.asList(StringUtils.deleteWhitespace(newValue)
|
||||
.replace(":9999", "").replace(".onion", "")
|
||||
.split(",")));
|
||||
|
||||
// referralId
|
||||
referralIdInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("setting.preferences.refererId")).second;
|
||||
referralIdListener = (observable, oldValue, newValue) -> {
|
||||
if (!newValue.equals(oldValue))
|
||||
referralIdService.setReferralId(newValue);
|
||||
};
|
||||
}
|
||||
|
||||
private void initializeDisplayCurrencies() {
|
||||
@ -496,7 +504,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
||||
|
||||
transactionFeeInputTextField.setText(String.valueOf(getTxFeeForWithdrawalPerByte()));
|
||||
ignoreTradersListInputTextField.setText(preferences.getIgnoreTradersList().stream().collect(Collectors.joining(", ")));
|
||||
|
||||
referralIdService.getOptionalReferralId().ifPresent(referralId -> referralIdInputTextField.setText(referralId));
|
||||
userLanguageComboBox.setItems(languageCodes);
|
||||
userLanguageComboBox.getSelectionModel().select(preferences.getUserLanguage());
|
||||
userLanguageComboBox.setConverter(new StringConverter<String>() {
|
||||
@ -574,6 +582,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
||||
transactionFeeInputTextField.focusedProperty().addListener(transactionFeeFocusedListener);
|
||||
ignoreTradersListInputTextField.textProperty().addListener(ignoreTradersListListener);
|
||||
useCustomFeeCheckbox.selectedProperty().addListener(useCustomFeeCheckboxListener);
|
||||
referralIdInputTextField.textProperty().addListener(referralIdListener);
|
||||
}
|
||||
|
||||
private Coin getTxFeeForWithdrawalPerByte() {
|
||||
@ -678,6 +687,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
||||
feeService.feeUpdateCounterProperty().removeListener(transactionFeeChangeListener);
|
||||
ignoreTradersListInputTextField.textProperty().removeListener(ignoreTradersListListener);
|
||||
useCustomFeeCheckbox.selectedProperty().removeListener(useCustomFeeCheckboxListener);
|
||||
referralIdInputTextField.textProperty().removeListener(referralIdListener);
|
||||
}
|
||||
|
||||
private void deactivateDisplayCurrencies() {
|
||||
|
Loading…
Reference in New Issue
Block a user