register and add bitcoin: uri handler, register aopp: handler

This commit is contained in:
Craig Raw 2021-05-06 14:21:56 +02:00
parent 07012615ff
commit e5dd33d5a1
11 changed files with 121 additions and 4 deletions

View file

@ -164,7 +164,7 @@ jlink {
appVersion = "${sparrowVersion}" appVersion = "${sparrowVersion}"
skipInstaller = os.macOsX skipInstaller = os.macOsX
imageOptions = [] imageOptions = []
installerOptions = ['--file-associations', 'src/main/deploy/associations.properties', '--license-file', 'LICENSE'] installerOptions = ['--file-associations', 'src/main/deploy/psbt.properties', '--file-associations', 'src/main/deploy/bitcoin.properties', '--file-associations', 'src/main/deploy/aopp.properties', '--license-file', 'LICENSE']
if(os.windows) { if(os.windows) {
installerOptions += ['--win-per-user-install', '--win-dir-chooser', '--win-menu', '--win-shortcut'] installerOptions += ['--win-per-user-install', '--win-dir-chooser', '--win-menu', '--win-shortcut']
imageOptions += ['--icon', 'src/main/deploy/package/windows/sparrow.ico'] imageOptions += ['--icon', 'src/main/deploy/package/windows/sparrow.ico']

2
drongo

@ -1 +1 @@
Subproject commit db9617ee10383bb78e71ec2252d92bb7fe639440 Subproject commit cc32285d58fcd1120b27797ff1d882ae4ae8a1ed

View file

@ -0,0 +1,2 @@
mime-type=x-scheme-handler/aopp
description=Verify Address Ownership URI

View file

@ -0,0 +1,2 @@
mime-type=x-scheme-handler/bitcoin
description=Bitcoin Scheme URI

View file

@ -35,5 +35,24 @@
<string>true</string> <string>true</string>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>Sparrow requires access to the camera in order to scan QR codes</string> <string>Sparrow requires access to the camera in order to scan QR codes</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.sparrowwallet.sparrow.bitcoin</string>
<key>CFBundleURLSchemes</key>
<array>
<string>bitcoin</string>
</array>
</dict>
<dict>
<key>CFBundleURLName</key>
<string>com.sparrowwallet.sparrow.aopp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>aopp</string>
</array>
</dict>
</array>
</dict> </dict>
</plist> </plist>

View file

@ -1,3 +1,3 @@
extension=psbt
mime-type=application/octet-stream mime-type=application/octet-stream
extension=psbt
description=Partially Signed Bitcoin Transaction description=Partially Signed Bitcoin Transaction

View file

@ -1795,4 +1795,9 @@ public class AppController implements Initializable {
openTransactionFromQR(null); openTransactionFromQR(null);
} }
} }
@Subscribe
public void sendAction(SendActionEvent event) {
selectTab(event.getWallet());
}
} }

View file

@ -29,7 +29,10 @@ import javafx.scene.Node;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.text.Font; import javafx.scene.text.Font;
import javafx.stage.Screen; import javafx.stage.Screen;
import javafx.stage.Stage; import javafx.stage.Stage;
@ -40,14 +43,17 @@ import org.controlsfx.control.HyperlinkLabel;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.awt.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Proxy; import java.net.Proxy;
import java.net.URI;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -135,6 +141,8 @@ public class AppServices {
restartServices(); restartServices();
} }
} }
addURIHandlers();
} }
private void restartServices() { private void restartServices() {
@ -591,6 +599,50 @@ public class AppServices {
} }
} }
public static void addURIHandlers() {
Desktop.getDesktop().setOpenURIHandler(event -> {
URI uri = event.getURI();
if("bitcoin".equals(uri.getScheme())) {
Platform.runLater(() -> openBitcoinUri(uri));
} else if("aopp".equals(uri.getScheme())) {
log.info(uri.toString());
}
});
}
private static void openBitcoinUri(URI uri) {
try {
BitcoinURI bitcoinURI = new BitcoinURI(uri.toString());
Wallet wallet = null;
Set<Wallet> wallets = get().getOpenWallets().keySet();
if(wallets.isEmpty()) {
showErrorDialog("No wallet available", "Open a wallet to send to the provided bitcoin URI.");
} else if(wallets.size() == 1) {
wallet = wallets.iterator().next();
} else {
ChoiceDialog<Wallet> walletChoiceDialog = new ChoiceDialog<>(wallets.iterator().next(), wallets);
walletChoiceDialog.setTitle("Choose Wallet");
walletChoiceDialog.setHeaderText("Choose a wallet to pay from");
Image image = new Image("/image/sparrow-small.png");
walletChoiceDialog.getDialogPane().setGraphic(new ImageView(image));
AppServices.setStageIcon(walletChoiceDialog.getDialogPane().getScene().getWindow());
Optional<Wallet> optWallet = walletChoiceDialog.showAndWait();
if(optWallet.isPresent()) {
wallet = optWallet.get();
}
}
if(wallet != null) {
final Wallet sendingWallet = wallet;
EventManager.get().post(new SendActionEvent(sendingWallet, new ArrayList<>(sendingWallet.getWalletUtxos().keySet())));
Platform.runLater(() -> EventManager.get().post(new SendPaymentsEvent(sendingWallet, List.of(bitcoinURI.toPayment()))));
}
} catch(Exception e) {
showErrorDialog("Not a valid bitcoin URI", e.getMessage());
}
}
public static Font getMonospaceFont() { public static Font getMonospaceFont() {
return Font.font("Roboto Mono", 13); return Font.font("Roboto Mono", 13);
} }

View file

@ -0,0 +1,24 @@
package com.sparrowwallet.sparrow.event;
import com.sparrowwallet.drongo.wallet.Payment;
import com.sparrowwallet.drongo.wallet.Wallet;
import java.util.List;
public class SendPaymentsEvent {
private final Wallet wallet;
private final List<Payment> payments;
public SendPaymentsEvent(Wallet wallet, List<Payment> payments) {
this.wallet = wallet;
this.payments = payments;
}
public Wallet getWallet() {
return wallet;
}
public List<Payment> getPayments() {
return payments;
}
}

View file

@ -282,7 +282,9 @@ public class PaymentController extends WalletFormController implements Initializ
if(payment.getLabel() != null) { if(payment.getLabel() != null) {
label.setText(payment.getLabel()); label.setText(payment.getLabel());
} }
if(payment.getAmount() >= 0) {
setRecipientValueSats(payment.getAmount()); setRecipientValueSats(payment.getAmount());
}
setFiatAmount(AppServices.getFiatCurrencyExchangeRate(), payment.getAmount()); setFiatAmount(AppServices.getFiatCurrencyExchangeRate(), payment.getAmount());
} }
} }

View file

@ -1074,6 +1074,17 @@ public class SendController extends WalletFormController implements Initializabl
} }
} }
@Subscribe
public void sendPayments(SendPaymentsEvent event) {
if(event.getWallet().equals(getWalletForm().getWallet())) {
if(event.getPayments() != null) {
clear(null);
setPayments(event.getPayments());
updateTransaction(event.getPayments() == null || event.getPayments().stream().anyMatch(Payment::isSendMax));
}
}
}
@Subscribe @Subscribe
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) { public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
BitcoinUnit unit = getBitcoinUnit(event.getBitcoinUnit()); BitcoinUnit unit = getBitcoinUnit(event.getBitcoinUnit());