Search in sources :

Example 16 with HD_Address

use of com.samourai.wallet.hd.HD_Address in project samourai-wallet-android by Samourai-Wallet.

the class APIFactory method lockXPUB.

/*
        public synchronized JSONObject deleteXPUB(String xpub, boolean bip49) {

            String _url = SamouraiWallet.getInstance().isTestNet() ? WebUtil.SAMOURAI_API2_TESTNET : WebUtil.SAMOURAI_API2;

            JSONObject jsonObject  = null;

            try {

                String response = null;
                ECKey ecKey = null;

                if(AddressFactory.getInstance(context).xpub2account().get(xpub) != null || xpub.equals(BIP49Util.getInstance(context).getWallet().getAccount(0).ypubstr()))    {

                    HD_Address addr = null;
                    if(bip49)    {
                        addr = BIP49Util.getInstance(context).getWallet().getAccountAt(0).getChange().getAddressAt(0);
                    }
                    else    {
                        addr = HD_WalletFactory.getInstance(context).get().getAccount(0).getChain(AddressFactory.CHANGE_CHAIN).getAddressAt(0);
                    }
                    ecKey = addr.getECKey();

                    if(ecKey != null && ecKey.hasPrivKey())    {

                        String sig = ecKey.signMessage(xpub);
                        String address = null;
                        if(bip49)    {
                            SegwitAddress segwitAddress = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
                            address = segwitAddress.getAddressAsString();
                        }
                        else    {
                            address = ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
                        }

                        if(!TorUtil.getInstance(context).statusFromBroadcast())    {
                            StringBuilder args = new StringBuilder();
                            args.append("message=");
                            args.append(xpub);
                            args.append("address=");
                            args.append(address);
                            args.append("&signature=");
                            args.append(Uri.encode(sig));
                            info("APIFactory", "delete XPUB:" + args.toString());
                            response = WebUtil.getInstance(context).deleteURL(_url + "delete/" + xpub, args.toString());
                            info("APIFactory", "delete XPUB response:" + response);
                        }
                        else    {
                            HashMap<String,String> args = new HashMap<String,String>();
                            args.put("message", xpub);
                            args.put("address", address);
                            args.put("signature", Uri.encode(sig));
                            info("APIFactory", "delete XPUB:" + args.toString());
                            response = WebUtil.getInstance(context).tor_deleteURL(_url + "delete", args);
                            info("APIFactory", "delete XPUB response:" + response);
                        }

                        try {
                            jsonObject = new JSONObject(response);

                            if(jsonObject.has("status") && jsonObject.getString("status").equals("ok"))    {
                                ;
                            }

                        }
                        catch(JSONException je) {
                            je.printStackTrace();
                            jsonObject = null;
                        }

                    }
                }

            }
            catch(Exception e) {
                jsonObject = null;
                e.printStackTrace();
            }

            return jsonObject;
        }
    */
public synchronized JSONObject lockXPUB(String xpub, int purpose, String tag) {
    String _url = WebUtil.getAPIUrl(context);
    JSONObject jsonObject = null;
    try {
        String response = null;
        ECKey ecKey = null;
        if (AddressFactory.getInstance(context).xpub2account().get(xpub) != null || xpub.equals(BIP49Util.getInstance(context).getWallet().getAccount(0).ypubstr()) || xpub.equals(BIP84Util.getInstance(context).getWallet().getAccount(0).zpubstr()) || xpub.equals(BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPremixAccount()).zpubstr()) || xpub.equals(BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).zpubstr())) {
            HD_Address addr = null;
            switch(purpose) {
                case 49:
                    addr = BIP49Util.getInstance(context).getWallet().getAccountAt(0).getChange().getAddressAt(0);
                    break;
                case 84:
                    if (tag != null && tag.equals(PrefsUtil.XPUBPRELOCK)) {
                        addr = BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPremixAccount()).getChange().getAddressAt(0);
                    } else if (tag != null && tag.equals(PrefsUtil.XPUBPOSTLOCK)) {
                        addr = BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).getChange().getAddressAt(0);
                    } else {
                        addr = BIP84Util.getInstance(context).getWallet().getAccountAt(0).getChange().getAddressAt(0);
                    }
                    break;
                default:
                    addr = HD_WalletFactory.getInstance(context).get().getAccount(0).getChain(AddressFactory.CHANGE_CHAIN).getAddressAt(0);
                    break;
            }
            ecKey = addr.getECKey();
            if (ecKey != null && ecKey.hasPrivKey()) {
                String sig = ecKey.signMessage("lock");
                String address = null;
                switch(purpose) {
                    case 49:
                        SegwitAddress p2shp2wpkh = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
                        address = p2shp2wpkh.getAddressAsString();
                        break;
                    case 84:
                        SegwitAddress segwitAddress = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
                        address = segwitAddress.getBech32AsString();
                        break;
                    default:
                        address = ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
                        break;
                }
                if (!TorManager.getInstance(context).isRequired()) {
                    StringBuilder args = new StringBuilder();
                    args.append("address=");
                    args.append(address);
                    args.append("&signature=");
                    args.append(Uri.encode(sig));
                    args.append("&message=");
                    args.append("lock");
                    // info("APIFactory", "lock XPUB:" + args.toString());
                    args.append("&at=");
                    args.append(getAccessToken());
                    response = WebUtil.getInstance(context).postURL(_url + "xpub/" + xpub + "/lock/", args.toString());
                // info("APIFactory", "lock XPUB response:" + response);
                } else {
                    HashMap<String, String> args = new HashMap<String, String>();
                    args.put("address", address);
                    // args.put("signature", Uri.encode(sig));
                    args.put("signature", sig);
                    args.put("message", "lock");
                    args.put("at", getAccessToken());
                    info("APIFactory", "lock XPUB:" + _url);
                    info("APIFactory", "lock XPUB:" + args.toString());
                    response = WebUtil.getInstance(context).tor_postURL(_url + "xpub/" + xpub + "/lock/", args);
                    info("APIFactory", "lock XPUB response:" + response);
                }
                try {
                    jsonObject = new JSONObject(response);
                    if (jsonObject.has("status") && jsonObject.getString("status").equals("ok")) {
                        if (tag != null) {
                            PrefsUtil.getInstance(context).setValue(tag, true);
                        } else {
                            switch(purpose) {
                                case 49:
                                    PrefsUtil.getInstance(context).setValue(PrefsUtil.XPUB49LOCK, true);
                                    break;
                                case 84:
                                    PrefsUtil.getInstance(context).setValue(PrefsUtil.XPUB84LOCK, true);
                                    break;
                                default:
                                    PrefsUtil.getInstance(context).setValue(PrefsUtil.XPUB44LOCK, true);
                                    break;
                            }
                        }
                    }
                } catch (JSONException je) {
                    je.printStackTrace();
                    jsonObject = null;
                }
            }
        }
    } catch (Exception e) {
        jsonObject = null;
        e.printStackTrace();
    }
    return jsonObject;
}
Also used : JSONObject(org.json.JSONObject) HD_Address(com.samourai.wallet.hd.HD_Address) SegwitAddress(com.samourai.wallet.segwit.SegwitAddress) HashMap(java.util.HashMap) JSONException(org.json.JSONException) ECKey(org.bitcoinj.core.ECKey) NotSecp256k1Exception(com.samourai.wallet.bip47.rpc.NotSecp256k1Exception) JSONException(org.json.JSONException) AddressFormatException(org.bitcoinj.core.AddressFormatException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) MnemonicException(org.bitcoinj.crypto.MnemonicException) DecryptionException(com.samourai.wallet.crypto.DecryptionException) IOException(java.io.IOException) NoSuchProviderException(java.security.NoSuchProviderException)

Example 17 with HD_Address

use of com.samourai.wallet.hd.HD_Address in project samourai-wallet-android by Samourai-Wallet.

the class CahootsUtil method doStowaway2.

// 
// sender
// 
public Cahoots doStowaway2(Stowaway stowaway1) throws Exception {
    debug("CahootsUtil", "sender account (2):" + stowaway1.getAccount());
    Transaction transaction = stowaway1.getTransaction();
    debug("CahootsUtil", "step2 tx:" + org.spongycastle.util.encoders.Hex.toHexString(transaction.bitcoinSerialize()));
    int nbIncomingInputs = transaction.getInputs().size();
    List<UTXO> utxos = getCahootsUTXO(stowaway1.getAccount());
    // sort in ascending order by value
    Collections.sort(utxos, new UTXO.UTXOComparator());
    Collections.reverse(utxos);
    debug("CahootsUtil", "BIP84 utxos:" + utxos.size());
    List<UTXO> selectedUTXO = new ArrayList<UTXO>();
    int nbTotalSelectedOutPoints = 0;
    long totalSelectedAmount = 0L;
    List<UTXO> lowUTXO = new ArrayList<UTXO>();
    for (UTXO utxo : utxos) {
        if (utxo.getValue() < stowaway1.getSpendAmount()) {
            lowUTXO.add(utxo);
        }
    }
    List<List<UTXO>> listOfLists = new ArrayList<List<UTXO>>();
    Collections.shuffle(lowUTXO);
    listOfLists.add(lowUTXO);
    listOfLists.add(utxos);
    for (List<UTXO> list : listOfLists) {
        selectedUTXO.clear();
        totalSelectedAmount = 0L;
        nbTotalSelectedOutPoints = 0;
        for (UTXO utxo : list) {
            selectedUTXO.add(utxo);
            totalSelectedAmount += utxo.getValue();
            debug("BIP84 selected utxo:", "" + utxo.getValue());
            nbTotalSelectedOutPoints += utxo.getOutpoints().size();
            if (totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
                // discard "extra" utxo, if any
                List<UTXO> _selectedUTXO = new ArrayList<UTXO>();
                Collections.reverse(selectedUTXO);
                int _nbTotalSelectedOutPoints = 0;
                long _totalSelectedAmount = 0L;
                for (UTXO utxoSel : selectedUTXO) {
                    _selectedUTXO.add(utxoSel);
                    _totalSelectedAmount += utxoSel.getValue();
                    debug("CahootsUtil", "BIP84 post selected utxo:" + utxoSel.getValue());
                    _nbTotalSelectedOutPoints += utxoSel.getOutpoints().size();
                    if (_totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, _nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
                        selectedUTXO.clear();
                        selectedUTXO.addAll(_selectedUTXO);
                        totalSelectedAmount = _totalSelectedAmount;
                        nbTotalSelectedOutPoints = _nbTotalSelectedOutPoints;
                        break;
                    }
                }
                break;
            }
        }
        if (totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
            break;
        }
    }
    /*
        if(lowUTXO.size() > 0)    {
            Collections.shuffle(lowUTXO);
            for (UTXO utxo : lowUTXO) {
                selectedUTXO.add(utxo);
                totalSelectedAmount += utxo.getValue();
                debug("BIP84 selected utxo:", "" + utxo.getValue());
                nbTotalSelectedOutPoints += utxo.getOutpoints().size();
                if (totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {

                    // discard "extra" utxo, if any
                    List<UTXO> _selectedUTXO = new ArrayList<UTXO>();
                    Collections.reverse(selectedUTXO);
                    int _nbTotalSelectedOutPoints = 0;
                    long _totalSelectedAmount = 0L;
                    for (UTXO utxoSel : selectedUTXO) {
                        _selectedUTXO.add(utxoSel);
                        _totalSelectedAmount += utxoSel.getValue();
                        debug("CahootsUtil", "BIP84 post selected utxo:" + utxoSel.getValue());
                        _nbTotalSelectedOutPoints += utxoSel.getOutpoints().size();
                        if (_totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, _nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
                            selectedUTXO.clear();
                            selectedUTXO.addAll(_selectedUTXO);
                            totalSelectedAmount = _totalSelectedAmount;
                            nbTotalSelectedOutPoints = _nbTotalSelectedOutPoints;
                            break;
                        }
                    }

                    break;
                }
            }

        }
        if (!(totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue())) {
            selectedUTXO.clear();
            totalSelectedAmount = 0L;
            nbTotalSelectedOutPoints = 0;
            for (UTXO utxo : utxos) {
                selectedUTXO.add(utxo);
                totalSelectedAmount += utxo.getValue();
                debug("BIP84 selected utxo:", "" + utxo.getValue());
                nbTotalSelectedOutPoints += utxo.getOutpoints().size();
                if (totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {

                    // discard "extra" utxo, if any
                    List<UTXO> _selectedUTXO = new ArrayList<UTXO>();
                    Collections.reverse(selectedUTXO);
                    int _nbTotalSelectedOutPoints = 0;
                    long _totalSelectedAmount = 0L;
                    for (UTXO utxoSel : selectedUTXO) {
                        _selectedUTXO.add(utxoSel);
                        _totalSelectedAmount += utxoSel.getValue();
                        debug("CahootsUtil", "BIP84 post selected utxo:" + utxoSel.getValue());
                        _nbTotalSelectedOutPoints += utxoSel.getOutpoints().size();
                        if (_totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, _nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
                            selectedUTXO.clear();
                            selectedUTXO.addAll(_selectedUTXO);
                            totalSelectedAmount = _totalSelectedAmount;
                            nbTotalSelectedOutPoints = _nbTotalSelectedOutPoints;
                            break;
                        }
                    }

                    break;
                }
            }
        }
        */
    if (!(totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue())) {
        return null;
    }
    debug("CahootsUtil", "BIP84 selected utxos:" + selectedUTXO.size());
    long fee = FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue();
    debug("CahootsUtil", "fee:" + fee);
    NetworkParameters params = stowaway1.getParams();
    // 
    // 
    // step2: B verif, utxos -> A (take smallest that cover amount)
    // 
    // 
    String zpub = BIP84Util.getInstance(context).getWallet().getAccountAt(stowaway1.getAccount()).zpubstr();
    HashMap<_TransactionOutPoint, Triple<byte[], byte[], String>> inputsB = new HashMap<_TransactionOutPoint, Triple<byte[], byte[], String>>();
    for (UTXO utxo : selectedUTXO) {
        for (MyTransactionOutPoint outpoint : utxo.getOutpoints()) {
            _TransactionOutPoint _outpoint = new _TransactionOutPoint(outpoint);
            ECKey eckey = SendFactory.getPrivKey(_outpoint.getAddress(), stowaway1.getAccount());
            String path = APIFactory.getInstance(context).getUnspentPaths().get(_outpoint.getAddress());
            inputsB.put(_outpoint, Triple.of(eckey.getPubKey(), stowaway1.getFingerprint(), path));
        }
    }
    debug("CahootsUtil", "inputsB:" + inputsB.size());
    // change output
    SegwitAddress segwitAddress = null;
    int idx = 0;
    if (stowaway1.getAccount() == WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()) {
        idx = AddressFactory.getInstance(context).getHighestPostChangeIdx();
        HD_Address addr = BIP84Util.getInstance(context).getWallet().getAccountAt(stowaway1.getAccount()).getChange().getAddressAt(idx);
        segwitAddress = new SegwitAddress(addr.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
    } else {
        idx = BIP84Util.getInstance(context).getWallet().getAccount(0).getChange().getAddrIdx();
        segwitAddress = BIP84Util.getInstance(context).getAddressAt(1, idx);
    }
    HashMap<_TransactionOutput, Triple<byte[], byte[], String>> outputsB = new HashMap<_TransactionOutput, Triple<byte[], byte[], String>>();
    Pair<Byte, byte[]> pair = Bech32Segwit.decode(SamouraiWallet.getInstance().isTestNet() ? "tb" : "bc", segwitAddress.getBech32AsString());
    byte[] scriptPubKey_B = Bech32Segwit.getScriptPubkey(pair.getLeft(), pair.getRight());
    _TransactionOutput output_B0 = new _TransactionOutput(params, null, Coin.valueOf((totalSelectedAmount - stowaway1.getSpendAmount()) - fee), scriptPubKey_B);
    outputsB.put(output_B0, Triple.of(segwitAddress.getECKey().getPubKey(), stowaway1.getFingerprint(), "M/1/" + idx));
    debug("CahootsUtil", "outputsB:" + outputsB.size());
    Stowaway stowaway2 = new Stowaway(stowaway1);
    stowaway2.inc(inputsB, outputsB, null);
    stowaway2.setFeeAmount(fee);
    return stowaway2;
}
Also used : HashMap(java.util.HashMap) SegwitAddress(com.samourai.wallet.segwit.SegwitAddress) ArrayList(java.util.ArrayList) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) ECKey(org.bitcoinj.core.ECKey) ArrayList(java.util.ArrayList) List(java.util.List) HD_Address(com.samourai.wallet.hd.HD_Address) NetworkParameters(org.bitcoinj.core.NetworkParameters) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) TransactionOutPoint(org.bitcoinj.core.TransactionOutPoint) Triple(org.apache.commons.lang3.tuple.Triple) UTXO(com.samourai.wallet.send.UTXO) Transaction(org.bitcoinj.core.Transaction)

Aggregations

HD_Address (com.samourai.wallet.hd.HD_Address)17 ECKey (org.bitcoinj.core.ECKey)11 SegwitAddress (com.samourai.wallet.segwit.SegwitAddress)10 IOException (java.io.IOException)9 MnemonicException (org.bitcoinj.crypto.MnemonicException)9 JSONException (org.json.JSONException)7 HashMap (java.util.HashMap)5 AddressFormatException (org.bitcoinj.core.AddressFormatException)5 MyTransactionOutPoint (com.samourai.wallet.send.MyTransactionOutPoint)4 DumpedPrivateKey (org.bitcoinj.core.DumpedPrivateKey)4 JSONObject (org.json.JSONObject)4 PaymentAddress (com.samourai.wallet.bip47.rpc.PaymentAddress)3 PaymentCode (com.samourai.wallet.bip47.rpc.PaymentCode)3 HD_Wallet (com.samourai.wallet.hd.HD_Wallet)3 Transaction (org.bitcoinj.core.Transaction)3 TransactionInput (org.bitcoinj.core.TransactionInput)3 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)3 TransactionSignature (org.bitcoinj.crypto.TransactionSignature)3 Script (org.bitcoinj.script.Script)3 ScriptException (org.bitcoinj.script.ScriptException)3