Search in sources :

Example 1 with P2SH_P2WPKH

use of com.samourai.sentinel.segwit.P2SH_P2WPKH in project sentinel-android by Samourai-Wallet.

the class SamouraiSentinel method getReceiveAddress.

public String getReceiveAddress() {
    final List<String> xpubList = getAllAddrsSorted();
    String addr = null;
    ECKey ecKey = null;
    if (xpubList.get(SamouraiSentinel.getInstance(context).getCurrentSelectedAccount() - 1).startsWith("xpub") || xpubList.get(SamouraiSentinel.getInstance(context).getCurrentSelectedAccount() - 1).startsWith("ypub")) {
        String xpub = xpubList.get(SamouraiSentinel.getInstance(context).getCurrentSelectedAccount() - 1);
        Log.d("SamouraiSentinel", "xpub:" + xpub);
        int account = AddressFactory.getInstance(context).xpub2account().get(xpub);
        Log.d("SamouraiSentinel", "account:" + account);
        if (SamouraiSentinel.getInstance(context).getBIP49().keySet().contains(xpub)) {
            ecKey = AddressFactory.getInstance(context).getECKey(AddressFactory.RECEIVE_CHAIN, account);
            P2SH_P2WPKH p2sh_p2wpkh = new P2SH_P2WPKH(ecKey.getPubKey(), MainNetParams.get());
            addr = p2sh_p2wpkh.getAddressAsString();
            Log.d("SamouraiSentinel", "addr:" + addr);
        } else {
            addr = AddressFactory.getInstance(context).get(AddressFactory.RECEIVE_CHAIN, account);
        }
    } else {
        addr = xpubList.get(SamouraiSentinel.getInstance(context).getCurrentSelectedAccount() - 1);
    }
    return addr;
}
Also used : P2SH_P2WPKH(com.samourai.sentinel.segwit.P2SH_P2WPKH) ECKey(org.bitcoinj.core.ECKey)

Example 2 with P2SH_P2WPKH

use of com.samourai.sentinel.segwit.P2SH_P2WPKH in project sentinel-android by Samourai-Wallet.

the class SweepUtil method sweep.

public void sweep(final PrivKeyReader privKeyReader, final String strReceiveAddress, final int type) {
    new Thread(new Runnable() {

        @Override
        public void run() {
            Looper.prepare();
            try {
                if (privKeyReader == null || privKeyReader.getKey() == null || !privKeyReader.getKey().hasPrivKey()) {
                    Toast.makeText(context, R.string.cannot_recognize_privkey, Toast.LENGTH_SHORT).show();
                    return;
                }
                String address = null;
                UTXO utxo = null;
                if (type == TYPE_P2SH_P2WPKH) {
                    utxo = utxoP2SH_P2WPKH;
                    address = addressP2SH_P2WPKH;
                } else if (type == TYPE_P2WPKH) {
                    utxo = utxoP2WPKH;
                    address = addressP2WPKH;
                } else {
                    addressP2PKH = privKeyReader.getKey().toAddress(MainNetParams.get()).toString();
                    Log.d("SweepUtil", "address derived P2PKH:" + addressP2PKH);
                    addressP2SH_P2WPKH = new P2SH_P2WPKH(privKeyReader.getKey(), MainNetParams.get()).getAddressAsString();
                    Log.d("SweepUtil", "address derived P2SH_P2WPKH:" + addressP2SH_P2WPKH);
                    addressP2WPKH = new SegwitAddress(privKeyReader.getKey(), MainNetParams.get()).getBech32AsString();
                    Log.d("SweepUtil", "address derived P2WPKH:" + addressP2WPKH);
                    utxoP2PKH = APIFactory.getInstance(context).getUnspentOutputsForSweep(addressP2PKH);
                    utxoP2SH_P2WPKH = APIFactory.getInstance(context).getUnspentOutputsForSweep(addressP2SH_P2WPKH);
                    utxoP2WPKH = APIFactory.getInstance(context).getUnspentOutputsForSweep(addressP2WPKH);
                    utxo = utxoP2PKH;
                    address = addressP2PKH;
                }
                if (utxo != null && utxo.getOutpoints().size() > 0) {
                    long total_value = 0L;
                    final List<MyTransactionOutPoint> outpoints = utxo.getOutpoints();
                    for (MyTransactionOutPoint outpoint : outpoints) {
                        total_value += outpoint.getValue().longValue();
                    }
                    FeeUtil.getInstance().setSuggestedFee(FeeUtil.getInstance().getNormalFee());
                    final BigInteger fee;
                    if (type == TYPE_P2SH_P2WPKH) {
                        fee = FeeUtil.getInstance().estimatedFeeSegwit(0, outpoints.size(), 1);
                    } else if (type == TYPE_P2PKH) {
                        fee = FeeUtil.getInstance().estimatedFeeSegwit(0, 0, outpoints.size(), 1);
                    } else {
                        fee = FeeUtil.getInstance().estimatedFee(outpoints.size(), 1);
                    }
                    final long amount = total_value - fee.longValue();
                    Log.d("SweepUtil", "Total value:" + total_value);
                    Log.d("SweepUtil", "Amount:" + amount);
                    Log.d("SweepUtil", "Fee:" + fee.toString());
                    Log.d("SweepUtil", "Receive address:" + strReceiveAddress);
                    String message = "Sweep " + Coin.valueOf(amount).toPlainString() + " from " + address + " (fee:" + Coin.valueOf(fee.longValue()).toPlainString() + ")?";
                    new AlertDialog.Builder(context).setTitle(R.string.app_name).setMessage(message).setCancelable(false).setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {

                        public void onClick(final DialogInterface dialog, int whichButton) {
                            Log.d("SweepUtil", "start sweep");
                            final HashMap<String, BigInteger> receivers = new HashMap<String, BigInteger>();
                            receivers.put(strReceiveAddress, BigInteger.valueOf(amount));
                            Transaction tx = SendFactory.getInstance(context).makeTransaction(0, outpoints, receivers);
                            Log.d("SweepUtil", "tx is " + ((tx == null) ? "null" : "not null"));
                            tx = SendFactory.getInstance(context).signTransactionForSweep(tx, privKeyReader);
                            final String hexTx = new String(Hex.encode(tx.bitcoinSerialize()));
                            Log.d("SweepUtil", hexTx);
                            // 
                            String response = null;
                            try {
                                response = PushTx.getInstance(context).samourai(hexTx);
                                if (response != null) {
                                    JSONObject jsonObject = new org.json.JSONObject(response);
                                    if (jsonObject.has("status")) {
                                        if (jsonObject.getString("status").equals("ok")) {
                                            Toast.makeText(context, R.string.tx_ok, Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                } else {
                                    Toast.makeText(context, R.string.pushtx_returns_null, Toast.LENGTH_SHORT).show();
                                }
                            } catch (JSONException je) {
                                Toast.makeText(context, "pushTx:" + je.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                            dialog.dismiss();
                        }
                    }).setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {

                        public void onClick(final DialogInterface dialog, int whichButton) {
                            dialog.dismiss();
                        }
                    }).show();
                } else if (type == TYPE_P2SH_P2WPKH) {
                    sweep(privKeyReader, strReceiveAddress, TYPE_P2WPKH);
                } else if (type == TYPE_P2PKH) {
                    sweep(privKeyReader, strReceiveAddress, TYPE_P2SH_P2WPKH);
                } else if (type == TYPE_P2WPKH) {
                    ;
                }
            } catch (Exception e) {
                Log.d("SweepUtil", e.getMessage());
                Toast.makeText(context, context.getText(R.string.cannot_sweep_privkey) + ", " + e.getMessage(), Toast.LENGTH_SHORT).show();
            }
            Looper.loop();
        }
    }).start();
}
Also used : SegwitAddress(com.samourai.sentinel.segwit.SegwitAddress) DialogInterface(android.content.DialogInterface) HashMap(java.util.HashMap) JSONException(org.json.JSONException) JSONException(org.json.JSONException) P2SH_P2WPKH(com.samourai.sentinel.segwit.P2SH_P2WPKH) JSONObject(org.json.JSONObject) Transaction(org.bitcoinj.core.Transaction) JSONObject(org.json.JSONObject) BigInteger(java.math.BigInteger)

Example 3 with P2SH_P2WPKH

use of com.samourai.sentinel.segwit.P2SH_P2WPKH in project sentinel-android by Samourai-Wallet.

the class SendFactory method signTransaction.

private synchronized Transaction signTransaction(Transaction transaction, HashMap<String, ECKey> keyBag) throws ScriptException {
    List<TransactionInput> inputs = transaction.getInputs();
    TransactionInput input = null;
    TransactionOutput connectedOutput = null;
    byte[] connectedPubKeyScript = null;
    TransactionSignature sig = null;
    Script scriptPubKey = null;
    ECKey key = null;
    for (int i = 0; i < inputs.size(); i++) {
        input = inputs.get(i);
        key = keyBag.get(input.getOutpoint().toString());
        connectedPubKeyScript = input.getOutpoint().getConnectedPubKeyScript();
        connectedOutput = input.getOutpoint().getConnectedOutput();
        scriptPubKey = connectedOutput.getScriptPubKey();
        String script = Hex.toHexString(connectedPubKeyScript);
        String address = null;
        if (Bech32Util.getInstance().isBech32Script(script)) {
            try {
                address = Bech32Util.getInstance().getAddressFromScript(script);
            } catch (Exception e) {
                ;
            }
        } else {
            address = new Script(connectedPubKeyScript).getToAddress(MainNetParams.get()).toString();
        }
        if (FormatsUtil.getInstance().isValidBech32(address) || Address.fromBase58(MainNetParams.get(), address).isP2SHAddress()) {
            final P2SH_P2WPKH p2shp2wpkh = new P2SH_P2WPKH(key.getPubKey(), MainNetParams.get());
            System.out.println("pubKey:" + Hex.toHexString(key.getPubKey()));
            // final Script scriptPubKey = p2shp2wpkh.segWitOutputScript();
            // System.out.println("scriptPubKey:" + Hex.toHexString(scriptPubKey.getProgram()));
            System.out.println("to address from script:" + scriptPubKey.getToAddress(MainNetParams.get()).toString());
            final Script redeemScript = p2shp2wpkh.segWitRedeemScript();
            System.out.println("redeem script:" + Hex.toHexString(redeemScript.getProgram()));
            final Script scriptCode = redeemScript.scriptCode();
            System.out.println("script code:" + Hex.toHexString(scriptCode.getProgram()));
            sig = transaction.calculateWitnessSignature(i, key, scriptCode, connectedOutput.getValue(), Transaction.SigHash.ALL, false);
            final TransactionWitness witness = new TransactionWitness(2);
            witness.setPush(0, sig.encodeToBitcoin());
            witness.setPush(1, key.getPubKey());
            transaction.setWitness(i, witness);
            if (!FormatsUtil.getInstance().isValidBech32(address) && Address.fromBase58(MainNetParams.get(), address).isP2SHAddress()) {
                final ScriptBuilder sigScript = new ScriptBuilder();
                sigScript.data(redeemScript.getProgram());
                transaction.getInput(i).setScriptSig(sigScript.build());
                transaction.getInput(i).getScriptSig().correctlySpends(transaction, i, scriptPubKey, connectedOutput.getValue(), Script.ALL_VERIFY_FLAGS);
            }
        } else {
            if (key != null && key.hasPrivKey() || key.isEncrypted()) {
                sig = transaction.calculateSignature(i, key, connectedPubKeyScript, Transaction.SigHash.ALL, false);
            } else {
                // watch only ?
                sig = TransactionSignature.dummy();
            }
            if (scriptPubKey.isSentToAddress()) {
                input.setScriptSig(ScriptBuilder.createInputScript(sig, key));
            } else if (scriptPubKey.isSentToRawPubKey()) {
                input.setScriptSig(ScriptBuilder.createInputScript(sig));
            } else {
                throw new RuntimeException("Unknown script type: " + scriptPubKey);
            }
        }
    }
    return transaction;
}
Also used : Script(org.bitcoinj.script.Script) TransactionOutput(org.bitcoinj.core.TransactionOutput) TransactionWitness(org.bitcoinj.core.TransactionWitness) TransactionSignature(org.bitcoinj.crypto.TransactionSignature) ECKey(org.bitcoinj.core.ECKey) ScriptBuilder(org.bitcoinj.script.ScriptBuilder) TransactionInput(org.bitcoinj.core.TransactionInput) ScriptException(org.bitcoinj.script.ScriptException) AddressFormatException(org.bitcoinj.core.AddressFormatException) P2SH_P2WPKH(com.samourai.sentinel.segwit.P2SH_P2WPKH)

Aggregations

P2SH_P2WPKH (com.samourai.sentinel.segwit.P2SH_P2WPKH)3 ECKey (org.bitcoinj.core.ECKey)2 DialogInterface (android.content.DialogInterface)1 SegwitAddress (com.samourai.sentinel.segwit.SegwitAddress)1 BigInteger (java.math.BigInteger)1 HashMap (java.util.HashMap)1 AddressFormatException (org.bitcoinj.core.AddressFormatException)1 Transaction (org.bitcoinj.core.Transaction)1 TransactionInput (org.bitcoinj.core.TransactionInput)1 TransactionOutput (org.bitcoinj.core.TransactionOutput)1 TransactionWitness (org.bitcoinj.core.TransactionWitness)1 TransactionSignature (org.bitcoinj.crypto.TransactionSignature)1 Script (org.bitcoinj.script.Script)1 ScriptBuilder (org.bitcoinj.script.ScriptBuilder)1 ScriptException (org.bitcoinj.script.ScriptException)1 JSONException (org.json.JSONException)1 JSONObject (org.json.JSONObject)1