mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-02 20:36:44 +00:00
refactor cardapi to generic service
This commit is contained in:
parent
057a9efb1f
commit
300545b289
17 changed files with 163 additions and 79 deletions
|
@ -14,7 +14,6 @@ import com.sparrowwallet.drongo.policy.PolicyType;
|
|||
import com.sparrowwallet.drongo.wallet.*;
|
||||
import com.sparrowwallet.sparrow.control.WalletPasswordDialog;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||
import com.sparrowwallet.sparrow.io.ckcard.CardApi;
|
||||
import com.sparrowwallet.sparrow.net.Auth47;
|
||||
import com.sparrowwallet.drongo.protocol.BlockHeader;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
|
|
|
@ -11,9 +11,10 @@ import com.sparrowwallet.sparrow.EventManager;
|
|||
import com.sparrowwallet.sparrow.event.KeystoreImportEvent;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||
import com.sparrowwallet.sparrow.io.KeystoreCardImport;
|
||||
import com.sparrowwallet.sparrow.io.ckcard.CardAuthorizationException;
|
||||
import com.sparrowwallet.sparrow.io.CardAuthorizationException;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.geometry.Insets;
|
||||
|
@ -81,10 +82,11 @@ public class CardImportPane extends TitledDescriptionPane {
|
|||
return;
|
||||
}
|
||||
|
||||
CardImportService cardImportService = new CardImportService(importer, pin.get(), derivation);
|
||||
cardImportService.messageProperty().addListener((observable, oldValue, newValue) -> {
|
||||
setDescription(newValue);
|
||||
StringProperty messageProperty = new SimpleStringProperty();
|
||||
messageProperty.addListener((observable, oldValue, newValue) -> {
|
||||
Platform.runLater(() -> setDescription(newValue));
|
||||
});
|
||||
CardImportService cardImportService = new CardImportService(importer, pin.get(), derivation, messageProperty);
|
||||
cardImportService.setOnSucceeded(event -> {
|
||||
EventManager.get().post(new KeystoreImportEvent(cardImportService.getValue()));
|
||||
});
|
||||
|
@ -193,11 +195,13 @@ public class CardImportPane extends TitledDescriptionPane {
|
|||
private final KeystoreCardImport cardImport;
|
||||
private final String pin;
|
||||
private final List<ChildNumber> derivation;
|
||||
private final StringProperty messageProperty;
|
||||
|
||||
public CardImportService(KeystoreCardImport cardImport, String pin, List<ChildNumber> derivation) {
|
||||
public CardImportService(KeystoreCardImport cardImport, String pin, List<ChildNumber> derivation, StringProperty messageProperty) {
|
||||
this.cardImport = cardImport;
|
||||
this.pin = pin;
|
||||
this.derivation = derivation;
|
||||
this.messageProperty = messageProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -205,10 +209,7 @@ public class CardImportPane extends TitledDescriptionPane {
|
|||
return new Task<>() {
|
||||
@Override
|
||||
protected Keystore call() throws Exception {
|
||||
cardImport.messageProperty().addListener((observable, oldValue, newValue) -> {
|
||||
updateMessage(newValue);
|
||||
});
|
||||
return cardImport.getKeystore(pin, derivation);
|
||||
return cardImport.getKeystore(pin, derivation, messageProperty);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -14,13 +14,11 @@ import com.sparrowwallet.drongo.wallet.*;
|
|||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.event.*;
|
||||
import com.sparrowwallet.sparrow.io.CardApi;
|
||||
import com.sparrowwallet.sparrow.io.Device;
|
||||
import com.sparrowwallet.sparrow.io.Hwi;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||
import com.sparrowwallet.sparrow.io.KeystoreCardImport;
|
||||
import com.sparrowwallet.sparrow.io.ckcard.CardApi;
|
||||
import com.sparrowwallet.sparrow.io.ckcard.CardAuthorizationException;
|
||||
import com.sparrowwallet.sparrow.io.ckcard.CkCard;
|
||||
import com.sparrowwallet.sparrow.io.CardAuthorizationException;
|
||||
import com.sparrowwallet.sparrow.net.ElectrumServer;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
@ -579,19 +577,16 @@ public class DevicePane extends TitledDescriptionPane {
|
|||
private void importKeystore(List<ChildNumber> derivation) {
|
||||
if(device.isCard()) {
|
||||
try {
|
||||
CkCard importer = new CkCard();
|
||||
if(!importer.isInitialized()) {
|
||||
CardApi cardApi = CardApi.getCardApi(device.getModel(), pin.get());
|
||||
if(!cardApi.isInitialized()) {
|
||||
setDescription("Card not initialized");
|
||||
setContent(getCardInitializationPanel(importer));
|
||||
setContent(getCardInitializationPanel(cardApi));
|
||||
showHideLink.setVisible(false);
|
||||
setExpanded(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Service<Keystore> importService = new CardImportPane.CardImportService(importer, pin.get(), derivation);
|
||||
importService.messageProperty().addListener((observable, oldValue, newValue) -> {
|
||||
messageProperty.set(newValue);
|
||||
});
|
||||
Service<Keystore> importService = cardApi.getImportService(derivation, messageProperty);
|
||||
handleCardOperation(importService, importButton, "Import", event -> {
|
||||
importKeystore(derivation, importService.getValue());
|
||||
});
|
||||
|
@ -669,7 +664,7 @@ public class DevicePane extends TitledDescriptionPane {
|
|||
private void sign() {
|
||||
if(device.isCard()) {
|
||||
try {
|
||||
CardApi cardApi = new CardApi(pin.get());
|
||||
CardApi cardApi = CardApi.getCardApi(device.getModel(), pin.get());
|
||||
Service<PSBT> signService = cardApi.getSignService(wallet, psbt, messageProperty);
|
||||
handleCardOperation(signService, signButton, "Signing", event -> {
|
||||
EventManager.get().post(new PSBTSignedEvent(psbt, signService.getValue()));
|
||||
|
@ -738,7 +733,7 @@ public class DevicePane extends TitledDescriptionPane {
|
|||
private void signMessage() {
|
||||
if(device.isCard()) {
|
||||
try {
|
||||
CardApi cardApi = new CardApi(pin.get());
|
||||
CardApi cardApi = CardApi.getCardApi(device.getModel(), pin.get());
|
||||
Service<String> signMessageService = cardApi.getSignMessageService(message, wallet.getScriptType(), keyDerivation.getDerivation(), messageProperty);
|
||||
handleCardOperation(signMessageService, signMessageButton, "Signing", event -> {
|
||||
String signature = signMessageService.getValue();
|
||||
|
@ -889,7 +884,7 @@ public class DevicePane extends TitledDescriptionPane {
|
|||
return contentBox;
|
||||
}
|
||||
|
||||
private Node getCardInitializationPanel(KeystoreCardImport importer) {
|
||||
private Node getCardInitializationPanel(CardApi cardApi) {
|
||||
VBox initTypeBox = new VBox(5);
|
||||
RadioButton automatic = new RadioButton("Automatic (Recommended)");
|
||||
RadioButton advanced = new RadioButton("Advanced");
|
||||
|
@ -911,7 +906,7 @@ public class DevicePane extends TitledDescriptionPane {
|
|||
initializeButton.setDefaultButton(true);
|
||||
initializeButton.setOnAction(event -> {
|
||||
byte[] chainCode = toggleGroup.getSelectedToggle() == automatic ? null : Sha256Hash.hashTwice(entropy.getText().getBytes(StandardCharsets.UTF_8));
|
||||
CardImportPane.CardInitializationService cardInitializationService = new CardImportPane.CardInitializationService(importer, chainCode);
|
||||
Service<Void> cardInitializationService = cardApi.getInitializationService(chainCode);
|
||||
cardInitializationService.setOnSucceeded(event1 -> {
|
||||
AppServices.showSuccessDialog("Card Initialized", "The card was successfully initialized.\n\nYou will now need to enter the PIN code found on the back. You can change the PIN code once it has been imported.");
|
||||
setDescription("Enter PIN code");
|
||||
|
|
|
@ -3,16 +3,12 @@ package com.sparrowwallet.sparrow.control;
|
|||
import com.google.common.eventbus.Subscribe;
|
||||
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import com.sparrowwallet.drongo.wallet.WalletModel;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.event.PSBTSignedEvent;
|
||||
import com.sparrowwallet.sparrow.io.Device;
|
||||
import com.sparrowwallet.sparrow.io.ckcard.CardApi;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.smartcardio.CardException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DeviceSignDialog extends DeviceDialog<PSBT> {
|
||||
|
|
78
src/main/java/com/sparrowwallet/sparrow/io/CardApi.java
Normal file
78
src/main/java/com/sparrowwallet/sparrow/io/CardApi.java
Normal file
|
@ -0,0 +1,78 @@
|
|||
package com.sparrowwallet.sparrow.io;
|
||||
|
||||
import com.sparrowwallet.drongo.crypto.ChildNumber;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import com.sparrowwallet.drongo.wallet.WalletModel;
|
||||
import com.sparrowwallet.sparrow.io.ckcard.CkCardApi;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.concurrent.Service;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.smartcardio.CardException;
|
||||
import javax.smartcardio.TerminalFactory;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class CardApi {
|
||||
private static final Logger log = LoggerFactory.getLogger(CardApi.class);
|
||||
|
||||
public static List<WalletModel> getConnectedCards() throws CardException {
|
||||
try {
|
||||
CkCardApi ckCardApi = new CkCardApi(null, null);
|
||||
return List.of(ckCardApi.getCardType());
|
||||
} catch(Exception e) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public static CardApi getCardApi(WalletModel walletModel, String pin) throws CardException {
|
||||
if(walletModel == WalletModel.TAPSIGNER || walletModel == WalletModel.SATSCARD) {
|
||||
return new CkCardApi(walletModel, pin);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Cannot create card API for " + walletModel.toDisplayString());
|
||||
}
|
||||
|
||||
public abstract boolean isInitialized() throws CardException;
|
||||
|
||||
public abstract void initialize(byte[] entropy) throws CardException;
|
||||
|
||||
public abstract WalletModel getCardType() throws CardException;
|
||||
|
||||
public abstract Service<Void> getAuthDelayService() throws CardException;
|
||||
|
||||
public abstract boolean requiresBackup() throws CardException;
|
||||
|
||||
public abstract Service<String> getBackupService();
|
||||
|
||||
public abstract boolean changePin(String newPin) throws CardException;
|
||||
|
||||
public abstract Keystore getKeystore() throws CardException;
|
||||
|
||||
public abstract Service<Void> getInitializationService(byte[] entropy);
|
||||
|
||||
public abstract Service<Keystore> getImportService(List<ChildNumber> derivation, StringProperty messageProperty);
|
||||
|
||||
public abstract Service<PSBT> getSignService(Wallet wallet, PSBT psbt, StringProperty messageProperty);
|
||||
|
||||
public abstract Service<String> getSignMessageService(String message, ScriptType scriptType, List<ChildNumber> derivation, StringProperty messageProperty);
|
||||
|
||||
public abstract void disconnect();
|
||||
|
||||
public static boolean isReaderAvailable() {
|
||||
try {
|
||||
TerminalFactory tf = TerminalFactory.getDefault();
|
||||
return !tf.terminals().list().isEmpty();
|
||||
} catch(Exception e) {
|
||||
log.error("Error detecting card terminals", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.sparrowwallet.sparrow.io.ckcard;
|
||||
package com.sparrowwallet.sparrow.io;
|
||||
|
||||
import javax.smartcardio.CardException;
|
||||
|
|
@ -1,11 +1,8 @@
|
|||
package com.sparrowwallet.sparrow.io;
|
||||
|
||||
import javafx.beans.property.StringProperty;
|
||||
|
||||
import javax.smartcardio.CardException;
|
||||
|
||||
public interface CardImport extends ImportExport {
|
||||
boolean isInitialized() throws CardException;
|
||||
void initialize(byte[] chainCode) throws CardException;
|
||||
StringProperty messageProperty();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.sparrowwallet.sparrow.io.ckcard;
|
||||
package com.sparrowwallet.sparrow.io;
|
||||
|
||||
import javax.smartcardio.CardException;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.sparrowwallet.sparrow.io.ckcard;
|
||||
package com.sparrowwallet.sparrow.io;
|
||||
|
||||
import javax.smartcardio.CardException;
|
||||
|
|
@ -10,7 +10,6 @@ import com.sparrowwallet.drongo.psbt.PSBT;
|
|||
import com.sparrowwallet.drongo.psbt.PSBTParseException;
|
||||
import com.sparrowwallet.drongo.wallet.StandardAccount;
|
||||
import com.sparrowwallet.drongo.wallet.WalletModel;
|
||||
import com.sparrowwallet.sparrow.io.ckcard.CardApi;
|
||||
import javafx.concurrent.ScheduledService;
|
||||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
|
@ -98,16 +97,19 @@ public class Hwi {
|
|||
List<Device> devices = new ArrayList<>();
|
||||
if(CardApi.isReaderAvailable()) {
|
||||
try {
|
||||
CardApi cardApi = new CardApi(null);
|
||||
WalletModel walletModel = cardApi.getCardType();
|
||||
List<WalletModel> connectedCards = CardApi.getConnectedCards();
|
||||
for(WalletModel card : connectedCards) {
|
||||
CardApi cardApi = CardApi.getCardApi(card, null);
|
||||
WalletModel walletModel = cardApi.getCardType();
|
||||
|
||||
Device cardDevice = new Device();
|
||||
cardDevice.setType(walletModel.getType());
|
||||
cardDevice.setModel(walletModel);
|
||||
cardDevice.setNeedsPassphraseSent(Boolean.FALSE);
|
||||
cardDevice.setNeedsPinSent(Boolean.FALSE);
|
||||
cardDevice.setCard(true);
|
||||
devices.add(cardDevice);
|
||||
Device cardDevice = new Device();
|
||||
cardDevice.setType(walletModel.getType());
|
||||
cardDevice.setModel(walletModel);
|
||||
cardDevice.setNeedsPassphraseSent(Boolean.FALSE);
|
||||
cardDevice.setNeedsPinSent(Boolean.FALSE);
|
||||
cardDevice.setCard(true);
|
||||
devices.add(cardDevice);
|
||||
}
|
||||
} catch(CardNotPresentException e) {
|
||||
//ignore
|
||||
} catch(CardException e) {
|
||||
|
|
|
@ -2,10 +2,11 @@ package com.sparrowwallet.sparrow.io;
|
|||
|
||||
import com.sparrowwallet.drongo.crypto.ChildNumber;
|
||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
import javafx.beans.property.StringProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface KeystoreCardImport extends CardImport {
|
||||
Keystore getKeystore(String pin, List<ChildNumber> derivation) throws ImportException;
|
||||
Keystore getKeystore(String pin, List<ChildNumber> derivation, StringProperty messageProperty) throws ImportException;
|
||||
String getKeystoreImportDescription(int account);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import com.sparrowwallet.drongo.crypto.ChildNumber;
|
|||
import com.sparrowwallet.drongo.crypto.ECDSASignature;
|
||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
||||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||
import com.sparrowwallet.sparrow.io.CardSignFailedException;
|
||||
import com.sparrowwallet.sparrow.io.CardUnluckyNumberException;
|
||||
import org.bitcoin.NativeSecp256k1;
|
||||
import org.bitcoin.NativeSecp256k1Util;
|
||||
import org.bitcoin.Secp256k1Context;
|
||||
|
|
|
@ -12,6 +12,8 @@ import com.google.gson.JsonElement;
|
|||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.sparrow.io.CardAuthorizationException;
|
||||
import com.sparrowwallet.sparrow.io.CardUnluckyNumberException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import com.sparrowwallet.drongo.psbt.PSBT;
|
|||
import com.sparrowwallet.drongo.psbt.PSBTInput;
|
||||
import com.sparrowwallet.drongo.psbt.PSBTInputSigner;
|
||||
import com.sparrowwallet.drongo.wallet.*;
|
||||
import com.sparrowwallet.sparrow.control.CardImportPane;
|
||||
import com.sparrowwallet.sparrow.io.CardApi;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
@ -24,33 +26,36 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CardApi {
|
||||
private static final Logger log = LoggerFactory.getLogger(CardApi.class);
|
||||
public class CkCardApi extends CardApi {
|
||||
private static final Logger log = LoggerFactory.getLogger(CkCardApi.class);
|
||||
|
||||
private final WalletModel cardType;
|
||||
private final CardProtocol cardProtocol;
|
||||
private String cvc;
|
||||
|
||||
public CardApi(String cvc) throws CardException {
|
||||
public CkCardApi(String cvc) throws CardException {
|
||||
this(WalletModel.TAPSIGNER, cvc);
|
||||
}
|
||||
|
||||
public CardApi(WalletModel cardType, String cvc) throws CardException {
|
||||
public CkCardApi(WalletModel cardType, String cvc) throws CardException {
|
||||
this.cardType = cardType;
|
||||
this.cardProtocol = new CardProtocol();
|
||||
this.cvc = cvc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() throws CardException {
|
||||
CardStatus cardStatus = getStatus();
|
||||
return cardStatus.isInitialized();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(byte[] chainCode) throws CardException {
|
||||
cardProtocol.verify();
|
||||
cardProtocol.setup(cvc, chainCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WalletModel getCardType() throws CardException {
|
||||
CardStatus cardStatus = getStatus();
|
||||
return cardStatus.getCardType();
|
||||
|
@ -58,7 +63,7 @@ public class CardApi {
|
|||
|
||||
CardStatus getStatus() throws CardException {
|
||||
CardStatus cardStatus = cardProtocol.getStatus();
|
||||
if(cardStatus.getCardType() != cardType) {
|
||||
if(cardType != null && cardStatus.getCardType() != cardType) {
|
||||
throw new CardException("Please use a " + cardType.toDisplayString() + " card.");
|
||||
}
|
||||
return cardStatus;
|
||||
|
@ -78,6 +83,7 @@ public class CardApi {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Service<Void> getAuthDelayService() throws CardException {
|
||||
CardStatus cardStatus = getStatus();
|
||||
if(cardStatus.auth_delay != null) {
|
||||
|
@ -87,11 +93,13 @@ public class CardApi {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresBackup() throws CardException {
|
||||
CardStatus cardStatus = getStatus();
|
||||
return cardStatus.requiresBackup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Service<String> getBackupService() {
|
||||
return new BackupService();
|
||||
}
|
||||
|
@ -101,6 +109,7 @@ public class CardApi {
|
|||
return Utils.bytesToHex(cardBackup.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean changePin(String newCvc) throws CardException {
|
||||
CardChange cardChange = cardProtocol.change(cvc, newCvc);
|
||||
if(cardChange.success) {
|
||||
|
@ -110,10 +119,21 @@ public class CardApi {
|
|||
return cardChange.success;
|
||||
}
|
||||
|
||||
public void setDerivation(List<ChildNumber> derivation) throws CardException {
|
||||
void setDerivation(List<ChildNumber> derivation) throws CardException {
|
||||
cardProtocol.derive(cvc, derivation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Service<Void> getInitializationService(byte[] entropy) {
|
||||
return new CardImportPane.CardInitializationService(new Tapsigner(), entropy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Service<Keystore> getImportService(List<ChildNumber> derivation, StringProperty messageProperty) {
|
||||
return new CardImportPane.CardImportService(new Tapsigner(), cvc, derivation, messageProperty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Keystore getKeystore() throws CardException {
|
||||
KeyDerivation keyDerivation = getKeyDerivation();
|
||||
|
||||
|
@ -141,6 +161,7 @@ public class CardApi {
|
|||
return Utils.bytesToHex(masterXpubkey.getKey().getFingerprint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Service<PSBT> getSignService(Wallet wallet, PSBT psbt, StringProperty messageProperty) {
|
||||
return new SignService(wallet, psbt, messageProperty);
|
||||
}
|
||||
|
@ -183,6 +204,7 @@ public class CardApi {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Service<String> getSignMessageService(String message, ScriptType scriptType, List<ChildNumber> derivation, StringProperty messageProperty) {
|
||||
return new SignMessageService(message, scriptType, derivation, messageProperty);
|
||||
}
|
||||
|
@ -217,6 +239,7 @@ public class CardApi {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
try {
|
||||
cardProtocol.disconnect();
|
||||
|
@ -225,10 +248,6 @@ public class CardApi {
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean isReaderAvailable() {
|
||||
return CardTransport.isReaderAvailable();
|
||||
}
|
||||
|
||||
public class AuthDelayService extends Service<Void> {
|
||||
private final CardStatus cardStatus;
|
||||
private final IntegerProperty delayProperty;
|
||||
|
@ -303,7 +322,7 @@ public class CardApi {
|
|||
@Override
|
||||
public TransactionSignature sign(Sha256Hash hash, SigHash sigHash, TransactionSignature.Type signatureType) {
|
||||
if(signatureType != TransactionSignature.Type.ECDSA) {
|
||||
throw new IllegalStateException(cardType.toDisplayString() + " cannot sign " + signatureType + " transactions.");
|
||||
throw new IllegalStateException(WalletModel.TAPSIGNER.toDisplayString() + " cannot sign " + signatureType + " transactions.");
|
||||
}
|
||||
|
||||
try {
|
|
@ -6,20 +6,17 @@ import com.sparrowwallet.drongo.wallet.WalletModel;
|
|||
import com.sparrowwallet.sparrow.io.KeystoreCardImport;
|
||||
import com.sparrowwallet.sparrow.io.ImportException;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
|
||||
import javax.smartcardio.CardException;
|
||||
import java.util.List;
|
||||
|
||||
public class CkCard implements KeystoreCardImport {
|
||||
private final StringProperty messageProperty = new SimpleStringProperty("");
|
||||
|
||||
public class Tapsigner implements KeystoreCardImport {
|
||||
@Override
|
||||
public boolean isInitialized() throws CardException {
|
||||
CardApi cardApi = null;
|
||||
CkCardApi cardApi = null;
|
||||
try {
|
||||
cardApi = new CardApi(null);
|
||||
cardApi = new CkCardApi(null);
|
||||
return cardApi.isInitialized();
|
||||
} finally {
|
||||
if(cardApi != null) {
|
||||
|
@ -30,9 +27,9 @@ public class CkCard implements KeystoreCardImport {
|
|||
|
||||
@Override
|
||||
public void initialize(byte[] chainCode) throws CardException {
|
||||
CardApi cardApi = null;
|
||||
CkCardApi cardApi = null;
|
||||
try {
|
||||
cardApi = new CardApi(null);
|
||||
cardApi = new CkCardApi(null);
|
||||
cardApi.initialize(chainCode);
|
||||
} finally {
|
||||
if(cardApi != null) {
|
||||
|
@ -42,7 +39,7 @@ public class CkCard implements KeystoreCardImport {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Keystore getKeystore(String pin, List<ChildNumber> derivation) throws ImportException {
|
||||
public Keystore getKeystore(String pin, List<ChildNumber> derivation, StringProperty messageProperty) throws ImportException {
|
||||
if(pin.length() < 6) {
|
||||
throw new ImportException("PIN too short.");
|
||||
}
|
||||
|
@ -51,9 +48,9 @@ public class CkCard implements KeystoreCardImport {
|
|||
throw new ImportException("PIN too long.");
|
||||
}
|
||||
|
||||
CardApi cardApi = null;
|
||||
CkCardApi cardApi = null;
|
||||
try {
|
||||
cardApi = new CardApi(pin);
|
||||
cardApi = new CkCardApi(pin);
|
||||
CardStatus cardStatus = cardApi.getStatus();
|
||||
if(!cardStatus.isInitialized()) {
|
||||
throw new IllegalStateException("Card is not initialized.");
|
||||
|
@ -87,9 +84,4 @@ public class CkCard implements KeystoreCardImport {
|
|||
public WalletModel getWalletModel() {
|
||||
return WalletModel.TAPSIGNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringProperty messageProperty() {
|
||||
return messageProperty;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ import com.sparrowwallet.sparrow.control.CardImportPane;
|
|||
import com.sparrowwallet.sparrow.control.FileKeystoreImportPane;
|
||||
import com.sparrowwallet.sparrow.control.TitledDescriptionPane;
|
||||
import com.sparrowwallet.sparrow.io.*;
|
||||
import com.sparrowwallet.sparrow.io.ckcard.CkCard;
|
||||
import com.sparrowwallet.sparrow.io.ckcard.Tapsigner;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Accordion;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -15,7 +15,7 @@ import java.util.Collections;
|
|||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.sparrowwallet.sparrow.io.ckcard.CardApi.isReaderAvailable;
|
||||
import static com.sparrowwallet.sparrow.io.CardApi.isReaderAvailable;
|
||||
|
||||
public class HwAirgappedController extends KeystoreImportDetailController {
|
||||
private static final Logger log = LoggerFactory.getLogger(HwAirgappedController.class);
|
||||
|
@ -42,7 +42,7 @@ public class HwAirgappedController extends KeystoreImportDetailController {
|
|||
|
||||
List<KeystoreCardImport> cardImporters = Collections.emptyList();
|
||||
if(isReaderAvailable()) {
|
||||
cardImporters = List.of(new CkCard());
|
||||
cardImporters = List.of(new Tapsigner());
|
||||
}
|
||||
for(KeystoreCardImport importer : cardImporters) {
|
||||
if(!importer.isDeprecated() || Config.get().isShowDeprecatedImportExport()) {
|
||||
|
|
|
@ -9,8 +9,8 @@ import com.sparrowwallet.sparrow.control.*;
|
|||
import com.sparrowwallet.sparrow.event.*;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
|
||||
import com.sparrowwallet.sparrow.io.CardApi;
|
||||
import com.sparrowwallet.sparrow.io.Storage;
|
||||
import com.sparrowwallet.sparrow.io.ckcard.CardApi;
|
||||
import com.sparrowwallet.sparrow.keystoreimport.KeystoreImportDialog;
|
||||
import javafx.application.Platform;
|
||||
import javafx.concurrent.Service;
|
||||
|
@ -37,7 +37,7 @@ import java.util.Optional;
|
|||
import java.util.ResourceBundle;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.sparrowwallet.sparrow.io.ckcard.CardApi.isReaderAvailable;
|
||||
import static com.sparrowwallet.sparrow.io.CardApi.isReaderAvailable;
|
||||
|
||||
public class KeystoreController extends WalletFormController implements Initializable {
|
||||
private static final Logger log = LoggerFactory.getLogger(KeystoreController.class);
|
||||
|
@ -427,7 +427,7 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
String newPin = optPinChange.get().newPin();
|
||||
boolean backupFirst = optPinChange.get().backupFirst();
|
||||
try {
|
||||
CardApi cardApi = new CardApi(currentPin);
|
||||
CardApi cardApi = CardApi.getCardApi(keystore.getWalletModel(), currentPin);
|
||||
Service<Void> authDelayService = cardApi.getAuthDelayService();
|
||||
if(authDelayService != null) {
|
||||
authDelayService.setOnSucceeded(event1 -> {
|
||||
|
|
Loading…
Reference in a new issue