Search in sources :

Example 21 with Address

use of com.sparrowwallet.drongo.address.Address in project sparrow by sparrowwallet.

the class AddressCell method updateItem.

@Override
protected void updateItem(UtxoEntry.AddressStatus addressStatus, boolean empty) {
    super.updateItem(addressStatus, empty);
    UtxoEntry utxoEntry = addressStatus == null ? null : addressStatus.getUtxoEntry();
    EntryCell.applyRowStyles(this, utxoEntry);
    if (empty) {
        setText(null);
        setGraphic(null);
    } else {
        if (utxoEntry != null) {
            Address address = addressStatus.getAddress();
            setText(address.toString());
            setContextMenu(new EntryCell.AddressContextMenu(address, utxoEntry.getOutputDescriptor(), new NodeEntry(utxoEntry.getWallet(), utxoEntry.getNode())));
            Tooltip tooltip = new Tooltip();
            tooltip.setShowDelay(Duration.millis(250));
            tooltip.setText(getTooltipText(utxoEntry, addressStatus.isDuplicate()));
            setTooltip(tooltip);
            if (addressStatus.isDuplicate()) {
                setGraphic(getDuplicateGlyph());
            } else {
                setGraphic(null);
            }
        }
    }
}
Also used : Address(com.sparrowwallet.drongo.address.Address) NodeEntry(com.sparrowwallet.sparrow.wallet.NodeEntry) Tooltip(javafx.scene.control.Tooltip) UtxoEntry(com.sparrowwallet.sparrow.wallet.UtxoEntry)

Example 22 with Address

use of com.sparrowwallet.drongo.address.Address in project sparrow by sparrowwallet.

the class Electrum method importWallet.

@Override
public Wallet importWallet(InputStream inputStream, String password) throws ImportException {
    Reader reader;
    if (password != null) {
        ECKey decryptionKey = Pbkdf2KeyDeriver.DEFAULT_INSTANCE.deriveECKey(password);
        reader = new InputStreamReader(new InflaterInputStream(new ECIESInputStream(inputStream, decryptionKey)), StandardCharsets.UTF_8);
    } else {
        reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
    }
    try {
        Gson gson = new Gson();
        Type stringStringMap = new TypeToken<Map<String, JsonElement>>() {
        }.getType();
        Map<String, JsonElement> map = gson.fromJson(reader, stringStringMap);
        ElectrumJsonWallet ew = new ElectrumJsonWallet();
        if (map.get("wallet_type") == null) {
            throw new ImportException("File was not a valid Electrum wallet");
        }
        ew.wallet_type = map.get("wallet_type").getAsString();
        for (String key : map.keySet()) {
            if (key.startsWith("x") || key.equals("keystore")) {
                ElectrumKeystore ek = gson.fromJson(map.get(key), ElectrumKeystore.class);
                if (ek.root_fingerprint == null && ek.ckcc_xfp != null) {
                    byte[] le = new byte[4];
                    Utils.uint32ToByteArrayLE(Long.parseLong(ek.ckcc_xfp), le, 0);
                    ek.root_fingerprint = Utils.bytesToHex(le).toUpperCase();
                }
                ew.keystores.put(key, ek);
            }
            if (key.equals("labels")) {
                JsonObject jsonObject = (JsonObject) map.get(key);
                for (String labelKey : jsonObject.keySet()) {
                    ew.labels.put(labelKey, jsonObject.get(labelKey).getAsString());
                }
            }
            if (key.equals("addresses")) {
                ew.addresses = gson.fromJson(map.get(key), ElectrumAddresses.class);
            }
            if (key.equals("verified_tx3")) {
                JsonObject jsonObject = (JsonObject) map.get(key);
                for (String txKey : jsonObject.keySet()) {
                    Sha256Hash txHash = Sha256Hash.wrap(txKey);
                    JsonArray array = jsonObject.getAsJsonArray(txKey);
                    if (array != null && array.size() > 3) {
                        int height = array.get(0).getAsInt();
                        Date date = new Date(array.get(1).getAsLong() * 1000);
                        long fee = array.get(2).getAsLong();
                        Sha256Hash blockHash = Sha256Hash.wrap(array.get(3).getAsString());
                        JsonObject transactions = (JsonObject) map.get("transactions");
                        if (transactions != null) {
                            String txhex = transactions.get(txKey).getAsString();
                            if (txhex != null) {
                                Transaction transaction = new Transaction(Utils.hexToBytes(txhex));
                                BlockTransaction blockTransaction = new BlockTransaction(txHash, height, date, fee, transaction, blockHash);
                                ew.transactions.put(txHash, blockTransaction);
                            }
                        }
                    }
                }
            }
        }
        Wallet wallet = new Wallet();
        ScriptType scriptType = null;
        for (ElectrumKeystore ek : ew.keystores.values()) {
            Keystore keystore = new Keystore();
            ExtendedKey xPub = ExtendedKey.fromDescriptor(ek.xpub);
            String derivationPath = ek.derivation;
            if (derivationPath == null) {
                derivationPath = "m/0";
            }
            String masterFingerprint = ek.root_fingerprint;
            if (masterFingerprint == null) {
                masterFingerprint = Utils.bytesToHex(xPub.getParentFingerprint());
            }
            if ("hardware".equals(ek.type)) {
                keystore.setSource(KeystoreSource.HW_USB);
                keystore.setWalletModel(WalletModel.fromType(ek.hw_type));
                if (keystore.getWalletModel() == null) {
                    throw new ImportException("Wallet has keystore of unknown hardware wallet type \"" + ek.hw_type + "\".");
                }
                if (keystore.getWalletModel().equals(WalletModel.TREZOR_1)) {
                    keystore.setWalletModel(WalletModel.TREZOR_T);
                }
            } else if ("bip32".equals(ek.type)) {
                if (ek.xprv != null && ek.seed == null) {
                    throw new ImportException("Electrum does not support exporting BIP39 derived seeds, as it does not store the mnemonic words. Only seeds created with its native Electrum Seed Version System are exportable. " + "If you have the mnemonic words, create a new wallet with a BIP39 keystore.");
                } else if (ek.seed != null) {
                    keystore.setSource(KeystoreSource.SW_SEED);
                    String mnemonic = ek.seed;
                    String passphrase = ek.passphrase;
                    if (password != null) {
                        mnemonic = decrypt(mnemonic, password);
                        passphrase = decrypt(passphrase, password);
                    }
                    keystore.setSeed(new DeterministicSeed(mnemonic, passphrase, 0, DeterministicSeed.Type.ELECTRUM));
                    // Ensure the derivation path from the seed matches the provided xpub
                    String[] possibleDerivations = { "m", "m/0", "m/0'" };
                    for (String possibleDerivation : possibleDerivations) {
                        List<ChildNumber> derivation = KeyDerivation.parsePath(possibleDerivation);
                        DeterministicKey derivedKey = keystore.getExtendedMasterPrivateKey().getKey(derivation);
                        DeterministicKey derivedKeyPublicOnly = derivedKey.dropPrivateBytes().dropParent();
                        ExtendedKey xpub = new ExtendedKey(derivedKeyPublicOnly, derivedKey.getParentFingerprint(), derivation.isEmpty() ? ChildNumber.ZERO : derivation.get(derivation.size() - 1));
                        if (xpub.equals(xPub)) {
                            derivationPath = possibleDerivation;
                            break;
                        }
                    }
                } else {
                    keystore.setSource(KeystoreSource.SW_WATCH);
                }
                keystore.setWalletModel(WalletModel.ELECTRUM);
            }
            keystore.setKeyDerivation(new KeyDerivation(masterFingerprint, derivationPath));
            keystore.setExtendedPublicKey(xPub);
            keystore.setLabel(ek.label != null ? ek.label : "Electrum");
            if (keystore.getLabel().length() > Keystore.MAX_LABEL_LENGTH) {
                keystore.setLabel(keystore.getLabel().substring(0, Keystore.MAX_LABEL_LENGTH));
            }
            wallet.getKeystores().add(keystore);
            ExtendedKey.Header xpubHeader = ExtendedKey.Header.fromExtendedKey(ek.xpub);
            scriptType = xpubHeader.getDefaultScriptType();
        }
        wallet.setScriptType(scriptType);
        if (ew.wallet_type.equals("standard")) {
            wallet.setPolicyType(PolicyType.SINGLE);
            wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, scriptType, wallet.getKeystores(), 1));
        } else if (ew.wallet_type.contains("of")) {
            wallet.setPolicyType(PolicyType.MULTI);
            String[] mOfn = ew.wallet_type.split("of");
            int threshold = Integer.parseInt(mOfn[0]);
            wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, scriptType, wallet.getKeystores(), threshold));
        } else {
            throw new ImportException("Unknown Electrum wallet type of " + ew.wallet_type);
        }
        for (String key : ew.labels.keySet()) {
            try {
                Sha256Hash txHash = Sha256Hash.wrap(key);
                BlockTransaction blockTransaction = ew.transactions.get(txHash);
                if (blockTransaction != null) {
                    blockTransaction.setLabel(ew.labels.get(key));
                }
            } catch (Exception e) {
                // not a tx - try an address
                if (ew.addresses != null) {
                    try {
                        Address address = Address.fromString(key);
                        Map<KeyPurpose, List<String>> keyPurposes = Map.of(KeyPurpose.RECEIVE, ew.addresses.receiving, KeyPurpose.CHANGE, ew.addresses.change);
                        for (KeyPurpose keyPurpose : keyPurposes.keySet()) {
                            WalletNode purposeNode = wallet.getNode(keyPurpose);
                            purposeNode.fillToIndex(keyPurposes.get(keyPurpose).size() - 1);
                            for (WalletNode addressNode : purposeNode.getChildren()) {
                                if (address.equals(addressNode.getAddress())) {
                                    addressNode.setLabel(ew.labels.get(key));
                                }
                            }
                        }
                        for (BlockTransaction blkTx : ew.transactions.values()) {
                            if (blkTx.getLabel() == null) {
                                Transaction tx = blkTx.getTransaction();
                                for (TransactionOutput txOutput : tx.getOutputs()) {
                                    try {
                                        Address[] addresses = txOutput.getScript().getToAddresses();
                                        if (Arrays.asList(addresses).contains(address)) {
                                            blkTx.setLabel(ew.labels.get(key));
                                        }
                                    } catch (NonStandardScriptException ex) {
                                    // ignore
                                    }
                                }
                            }
                        }
                    } catch (Exception ex) {
                    // not an address
                    }
                }
            }
        }
        wallet.updateTransactions(ew.transactions);
        try {
            wallet.checkWallet();
        } catch (InvalidWalletException e) {
            throw new IllegalStateException("Imported Electrum wallet was invalid: " + e.getMessage());
        }
        return wallet;
    } catch (Exception e) {
        throw new ImportException("Error importing Electrum Wallet", e);
    }
}
Also used : Address(com.sparrowwallet.drongo.address.Address) KeyPurpose(com.sparrowwallet.drongo.KeyPurpose) InflaterInputStream(java.util.zip.InflaterInputStream) KeyDerivation(com.sparrowwallet.drongo.KeyDerivation) PolicyType(com.sparrowwallet.drongo.policy.PolicyType) Type(java.lang.reflect.Type) ExtendedKey(com.sparrowwallet.drongo.ExtendedKey)

Example 23 with Address

use of com.sparrowwallet.drongo.address.Address in project drongo by sparrowwallet.

the class WatchWallet method initialiseAddresses.

public void initialiseAddresses() {
    if (outputDescriptor.describesMultipleAddresses()) {
        for (int index = 0; index <= LOOK_AHEAD_LIMIT; index++) {
            List<ChildNumber> receivingDerivation = outputDescriptor.getReceivingDerivation(index);
            Address address = getReceivingAddress(index);
            addresses.put(address, receivingDerivation);
        }
        for (int index = 0; index <= LOOK_AHEAD_LIMIT; index++) {
            List<ChildNumber> changeDerivation = outputDescriptor.getChangeDerivation(index);
            Address address = getChangeAddress(index);
            addresses.put(address, changeDerivation);
        }
    } else {
        List<ChildNumber> derivation = outputDescriptor.getChildDerivation();
        Address address = outputDescriptor.getAddress(derivation);
        addresses.put(address, derivation);
    }
}
Also used : Address(com.sparrowwallet.drongo.address.Address)

Example 24 with Address

use of com.sparrowwallet.drongo.address.Address in project drongo by sparrowwallet.

the class TransactionTest method verifyConstructedTxLengthP2WPKH.

@Test
public void verifyConstructedTxLengthP2WPKH() throws NonStandardScriptException, IOException {
    String hex = "020000000001014596cc6219630c13cbca099838c2fb0920cde29de1e5473087de8bbce06b9f510100000000ffffffff02502a4b000000000017a914b1cd708c9d49c7ad6ec851ad7f24076233fa7cfb8772915600000000001600145279dddc177883923bcf3bd5aab50e725dca01f302483045022100e9056474685b7d885956c7c7e5ac77e1249373e5d222b13620dcde6a63e337d602206ebb59c1834e991e9c9f6129a78c7669cfc4c41c4d19c6be4dabe6749715d5ee01210278f5f957591a07a51fc5033c3407de2ff722b0a5f98e91c9a9e1e038c9b1b59300000000";
    Transaction parsedTransaction = new Transaction(Utils.hexToBytes(hex));
    Transaction transaction = new Transaction();
    transaction.setVersion(parsedTransaction.getVersion());
    transaction.setSegwitFlag(parsedTransaction.getSegwitFlag());
    for (TransactionInput txInput : parsedTransaction.getInputs()) {
        transaction.addInput(txInput.getOutpoint().getHash(), txInput.getOutpoint().getIndex(), txInput.getScriptSig(), txInput.getWitness());
    }
    for (TransactionOutput txOutput : parsedTransaction.getOutputs()) {
        Address address = txOutput.getScript().getToAddresses()[0];
        transaction.addOutput(txOutput.getValue(), address);
    }
    Assert.assertEquals(parsedTransaction.getLength(), transaction.getLength());
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    transaction.bitcoinSerializeToStream(baos);
    String constructedHex = Utils.bytesToHex(baos.toByteArray());
    Assert.assertEquals(hex, constructedHex);
}
Also used : Address(com.sparrowwallet.drongo.address.Address) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Test(org.junit.Test)

Example 25 with Address

use of com.sparrowwallet.drongo.address.Address in project drongo by sparrowwallet.

the class PaymentCodeTest method testChildWallet.

@Test
public void testChildWallet() throws MnemonicException, InvalidPaymentCodeException {
    DeterministicSeed aliceSeed = new DeterministicSeed("response seminar brave tip suit recall often sound stick owner lottery motion", "", 0, DeterministicSeed.Type.BIP39);
    Wallet aliceWallet = new Wallet();
    aliceWallet.setPolicyType(PolicyType.SINGLE);
    aliceWallet.setScriptType(ScriptType.P2PKH);
    aliceWallet.getKeystores().add(Keystore.fromSeed(aliceSeed, aliceWallet.getScriptType().getDefaultDerivation()));
    aliceWallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, aliceWallet.getKeystores(), 1));
    PaymentCode paymentCodeBob = new PaymentCode("PM8TJS2JxQ5ztXUpBBRnpTbcUXbUHy2T1abfrb3KkAAtMEGNbey4oumH7Hc578WgQJhPjBxteQ5GHHToTYHE3A1w6p7tU6KSoFmWBVbFGjKPisZDbP97");
    Wallet aliceBip47Wallet = aliceWallet.addChildWallet(paymentCodeBob, ScriptType.P2PKH, "Alice");
    PaymentCode paymentCodeAlice = aliceBip47Wallet.getKeystores().get(0).getPaymentCode();
    Assert.assertEquals(aliceWallet.getPaymentCode(), aliceBip47Wallet.getPaymentCode());
    Assert.assertEquals("PM8TJTLJbPRGxSbc8EJi42Wrr6QbNSaSSVJ5Y3E4pbCYiTHUskHg13935Ubb7q8tx9GVbh2UuRnBc3WSyJHhUrw8KhprKnn9eDznYGieTzFcwQRya4GA", paymentCodeAlice.toString());
    Assert.assertEquals("1JDdmqFLhpzcUwPeinhJbUPw4Co3aWLyzW", paymentCodeAlice.getNotificationAddress().toString());
    WalletNode sendNode0 = aliceBip47Wallet.getFreshNode(KeyPurpose.SEND);
    Address address0 = sendNode0.getAddress();
    Assert.assertEquals("141fi7TY3h936vRUKh1qfUZr8rSBuYbVBK", address0.toString());
    WalletNode sendNode1 = aliceBip47Wallet.getFreshNode(KeyPurpose.SEND, sendNode0);
    Address address1 = sendNode1.getAddress();
    Assert.assertEquals("12u3Uued2fuko2nY4SoSFGCoGLCBUGPkk6", address1.toString());
    WalletNode sendNode2 = aliceBip47Wallet.getFreshNode(KeyPurpose.SEND, sendNode1);
    Address address2 = sendNode2.getAddress();
    Assert.assertEquals("1FsBVhT5dQutGwaPePTYMe5qvYqqjxyftc", address2.toString());
    DeterministicSeed bobSeed = new DeterministicSeed("reward upper indicate eight swift arch injury crystal super wrestle already dentist", "", 0, DeterministicSeed.Type.BIP39);
    Wallet bobWallet = new Wallet();
    bobWallet.setPolicyType(PolicyType.SINGLE);
    bobWallet.setScriptType(ScriptType.P2PKH);
    bobWallet.getKeystores().add(Keystore.fromSeed(bobSeed, bobWallet.getScriptType().getDefaultDerivation()));
    bobWallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, bobWallet.getKeystores(), 1));
    Wallet bobBip47Wallet = bobWallet.addChildWallet(paymentCodeAlice, ScriptType.P2PKH, "Bob");
    Assert.assertEquals(paymentCodeBob.toString(), bobBip47Wallet.getKeystores().get(0).getPaymentCode().toString());
    Assert.assertEquals("1ChvUUvht2hUQufHBXF8NgLhW8SwE2ecGV", paymentCodeBob.getNotificationAddress().toString());
    WalletNode receiveNode0 = bobBip47Wallet.getFreshNode(KeyPurpose.RECEIVE);
    Address receiveAddress0 = receiveNode0.getAddress();
    Assert.assertEquals("141fi7TY3h936vRUKh1qfUZr8rSBuYbVBK", receiveAddress0.toString());
    WalletNode receiveNode1 = bobBip47Wallet.getFreshNode(KeyPurpose.RECEIVE, receiveNode0);
    Address receiveAddress1 = receiveNode1.getAddress();
    Assert.assertEquals("12u3Uued2fuko2nY4SoSFGCoGLCBUGPkk6", receiveAddress1.toString());
    WalletNode receiveNode2 = bobBip47Wallet.getFreshNode(KeyPurpose.RECEIVE, receiveNode1);
    Address receiveAddress2 = receiveNode2.getAddress();
    Assert.assertEquals("1FsBVhT5dQutGwaPePTYMe5qvYqqjxyftc", receiveAddress2.toString());
    ECKey privKey0 = bobWallet.getKeystores().get(0).getKey(receiveNode0);
    ECKey pubKey0 = bobWallet.getKeystores().get(0).getPubKey(receiveNode0);
    Assert.assertArrayEquals(privKey0.getPubKey(), pubKey0.getPubKey());
    ECKey privKey1 = bobWallet.getKeystores().get(0).getKey(receiveNode1);
    ECKey pubKey1 = bobWallet.getKeystores().get(0).getPubKey(receiveNode1);
    Assert.assertArrayEquals(privKey1.getPubKey(), pubKey1.getPubKey());
}
Also used : Address(com.sparrowwallet.drongo.address.Address) ECKey(com.sparrowwallet.drongo.crypto.ECKey) Test(org.junit.Test)

Aggregations

Address (com.sparrowwallet.drongo.address.Address)26 Test (org.junit.Test)6 InvalidAddressException (com.sparrowwallet.drongo.address.InvalidAddressException)5 ECKey (com.sparrowwallet.drongo.crypto.ECKey)5 KeyPurpose (com.sparrowwallet.drongo.KeyPurpose)4 TransactionOutput (com.sparrowwallet.drongo.protocol.TransactionOutput)4 P2PKHAddress (com.sparrowwallet.drongo.address.P2PKHAddress)3 com.sparrowwallet.drongo.wallet (com.sparrowwallet.drongo.wallet)3 PayNymAddress (com.sparrowwallet.sparrow.paynym.PayNymAddress)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 java.util (java.util)3 Collectors (java.util.stream.Collectors)3 InvalidPaymentCodeException (com.sparrowwallet.drongo.bip47.InvalidPaymentCodeException)2 DumpedPrivateKey (com.sparrowwallet.drongo.crypto.DumpedPrivateKey)2 NonStandardScriptException (com.sparrowwallet.drongo.protocol.NonStandardScriptException)2 ScriptType (com.sparrowwallet.drongo.protocol.ScriptType)2 Transaction (com.sparrowwallet.drongo.protocol.Transaction)2 BitcoinURI (com.sparrowwallet.drongo.uri.BitcoinURI)2 AppServices (com.sparrowwallet.sparrow.AppServices)2 EventManager (com.sparrowwallet.sparrow.EventManager)2