Search in sources :

Example 61 with Address

use of org.bitcoinj.core.Address in project Bitcoin-Brainwallet-PasswordCrackPlatform by Dimou-John.

the class AddressGenerator method AddressGenerator.

public static String AddressGenerator(String rest) throws IOException {
    NetworkParameters mainNet = MainNetParams.get();
    String newline = rest;
    rest = getSha256(rest);
    BigInteger big = new BigInteger(rest, 16);
    // uncompressed
    ECKey key = ECKey.fromPrivate(big, false);
    byte[] priv = key.getPrivKeyBytes();
    byte[] bytes = new byte[1 + 32 + 4];
    bytes[0] = (byte) 0x80;
    System.arraycopy(priv, 0, bytes, 1, 32);
    byte[] checksum = Sha256Hash.hashTwice(bytes, 0, 33);
    System.arraycopy(checksum, 0, bytes, 33, 4);
    String wif3 = Base58.encode(bytes);
    Address s = key.toAddress(mainNet);
    String Stringed = s.toString();
    return Stringed;
}
Also used : Address(org.bitcoinj.core.Address) NetworkParameters(org.bitcoinj.core.NetworkParameters) BigInteger(java.math.BigInteger) ECKey(org.bitcoinj.core.ECKey)

Example 62 with Address

use of org.bitcoinj.core.Address in project Bitcoin-Brainwallet-PasswordCrackPlatform by Dimou-John.

the class PrivateKeyGetter method PrivateKeyGetter.

public static String PrivateKeyGetter(String rest) throws IOException {
    NetworkParameters mainNet = MainNetParams.get();
    rest = getSha256(rest);
    BigInteger big = new BigInteger(rest, 16);
    // uncompressed
    ECKey key = ECKey.fromPrivate(big, false);
    byte[] priv = key.getPrivKeyBytes();
    byte[] bytes = new byte[1 + 32 + 4];
    bytes[0] = (byte) 0x80;
    System.arraycopy(priv, 0, bytes, 1, 32);
    byte[] checksum = Sha256Hash.hashTwice(bytes, 0, 33);
    System.arraycopy(checksum, 0, bytes, 33, 4);
    String wif3 = Base58.encode(bytes);
    Address s = key.toAddress(mainNet);
    String Stringed = s.toString();
    return wif3;
}
Also used : Address(org.bitcoinj.core.Address) NetworkParameters(org.bitcoinj.core.NetworkParameters) BigInteger(java.math.BigInteger) ECKey(org.bitcoinj.core.ECKey)

Example 63 with Address

use of org.bitcoinj.core.Address in project samourai-wallet-android by Samourai-Wallet.

the class FormatsUtil method isValidBitcoinAddress.

public boolean isValidBitcoinAddress(final String address) {
    boolean ret = false;
    Address addr = null;
    if ((!SamouraiWallet.getInstance().isTestNet() && address.toLowerCase().startsWith("bc")) || (SamouraiWallet.getInstance().isTestNet() && address.toLowerCase().startsWith("tb"))) {
        try {
            Pair<Byte, byte[]> pair = Bech32Segwit.decode(address.substring(0, 2), address);
            if (pair.getLeft() == null || pair.getRight() == null) {
                ;
            } else {
                ret = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    } else {
        try {
            addr = new Address(SamouraiWallet.getInstance().getCurrentNetworkParams(), address);
            if (addr != null) {
                ret = true;
            }
        } catch (WrongNetworkException wne) {
            ret = false;
        } catch (AddressFormatException afe) {
            ret = false;
        }
    }
    return ret;
}
Also used : AddressFormatException(org.bitcoinj.core.AddressFormatException) Address(org.bitcoinj.core.Address) AddressFormatException(org.bitcoinj.core.AddressFormatException) BitcoinURIParseException(org.bitcoinj.uri.BitcoinURIParseException) WrongNetworkException(org.bitcoinj.core.WrongNetworkException) ParseException(java.text.ParseException) WrongNetworkException(org.bitcoinj.core.WrongNetworkException)

Example 64 with Address

use of org.bitcoinj.core.Address in project samourai-wallet-android by Samourai-Wallet.

the class SendActivity method onCreate.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_send);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    SendActivity.this.getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    if (SamouraiWallet.getInstance().getShowTotalBalance()) {
        if (SamouraiWallet.getInstance().getCurrentSelectedAccount() == 2) {
            selectedAccount = 1;
        } else {
            selectedAccount = 0;
        }
    } else {
        selectedAccount = 0;
    }
    tvMaxPrompt = (TextView) findViewById(R.id.max_prompt);
    tvMax = (TextView) findViewById(R.id.max);
    try {
        balance = APIFactory.getInstance(SendActivity.this).getXpubAmounts().get(HD_WalletFactory.getInstance(SendActivity.this).get().getAccount(selectedAccount).xpubstr());
    } catch (IOException ioe) {
        balance = 0L;
    } catch (MnemonicException.MnemonicLengthException mle) {
        balance = 0L;
    } catch (java.lang.NullPointerException npe) {
        balance = 0L;
    }
    final String strAmount;
    NumberFormat nf = NumberFormat.getInstance(Locale.US);
    nf.setMaximumFractionDigits(8);
    nf.setMinimumFractionDigits(1);
    nf.setMinimumIntegerDigits(1);
    strAmount = nf.format(balance / 1e8);
    tvMax.setText(strAmount + " " + getDisplayUnits());
    tvMaxPrompt.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            edAmountBTC.setText(strAmount);
            return false;
        }
    });
    tvMax.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            edAmountBTC.setText(strAmount);
            return false;
        }
    });
    DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
    DecimalFormatSymbols symbols = format.getDecimalFormatSymbols();
    defaultSeparator = Character.toString(symbols.getDecimalSeparator());
    strFiat = PrefsUtil.getInstance(SendActivity.this).getValue(PrefsUtil.CURRENT_FIAT, "USD");
    btc_fx = ExchangeRateFactory.getInstance(SendActivity.this).getAvgPrice(strFiat);
    tvFiatSymbol = (TextView) findViewById(R.id.fiatSymbol);
    tvFiatSymbol.setText(getDisplayUnits() + "-" + strFiat);
    edAddress = (EditText) findViewById(R.id.destination);
    textWatcherAddress = new TextWatcher() {

        public void afterTextChanged(Editable s) {
            validateSpend();
        }

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            ;
        }

        public void onTextChanged(CharSequence s, int start, int before, int count) {
            ;
        }
    };
    edAddress.addTextChangedListener(textWatcherAddress);
    edAddress.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // final int DRAWABLE_LEFT = 0;
            // final int DRAWABLE_TOP = 1;
            final int DRAWABLE_RIGHT = 2;
            if (event.getAction() == MotionEvent.ACTION_UP && event.getRawX() >= (edAddress.getRight() - edAddress.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
                final List<String> entries = new ArrayList<String>();
                entries.addAll(BIP47Meta.getInstance().getSortedByLabels(false));
                final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(SendActivity.this, android.R.layout.select_dialog_singlechoice);
                for (int i = 0; i < entries.size(); i++) {
                    arrayAdapter.add(BIP47Meta.getInstance().getDisplayLabel(entries.get(i)));
                }
                AlertDialog.Builder dlg = new AlertDialog.Builder(SendActivity.this);
                dlg.setIcon(R.drawable.ic_launcher);
                dlg.setTitle(R.string.app_name);
                dlg.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // Toast.makeText(SendActivity.this, BIP47Meta.getInstance().getDisplayLabel(entries.get(which)), Toast.LENGTH_SHORT).show();
                        // Toast.makeText(SendActivity.this, entries.get(which), Toast.LENGTH_SHORT).show();
                        processPCode(entries.get(which), null);
                    }
                });
                dlg.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                dlg.show();
                return true;
            }
            return false;
        }
    });
    edAmountBTC = (EditText) findViewById(R.id.amountBTC);
    edAmountFiat = (EditText) findViewById(R.id.amountFiat);
    textWatcherBTC = new TextWatcher() {

        public void afterTextChanged(Editable s) {
            edAmountBTC.removeTextChangedListener(this);
            edAmountFiat.removeTextChangedListener(textWatcherFiat);
            int max_len = 8;
            NumberFormat btcFormat = NumberFormat.getInstance(Locale.US);
            btcFormat.setMaximumFractionDigits(max_len + 1);
            btcFormat.setMinimumFractionDigits(0);
            double d = 0.0;
            try {
                d = NumberFormat.getInstance(Locale.US).parse(s.toString()).doubleValue();
                String s1 = btcFormat.format(d);
                if (s1.indexOf(defaultSeparator) != -1) {
                    String dec = s1.substring(s1.indexOf(defaultSeparator));
                    if (dec.length() > 0) {
                        dec = dec.substring(1);
                        if (dec.length() > max_len) {
                            edAmountBTC.setText(s1.substring(0, s1.length() - 1));
                            edAmountBTC.setSelection(edAmountBTC.getText().length());
                            s = edAmountBTC.getEditableText();
                        }
                    }
                }
            } catch (NumberFormatException nfe) {
                ;
            } catch (ParseException pe) {
                ;
            }
            if (d > 21000000.0) {
                edAmountFiat.setText("0.00");
                edAmountFiat.setSelection(edAmountFiat.getText().length());
                edAmountBTC.setText("0");
                edAmountBTC.setSelection(edAmountBTC.getText().length());
                Toast.makeText(SendActivity.this, R.string.invalid_amount, Toast.LENGTH_SHORT).show();
            } else {
                edAmountFiat.setText(MonetaryUtil.getInstance().getFiatFormat(strFiat).format(d * btc_fx));
                edAmountFiat.setSelection(edAmountFiat.getText().length());
            }
            edAmountFiat.addTextChangedListener(textWatcherFiat);
            edAmountBTC.addTextChangedListener(this);
            validateSpend();
        }

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            ;
        }

        public void onTextChanged(CharSequence s, int start, int before, int count) {
            ;
        }
    };
    edAmountBTC.addTextChangedListener(textWatcherBTC);
    textWatcherFiat = new TextWatcher() {

        public void afterTextChanged(Editable s) {
            edAmountFiat.removeTextChangedListener(this);
            edAmountBTC.removeTextChangedListener(textWatcherBTC);
            int max_len = 2;
            NumberFormat fiatFormat = NumberFormat.getInstance(Locale.US);
            fiatFormat.setMaximumFractionDigits(max_len + 1);
            fiatFormat.setMinimumFractionDigits(0);
            double d = 0.0;
            try {
                d = NumberFormat.getInstance(Locale.US).parse(s.toString()).doubleValue();
                String s1 = fiatFormat.format(d);
                if (s1.indexOf(defaultSeparator) != -1) {
                    String dec = s1.substring(s1.indexOf(defaultSeparator));
                    if (dec.length() > 0) {
                        dec = dec.substring(1);
                        if (dec.length() > max_len) {
                            edAmountFiat.setText(s1.substring(0, s1.length() - 1));
                            edAmountFiat.setSelection(edAmountFiat.getText().length());
                        }
                    }
                }
            } catch (NumberFormatException nfe) {
                ;
            } catch (ParseException pe) {
                ;
            }
            if ((d / btc_fx) > 21000000.0) {
                edAmountFiat.setText("0.00");
                edAmountFiat.setSelection(edAmountFiat.getText().length());
                edAmountBTC.setText("0");
                edAmountBTC.setSelection(edAmountBTC.getText().length());
                Toast.makeText(SendActivity.this, R.string.invalid_amount, Toast.LENGTH_SHORT).show();
            } else {
                edAmountBTC.setText(MonetaryUtil.getInstance().getBTCFormat().format(d / btc_fx));
                edAmountBTC.setSelection(edAmountBTC.getText().length());
            }
            edAmountBTC.addTextChangedListener(textWatcherBTC);
            edAmountFiat.addTextChangedListener(this);
            validateSpend();
        }

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            ;
        }

        public void onTextChanged(CharSequence s, int start, int before, int count) {
            ;
        }
    };
    edAmountFiat.addTextChangedListener(textWatcherFiat);
    SPEND_TYPE = PrefsUtil.getInstance(SendActivity.this).getValue(PrefsUtil.USE_BIP126, true) ? SPEND_BIP126 : SPEND_SIMPLE;
    if (SPEND_TYPE > SPEND_BIP126) {
        SPEND_TYPE = SPEND_BIP126;
        PrefsUtil.getInstance(SendActivity.this).setValue(PrefsUtil.SPEND_TYPE, SPEND_BIP126);
    }
    swRicochet = (Switch) findViewById(R.id.ricochet);
    swRicochet.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                SPEND_TYPE = SPEND_RICOCHET;
            } else {
                SPEND_TYPE = PrefsUtil.getInstance(SendActivity.this).getValue(PrefsUtil.SPEND_TYPE, SPEND_BIP126);
            }
        }
    });
    btLowFee = (Button) findViewById(R.id.low_fee);
    btAutoFee = (Button) findViewById(R.id.auto_fee);
    btPriorityFee = (Button) findViewById(R.id.priority_fee);
    btCustomFee = (Button) findViewById(R.id.custom_fee);
    tvFeePrompt = (TextView) findViewById(R.id.current_fee_prompt);
    FEE_TYPE = PrefsUtil.getInstance(SendActivity.this).getValue(PrefsUtil.CURRENT_FEE_TYPE, FEE_NORMAL);
    long lo = FeeUtil.getInstance().getLowFee().getDefaultPerKB().longValue() / 1000L;
    long mi = FeeUtil.getInstance().getNormalFee().getDefaultPerKB().longValue() / 1000L;
    long hi = FeeUtil.getInstance().getHighFee().getDefaultPerKB().longValue() / 1000L;
    if (lo == mi && mi == hi) {
        lo = (long) ((double) mi * 0.85);
        hi = (long) ((double) mi * 1.15);
        SuggestedFee lo_sf = new SuggestedFee();
        lo_sf.setDefaultPerKB(BigInteger.valueOf(lo * 1000L));
        FeeUtil.getInstance().setLowFee(lo_sf);
        SuggestedFee hi_sf = new SuggestedFee();
        hi_sf.setDefaultPerKB(BigInteger.valueOf(hi * 1000L));
        FeeUtil.getInstance().setHighFee(hi_sf);
    } else if (lo == mi || mi == hi) {
        mi = (lo + hi) / 2L;
        SuggestedFee mi_sf = new SuggestedFee();
        mi_sf.setDefaultPerKB(BigInteger.valueOf(mi * 1000L));
        FeeUtil.getInstance().setNormalFee(mi_sf);
    } else {
        ;
    }
    switch(FEE_TYPE) {
        case FEE_LOW:
            FeeUtil.getInstance().setSuggestedFee(FeeUtil.getInstance().getLowFee());
            btLowFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.blue));
            btAutoFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btPriorityFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btCustomFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btLowFee.setTypeface(null, Typeface.BOLD);
            btAutoFee.setTypeface(null, Typeface.NORMAL);
            btPriorityFee.setTypeface(null, Typeface.NORMAL);
            btCustomFee.setTypeface(null, Typeface.NORMAL);
            tvFeePrompt.setText(getText(R.string.fee_low_priority) + " " + getText(R.string.blocks_to_cf));
            break;
        case FEE_PRIORITY:
            FeeUtil.getInstance().setSuggestedFee(FeeUtil.getInstance().getHighFee());
            btLowFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btAutoFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btPriorityFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.blue));
            btCustomFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btLowFee.setTypeface(null, Typeface.NORMAL);
            btAutoFee.setTypeface(null, Typeface.NORMAL);
            btPriorityFee.setTypeface(null, Typeface.BOLD);
            btCustomFee.setTypeface(null, Typeface.NORMAL);
            tvFeePrompt.setText(getText(R.string.fee_high_priority) + " " + getText(R.string.blocks_to_cf));
            break;
        default:
            FeeUtil.getInstance().setSuggestedFee(FeeUtil.getInstance().getNormalFee());
            btLowFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btAutoFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.blue));
            btPriorityFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btCustomFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btLowFee.setTypeface(null, Typeface.NORMAL);
            btAutoFee.setTypeface(null, Typeface.BOLD);
            btPriorityFee.setTypeface(null, Typeface.NORMAL);
            btCustomFee.setTypeface(null, Typeface.NORMAL);
            tvFeePrompt.setText(getText(R.string.fee_mid_priority) + " " + getText(R.string.blocks_to_cf));
            break;
    }
    btLowFee.setText((FeeUtil.getInstance().getLowFee().getDefaultPerKB().longValue() / 1000L) + "\n" + getString(R.string.sat_b));
    btPriorityFee.setText((FeeUtil.getInstance().getHighFee().getDefaultPerKB().longValue() / 1000L) + "\n" + getString(R.string.sat_b));
    btAutoFee.setText((FeeUtil.getInstance().getNormalFee().getDefaultPerKB().longValue() / 1000L) + "\n" + getString(R.string.sat_b));
    btLowFee.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            FeeUtil.getInstance().setSuggestedFee(FeeUtil.getInstance().getLowFee());
            PrefsUtil.getInstance(SendActivity.this).setValue(PrefsUtil.CURRENT_FEE_TYPE, FEE_LOW);
            btLowFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.blue));
            btAutoFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btPriorityFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btCustomFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btLowFee.setTypeface(null, Typeface.BOLD);
            btAutoFee.setTypeface(null, Typeface.NORMAL);
            btPriorityFee.setTypeface(null, Typeface.NORMAL);
            btCustomFee.setTypeface(null, Typeface.NORMAL);
            btCustomFee.setText(R.string.custom_fee);
            tvFeePrompt.setText(getText(R.string.fee_low_priority) + " " + getText(R.string.blocks_to_cf));
        }
    });
    btAutoFee.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            FeeUtil.getInstance().setSuggestedFee(FeeUtil.getInstance().getNormalFee());
            PrefsUtil.getInstance(SendActivity.this).setValue(PrefsUtil.CURRENT_FEE_TYPE, FEE_NORMAL);
            btLowFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btAutoFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.blue));
            btPriorityFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btCustomFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btLowFee.setTypeface(null, Typeface.NORMAL);
            btAutoFee.setTypeface(null, Typeface.BOLD);
            btPriorityFee.setTypeface(null, Typeface.NORMAL);
            btCustomFee.setTypeface(null, Typeface.NORMAL);
            btCustomFee.setText(R.string.custom_fee);
            tvFeePrompt.setText(getText(R.string.fee_mid_priority) + " " + getText(R.string.blocks_to_cf));
        }
    });
    btPriorityFee.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            FeeUtil.getInstance().setSuggestedFee(FeeUtil.getInstance().getHighFee());
            PrefsUtil.getInstance(SendActivity.this).setValue(PrefsUtil.CURRENT_FEE_TYPE, FEE_PRIORITY);
            btLowFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btAutoFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btPriorityFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.blue));
            btCustomFee.setBackgroundColor(SendActivity.this.getResources().getColor(R.color.darkgrey));
            btLowFee.setTypeface(null, Typeface.NORMAL);
            btAutoFee.setTypeface(null, Typeface.NORMAL);
            btPriorityFee.setTypeface(null, Typeface.BOLD);
            btCustomFee.setTypeface(null, Typeface.NORMAL);
            btCustomFee.setText(R.string.custom_fee);
            tvFeePrompt.setText(getText(R.string.fee_high_priority) + " " + getText(R.string.blocks_to_cf));
        }
    });
    btCustomFee.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            doCustomFee();
        }
    });
    btSend = (Button) findViewById(R.id.send);
    btSend.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            btSend.setClickable(false);
            btSend.setActivated(false);
            double btc_amount = 0.0;
            try {
                btc_amount = NumberFormat.getInstance(Locale.US).parse(edAmountBTC.getText().toString().trim()).doubleValue();
            // Log.i("SendFragment", "amount entered:" + btc_amount);
            } catch (NumberFormatException nfe) {
                btc_amount = 0.0;
            } catch (ParseException pe) {
                btc_amount = 0.0;
            }
            double dAmount = btc_amount;
            long amount = (long) (Math.round(dAmount * 1e8));
            ;
            // Log.i("SendActivity", "amount:" + amount);
            final String address = strDestinationBTCAddress == null ? edAddress.getText().toString() : strDestinationBTCAddress;
            final int accountIdx = selectedAccount;
            final boolean isSegwitChange = (FormatsUtil.getInstance().isValidBech32(address) || Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) || PrefsUtil.getInstance(SendActivity.this).getValue(PrefsUtil.USE_LIKE_TYPED_CHANGE, true) == false;
            final HashMap<String, BigInteger> receivers = new HashMap<String, BigInteger>();
            receivers.put(address, BigInteger.valueOf(amount));
            // store current change index to restore value in case of sending fail
            int change_index = 0;
            if (isSegwitChange) {
                change_index = BIP49Util.getInstance(SendActivity.this).getWallet().getAccount(0).getChange().getAddrIdx();
            } else {
                try {
                    change_index = HD_WalletFactory.getInstance(SendActivity.this).get().getAccount(0).getChange().getAddrIdx();
                // Log.d("SendActivity", "storing change index:" + change_index);
                } catch (IOException ioe) {
                    ;
                } catch (MnemonicException.MnemonicLengthException mle) {
                    ;
                }
            }
            // get all UTXO
            List<UTXO> utxos = null;
            // if possible, get UTXO by input 'type': p2pkh or p2sh-p2wpkh, else get all UTXO
            long neededAmount = 0L;
            if (FormatsUtil.getInstance().isValidBech32(address) || Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
                neededAmount += FeeUtil.getInstance().estimatedFeeSegwit(0, UTXOFactory.getInstance().getCountP2SH_P2WPKH(), 4).longValue();
            // Log.d("SendActivity", "segwit:" + neededAmount);
            } else {
                neededAmount += FeeUtil.getInstance().estimatedFeeSegwit(UTXOFactory.getInstance().getCountP2PKH(), 0, 4).longValue();
            // Log.d("SendActivity", "p2pkh:" + neededAmount);
            }
            neededAmount += amount;
            neededAmount += SamouraiWallet.bDust.longValue();
            if ((FormatsUtil.getInstance().isValidBech32(address) || Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) && (UTXOFactory.getInstance().getP2SH_P2WPKH().size() > 0 && UTXOFactory.getInstance().getTotalP2SH_P2WPKH() > neededAmount)) {
                utxos = new ArrayList<UTXO>(UTXOFactory.getInstance().getP2SH_P2WPKH().values());
            // Log.d("SendActivity", "segwit utxos:" + utxos.size());
            } else if ((UTXOFactory.getInstance().getP2PKH().size() > 0) && (UTXOFactory.getInstance().getTotalP2PKH() > neededAmount)) {
                utxos = new ArrayList<UTXO>(UTXOFactory.getInstance().getP2PKH().values());
            // Log.d("SendActivity", "p2pkh utxos:" + utxos.size());
            } else {
                utxos = APIFactory.getInstance(SendActivity.this).getUtxos(true);
            // Log.d("SendActivity", "all filtered utxos:" + utxos.size());
            }
            final List<UTXO> selectedUTXO = new ArrayList<UTXO>();
            long totalValueSelected = 0L;
            long change = 0L;
            BigInteger fee = null;
            // insufficient funds
            if (amount > balance) {
                Toast.makeText(SendActivity.this, R.string.insufficient_funds, Toast.LENGTH_SHORT).show();
            } else // entire balance (can only be simple spend)
            if (amount == balance) {
                // make sure we are using simple spend
                SPEND_TYPE = SPEND_SIMPLE;
                // Log.d("SendActivity", "amount == balance");
                // take all utxos, deduct fee
                selectedUTXO.addAll(utxos);
                for (UTXO u : selectedUTXO) {
                    totalValueSelected += u.getValue();
                }
            // Log.d("SendActivity", "balance:" + balance);
            // Log.d("SendActivity", "total value selected:" + totalValueSelected);
            } else {
                ;
            }
            org.apache.commons.lang3.tuple.Pair<ArrayList<MyTransactionOutPoint>, ArrayList<TransactionOutput>> pair = null;
            if (SPEND_TYPE == SPEND_RICOCHET) {
                boolean samouraiFeeViaBIP47 = false;
                if (BIP47Meta.getInstance().getOutgoingStatus(BIP47Meta.strSamouraiDonationPCode) == BIP47Meta.STATUS_SENT_CFM) {
                    samouraiFeeViaBIP47 = true;
                }
                final JSONObject jObj = RicochetMeta.getInstance(SendActivity.this).script(amount, FeeUtil.getInstance().getSuggestedFee().getDefaultPerKB().longValue(), address, 4, strPCode, samouraiFeeViaBIP47);
                if (jObj != null) {
                    try {
                        long totalAmount = jObj.getLong("total_spend");
                        if (totalAmount > balance) {
                            Toast.makeText(SendActivity.this, R.string.insufficient_funds, Toast.LENGTH_SHORT).show();
                            return;
                        }
                        String msg = getText(R.string.ricochet_spend1) + " " + address + " " + getText(R.string.ricochet_spend2) + " " + Coin.valueOf(totalAmount).toPlainString() + " " + getText(R.string.ricochet_spend3);
                        AlertDialog.Builder dlg = new AlertDialog.Builder(SendActivity.this).setTitle(R.string.app_name).setMessage(msg).setCancelable(false).setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {

                            public void onClick(DialogInterface dialog, int whichButton) {
                                RicochetMeta.getInstance(SendActivity.this).add(jObj);
                                dialog.dismiss();
                                Intent intent = new Intent(SendActivity.this, RicochetActivity.class);
                                startActivityForResult(intent, RICOCHET);
                            }
                        }).setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {

                            public void onClick(DialogInterface dialog, int whichButton) {
                                dialog.dismiss();
                            }
                        });
                        if (!isFinishing()) {
                            dlg.show();
                        }
                        return;
                    } catch (JSONException je) {
                        return;
                    }
                }
                return;
            } else // if BIP126 try both hetero/alt, if fails change type to SPEND_SIMPLE
            if (SPEND_TYPE == SPEND_BIP126) {
                List<UTXO> _utxos = utxos;
                // Collections.shuffle(_utxos);
                // sort in descending order by value
                Collections.sort(_utxos, new UTXO.UTXOComparator());
                // hetero
                pair = SendFactory.getInstance(SendActivity.this).heterogeneous(_utxos, BigInteger.valueOf(amount), address);
                if (pair == null) {
                    // Collections.sort(_utxos, new UTXO.UTXOComparator());
                    // alt
                    pair = SendFactory.getInstance(SendActivity.this).altHeterogeneous(_utxos, BigInteger.valueOf(amount), address);
                }
                if (pair == null) {
                    // can't do BIP126, revert to SPEND_SIMPLE
                    SPEND_TYPE = SPEND_SIMPLE;
                }
            } else {
                ;
            }
            // simple spend (less than balance)
            if (SPEND_TYPE == SPEND_SIMPLE) {
                List<UTXO> _utxos = utxos;
                // sort in ascending order by value
                Collections.sort(_utxos, new UTXO.UTXOComparator());
                Collections.reverse(_utxos);
                // get smallest 1 UTXO > than spend + fee + dust
                for (UTXO u : _utxos) {
                    Pair<Integer, Integer> outpointTypes = FeeUtil.getInstance().getOutpointCount(u.getOutpoints());
                    if (u.getValue() >= (amount + SamouraiWallet.bDust.longValue() + FeeUtil.getInstance().estimatedFeeSegwit(outpointTypes.getLeft(), outpointTypes.getRight(), 2).longValue())) {
                        selectedUTXO.add(u);
                        totalValueSelected += u.getValue();
                        // Log.d("SendActivity", "nb inputs:" + u.getOutpoints().size());
                        break;
                    }
                }
                if (selectedUTXO.size() == 0) {
                    // sort in descending order by value
                    Collections.sort(_utxos, new UTXO.UTXOComparator());
                    int selected = 0;
                    int p2pkh = 0;
                    int p2wpkh = 0;
                    // get largest UTXOs > than spend + fee + dust
                    for (UTXO u : _utxos) {
                        selectedUTXO.add(u);
                        totalValueSelected += u.getValue();
                        selected += u.getOutpoints().size();
                        // Log.d("SendActivity", "value selected:" + u.getValue());
                        // Log.d("SendActivity", "total value selected/threshold:" + totalValueSelected + "/" + (amount + SamouraiWallet.bDust.longValue() + FeeUtil.getInstance().estimatedFee(selected, 2).longValue()));
                        Pair<Integer, Integer> outpointTypes = FeeUtil.getInstance().getOutpointCount(u.getOutpoints());
                        p2pkh += outpointTypes.getLeft();
                        p2wpkh += outpointTypes.getRight();
                        if (totalValueSelected >= (amount + SamouraiWallet.bDust.longValue() + FeeUtil.getInstance().estimatedFeeSegwit(p2pkh, p2wpkh, 2).longValue())) {
                            // Log.d("SendActivity", "nb inputs:" + selected);
                            break;
                        }
                    }
                }
            } else if (pair != null) {
                selectedUTXO.clear();
                receivers.clear();
                long inputAmount = 0L;
                long outputAmount = 0L;
                for (MyTransactionOutPoint outpoint : pair.getLeft()) {
                    UTXO u = new UTXO();
                    List<MyTransactionOutPoint> outs = new ArrayList<MyTransactionOutPoint>();
                    outs.add(outpoint);
                    u.setOutpoints(outs);
                    totalValueSelected += u.getValue();
                    selectedUTXO.add(u);
                    inputAmount += u.getValue();
                }
                for (TransactionOutput output : pair.getRight()) {
                    try {
                        Script script = new Script(output.getScriptBytes());
                        receivers.put(script.getToAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString(), BigInteger.valueOf(output.getValue().longValue()));
                        outputAmount += output.getValue().longValue();
                    } catch (Exception e) {
                        Toast.makeText(SendActivity.this, R.string.error_bip126_output, Toast.LENGTH_SHORT).show();
                        return;
                    }
                }
                change = outputAmount - amount;
                fee = BigInteger.valueOf(inputAmount - outputAmount);
            } else {
                Toast.makeText(SendActivity.this, R.string.cannot_select_utxo, Toast.LENGTH_SHORT).show();
                return;
            }
            // do spend here
            if (selectedUTXO.size() > 0) {
                // estimate fee for simple spend, already done if BIP126
                if (SPEND_TYPE == SPEND_SIMPLE) {
                    List<MyTransactionOutPoint> outpoints = new ArrayList<MyTransactionOutPoint>();
                    for (UTXO utxo : selectedUTXO) {
                        outpoints.addAll(utxo.getOutpoints());
                    }
                    Pair<Integer, Integer> outpointTypes = FeeUtil.getInstance().getOutpointCount(outpoints);
                    fee = FeeUtil.getInstance().estimatedFeeSegwit(outpointTypes.getLeft(), outpointTypes.getRight(), 2);
                }
                // Log.d("SendActivity", "spend type:" + SPEND_TYPE);
                // Log.d("SendActivity", "amount:" + amount);
                // Log.d("SendActivity", "total value selected:" + totalValueSelected);
                // Log.d("SendActivity", "fee:" + fee.longValue());
                // Log.d("SendActivity", "nb inputs:" + selectedUTXO.size());
                change = totalValueSelected - (amount + fee.longValue());
                // Log.d("SendActivity", "change:" + change);
                boolean changeIsDust = false;
                if (change < SamouraiWallet.bDust.longValue() && SPEND_TYPE == SPEND_SIMPLE) {
                    change = 0L;
                    fee = fee.add(BigInteger.valueOf(change));
                    amount = totalValueSelected - fee.longValue();
                    // Log.d("SendActivity", "fee:" + fee.longValue());
                    // Log.d("SendActivity", "change:" + change);
                    // Log.d("SendActivity", "amount:" + amount);
                    receivers.put(address, BigInteger.valueOf(amount));
                    changeIsDust = true;
                }
                final long _change = change;
                final BigInteger _fee = fee;
                final int _change_index = change_index;
                String dest = null;
                if (strPCode != null && strPCode.length() > 0) {
                    dest = BIP47Meta.getInstance().getDisplayLabel(strPCode);
                } else {
                    dest = address;
                }
                final String strPrivacyWarning;
                if (SendAddressUtil.getInstance().get(address) == 1) {
                    strPrivacyWarning = getString(R.string.send_privacy_warning) + "\n\n";
                } else {
                    strPrivacyWarning = "";
                }
                String strChangeIsDust = null;
                if (changeIsDust) {
                    strChangeIsDust = getString(R.string.change_is_dust) + "\n\n";
                } else {
                    strChangeIsDust = "";
                }
                String message = strChangeIsDust + strPrivacyWarning + "Send " + Coin.valueOf(amount).toPlainString() + " to " + dest + " (fee:" + Coin.valueOf(_fee.longValue()).toPlainString() + ")?\n";
                final long _amount = amount;
                AlertDialog.Builder builder = new AlertDialog.Builder(SendActivity.this);
                builder.setTitle(R.string.app_name);
                builder.setMessage(message);
                final CheckBox cbShowAgain;
                if (strPrivacyWarning.length() > 0) {
                    cbShowAgain = new CheckBox(SendActivity.this);
                    cbShowAgain.setText(R.string.do_not_repeat_sent_to);
                    cbShowAgain.setChecked(false);
                    builder.setView(cbShowAgain);
                } else {
                    cbShowAgain = null;
                }
                builder.setCancelable(false);
                builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {

                    public void onClick(final DialogInterface dialog, int whichButton) {
                        final ProgressDialog progress = new ProgressDialog(SendActivity.this);
                        progress.setCancelable(false);
                        progress.setTitle(R.string.app_name);
                        progress.setMessage(getString(R.string.please_wait_sending));
                        progress.show();
                        final List<MyTransactionOutPoint> outPoints = new ArrayList<MyTransactionOutPoint>();
                        for (UTXO u : selectedUTXO) {
                            outPoints.addAll(u.getOutpoints());
                        }
                        // add change
                        if (_change > 0L) {
                            if (SPEND_TYPE == SPEND_SIMPLE) {
                                if (isSegwitChange) {
                                    String change_address = BIP49Util.getInstance(SendActivity.this).getAddressAt(AddressFactory.CHANGE_CHAIN, BIP49Util.getInstance(SendActivity.this).getWallet().getAccount(0).getChange().getAddrIdx()).getAddressAsString();
                                    receivers.put(change_address, BigInteger.valueOf(_change));
                                } else {
                                    try {
                                        String change_address = HD_WalletFactory.getInstance(SendActivity.this).get().getAccount(0).getChange().getAddressAt(HD_WalletFactory.getInstance(SendActivity.this).get().getAccount(0).getChange().getAddrIdx()).getAddressString();
                                        receivers.put(change_address, BigInteger.valueOf(_change));
                                    } catch (IOException ioe) {
                                        Toast.makeText(SendActivity.this, R.string.error_change_output, Toast.LENGTH_SHORT).show();
                                        return;
                                    } catch (MnemonicException.MnemonicLengthException mle) {
                                        Toast.makeText(SendActivity.this, R.string.error_change_output, Toast.LENGTH_SHORT).show();
                                        return;
                                    }
                                }
                            } else if (SPEND_TYPE == SPEND_BIP126) {
                            // do nothing, change addresses included
                            } else {
                                ;
                            }
                        }
                        // make tx
                        Transaction tx = SendFactory.getInstance(SendActivity.this).makeTransaction(0, outPoints, receivers);
                        final RBFSpend rbf;
                        if (PrefsUtil.getInstance(SendActivity.this).getValue(PrefsUtil.RBF_OPT_IN, false) == true) {
                            rbf = new RBFSpend();
                            for (TransactionInput input : tx.getInputs()) {
                                boolean _isBIP49 = false;
                                String _addr = null;
                                Address _address = input.getConnectedOutput().getAddressFromP2PKHScript(SamouraiWallet.getInstance().getCurrentNetworkParams());
                                if (_address != null) {
                                    _addr = _address.toString();
                                }
                                if (_addr == null) {
                                    _addr = input.getConnectedOutput().getAddressFromP2SH(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
                                    _isBIP49 = true;
                                }
                                String path = APIFactory.getInstance(SendActivity.this).getUnspentPaths().get(_addr);
                                if (path != null) {
                                    if (_isBIP49) {
                                        rbf.addKey(input.getOutpoint().toString(), path + "/49");
                                    } else {
                                        rbf.addKey(input.getOutpoint().toString(), path);
                                    }
                                } else {
                                    String pcode = BIP47Meta.getInstance().getPCode4Addr(_addr);
                                    int idx = BIP47Meta.getInstance().getIdx4Addr(_addr);
                                    rbf.addKey(input.getOutpoint().toString(), pcode + "/" + idx);
                                }
                            }
                        } else {
                            rbf = null;
                        }
                        if (tx != null) {
                            tx = SendFactory.getInstance(SendActivity.this).signTransaction(tx);
                            final Transaction _tx = tx;
                            final String hexTx = new String(Hex.encode(tx.bitcoinSerialize()));
                            // Log.d("SendActivity", hexTx);
                            final String strTxHash = tx.getHashAsString();
                            if (PrefsUtil.getInstance(SendActivity.this).getValue(PrefsUtil.BROADCAST_TX, true) == false) {
                                if (progress != null && progress.isShowing()) {
                                    progress.dismiss();
                                }
                                doShowTx(hexTx, strTxHash);
                                return;
                            }
                            new Thread(new Runnable() {

                                @Override
                                public void run() {
                                    Looper.prepare();
                                    boolean isOK = false;
                                    String response = null;
                                    try {
                                        if (PrefsUtil.getInstance(SendActivity.this).getValue(PrefsUtil.USE_TRUSTED_NODE, false) == true) {
                                            if (TrustedNodeUtil.getInstance().isSet()) {
                                                response = PushTx.getInstance(SendActivity.this).trustedNode(hexTx);
                                                JSONObject jsonObject = new org.json.JSONObject(response);
                                                if (jsonObject.has("result")) {
                                                    if (jsonObject.getString("result").matches("^[A-Za-z0-9]{64}$")) {
                                                        isOK = true;
                                                    } else {
                                                        Toast.makeText(SendActivity.this, R.string.trusted_node_tx_error, Toast.LENGTH_SHORT).show();
                                                    }
                                                }
                                            } else {
                                                Toast.makeText(SendActivity.this, R.string.trusted_node_not_valid, Toast.LENGTH_SHORT).show();
                                            }
                                        } else {
                                            response = PushTx.getInstance(SendActivity.this).samourai(hexTx);
                                            if (response != null) {
                                                JSONObject jsonObject = new org.json.JSONObject(response);
                                                if (jsonObject.has("status")) {
                                                    if (jsonObject.getString("status").equals("ok")) {
                                                        isOK = true;
                                                    }
                                                }
                                            } else {
                                                Toast.makeText(SendActivity.this, R.string.pushtx_returns_null, Toast.LENGTH_SHORT).show();
                                            }
                                        }
                                        if (isOK) {
                                            if (PrefsUtil.getInstance(SendActivity.this).getValue(PrefsUtil.USE_TRUSTED_NODE, false) == false) {
                                                Toast.makeText(SendActivity.this, R.string.tx_sent, Toast.LENGTH_SHORT).show();
                                            } else {
                                                Toast.makeText(SendActivity.this, R.string.trusted_node_tx_sent, Toast.LENGTH_SHORT).show();
                                            }
                                            if (_change > 0L && SPEND_TYPE == SPEND_SIMPLE) {
                                                if (isSegwitChange) {
                                                    BIP49Util.getInstance(SendActivity.this).getWallet().getAccount(0).getChange().incAddrIdx();
                                                } else {
                                                    try {
                                                        HD_WalletFactory.getInstance(SendActivity.this).get().getAccount(0).getChange().incAddrIdx();
                                                    } catch (IOException ioe) {
                                                        ;
                                                    } catch (MnemonicException.MnemonicLengthException mle) {
                                                        ;
                                                    }
                                                }
                                            }
                                            if (PrefsUtil.getInstance(SendActivity.this).getValue(PrefsUtil.RBF_OPT_IN, false) == true) {
                                                for (TransactionOutput out : _tx.getOutputs()) {
                                                    try {
                                                        if (!isSegwitChange && !address.equals(out.getAddressFromP2PKHScript(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString())) {
                                                            rbf.addChangeAddr(out.getAddressFromP2PKHScript(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString());
                                                        } else if (isSegwitChange && !address.equals(out.getAddressFromP2SH(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString())) {
                                                            rbf.addChangeAddr(out.getAddressFromP2SH(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString());
                                                        } else {
                                                            ;
                                                        }
                                                    } catch (NullPointerException npe) {
                                                        // test for bech32, skip for now as it's not a change address
                                                        ;
                                                    }
                                                }
                                                rbf.setHash(strTxHash);
                                                rbf.setSerializedTx(hexTx);
                                                RBFUtil.getInstance().add(rbf);
                                            }
                                            // increment counter if BIP47 spend
                                            if (strPCode != null && strPCode.length() > 0) {
                                                BIP47Meta.getInstance().getPCode4AddrLookup().put(address, strPCode);
                                                BIP47Meta.getInstance().inc(strPCode);
                                                SimpleDateFormat sd = new SimpleDateFormat("dd MMM");
                                                String strTS = sd.format(currentTimeMillis());
                                                String event = strTS + " " + SendActivity.this.getString(R.string.sent) + " " + MonetaryUtil.getInstance().getBTCFormat().format((double) _amount / 1e8) + " BTC";
                                                BIP47Meta.getInstance().setLatestEvent(strPCode, event);
                                                strPCode = null;
                                            }
                                            if (strPrivacyWarning.length() > 0 && cbShowAgain != null) {
                                                SendAddressUtil.getInstance().add(address, cbShowAgain.isChecked() ? false : true);
                                            } else if (SendAddressUtil.getInstance().get(address) == 0) {
                                                SendAddressUtil.getInstance().add(address, false);
                                            } else {
                                                SendAddressUtil.getInstance().add(address, true);
                                            }
                                            Intent intent = new Intent("com.samourai.wallet.BalanceFragment.REFRESH");
                                            intent.putExtra("notifTx", false);
                                            intent.putExtra("fetch", true);
                                            LocalBroadcastManager.getInstance(SendActivity.this).sendBroadcast(intent);
                                            View view = SendActivity.this.getCurrentFocus();
                                            if (view != null) {
                                                InputMethodManager imm = (InputMethodManager) SendActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE);
                                                imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                                            }
                                            if (bViaMenu) {
                                                SendActivity.this.finish();
                                            } else {
                                                Intent _intent = new Intent(SendActivity.this, BalanceActivity.class);
                                                _intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                                                startActivity(_intent);
                                            }
                                        } else {
                                            Toast.makeText(SendActivity.this, R.string.tx_failed, Toast.LENGTH_SHORT).show();
                                            // reset change index upon tx fail
                                            if (isSegwitChange) {
                                                BIP49Util.getInstance(SendActivity.this).getWallet().getAccount(0).getChange().setAddrIdx(_change_index);
                                            } else {
                                                HD_WalletFactory.getInstance(SendActivity.this).get().getAccount(0).getChange().setAddrIdx(_change_index);
                                            }
                                        }
                                    } catch (JSONException je) {
                                        Toast.makeText(SendActivity.this, "pushTx:" + je.getMessage(), Toast.LENGTH_SHORT).show();
                                    } catch (MnemonicException.MnemonicLengthException mle) {
                                        Toast.makeText(SendActivity.this, "pushTx:" + mle.getMessage(), Toast.LENGTH_SHORT).show();
                                    } catch (DecoderException de) {
                                        Toast.makeText(SendActivity.this, "pushTx:" + de.getMessage(), Toast.LENGTH_SHORT).show();
                                    } catch (IOException ioe) {
                                        Toast.makeText(SendActivity.this, "pushTx:" + ioe.getMessage(), Toast.LENGTH_SHORT).show();
                                    } finally {
                                        SendActivity.this.runOnUiThread(new Runnable() {

                                            @Override
                                            public void run() {
                                                btSend.setActivated(true);
                                                btSend.setClickable(true);
                                                progress.dismiss();
                                                dialog.dismiss();
                                            }
                                        });
                                    }
                                    Looper.loop();
                                }
                            }).start();
                        } else {
                            // Log.d("SendActivity", "tx error");
                            Toast.makeText(SendActivity.this, "tx error", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
                builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {

                    public void onClick(final DialogInterface dialog, int whichButton) {
                        try {
                            // reset change index upon 'NO'
                            if (isSegwitChange) {
                                BIP49Util.getInstance(SendActivity.this).getWallet().getAccount(0).getChange().setAddrIdx(_change_index);
                            } else {
                                HD_WalletFactory.getInstance(SendActivity.this).get().getAccount(0).getChange().setAddrIdx(_change_index);
                            }
                        } catch (Exception e) {
                            // Log.d("SendActivity", e.getMessage());
                            Toast.makeText(SendActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                        } finally {
                            SendActivity.this.runOnUiThread(new Runnable() {

                                @Override
                                public void run() {
                                    btSend.setActivated(true);
                                    btSend.setClickable(true);
                                    dialog.dismiss();
                                }
                            });
                        }
                    }
                });
                AlertDialog alert = builder.create();
                alert.show();
            }
        }
    });
    Bundle extras = getIntent().getExtras();
    if (extras != null) {
        bViaMenu = extras.getBoolean("via_menu", false);
        String strUri = extras.getString("uri");
        strPCode = extras.getString("pcode");
        if (strUri != null && strUri.length() > 0) {
            processScan(strUri);
        }
        if (strPCode != null && strPCode.length() > 0) {
            processPCode(strPCode, null);
        }
    }
    validateSpend();
}
Also used : AlertDialog(android.app.AlertDialog) PaymentAddress(com.samourai.wallet.bip47.rpc.PaymentAddress) Address(org.bitcoinj.core.Address) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) RicochetActivity(com.samourai.wallet.ricochet.RicochetActivity) ProgressDialog(android.app.ProgressDialog) ArrayList(java.util.ArrayList) List(java.util.List) Script(org.bitcoinj.script.Script) SuggestedFee(com.samourai.wallet.send.SuggestedFee) JSONObject(org.json.JSONObject) Transaction(org.bitcoinj.core.Transaction) CheckBox(android.widget.CheckBox) BigInteger(java.math.BigInteger) TransactionOutput(org.bitcoinj.core.TransactionOutput) DialogInterface(android.content.DialogInterface) DecimalFormat(java.text.DecimalFormat) InputMethodManager(android.view.inputmethod.InputMethodManager) TransactionInput(org.bitcoinj.core.TransactionInput) MnemonicException(org.bitcoinj.crypto.MnemonicException) TextWatcher(android.text.TextWatcher) Editable(android.text.Editable) RBFSpend(com.samourai.wallet.send.RBFSpend) Pair(org.apache.commons.lang3.tuple.Pair) DecimalFormatSymbols(java.text.DecimalFormatSymbols) Bundle(android.os.Bundle) JSONException(org.json.JSONException) Intent(android.content.Intent) IOException(java.io.IOException) ImageView(android.widget.ImageView) View(android.view.View) TextView(android.widget.TextView) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) Point(android.graphics.Point) JSONException(org.json.JSONException) IOException(java.io.IOException) WriterException(com.google.zxing.WriterException) ParseException(java.text.ParseException) DecoderException(org.bouncycastle.util.encoders.DecoderException) FileNotFoundException(java.io.FileNotFoundException) MnemonicException(org.bitcoinj.crypto.MnemonicException) MotionEvent(android.view.MotionEvent) UTXO(com.samourai.wallet.send.UTXO) BlockedUTXO(com.samourai.wallet.send.BlockedUTXO) DecoderException(org.bouncycastle.util.encoders.DecoderException) ParseException(java.text.ParseException) SimpleDateFormat(java.text.SimpleDateFormat) ArrayAdapter(android.widget.ArrayAdapter) CompoundButton(android.widget.CompoundButton) NumberFormat(java.text.NumberFormat)

Example 65 with Address

use of org.bitcoinj.core.Address in project bisq-api by mrosseel.

the class BisqProxy method withdrawFunds.

public void withdrawFunds(Set<String> sourceAddresses, Coin amountAsCoin, boolean feeExcluded, String targetAddress) throws AddressEntryException, InsufficientFundsException, AmountTooLowException {
    // get all address entries
    final List<AddressEntry> sourceAddressEntries = sourceAddresses.stream().filter(address -> null != address).map(address -> btcWalletService.getAddressEntryListAsImmutableList().stream().filter(addressEntry -> address.equals(addressEntry.getAddressString())).findFirst().orElse(null)).filter(item -> null != item).collect(Collectors.toList());
    // this filter matches all unauthorized address types
    Predicate<AddressEntry> filterNotAllowedAddressEntries = addressEntry -> !(AddressEntry.Context.AVAILABLE.equals(addressEntry.getContext()) || AddressEntry.Context.TRADE_PAYOUT.equals(addressEntry.getContext()));
    // check if there are any unauthorized address types
    if (sourceAddressEntries.stream().anyMatch(filterNotAllowedAddressEntries)) {
        throw new ValidationException("Funds can be withdrawn only from addresses with context AVAILABLE and TRADE_PAYOUT");
    }
    Coin sendersAmount;
    // We do not know sendersAmount if senderPaysFee is true. We repeat fee calculation after first attempt if senderPaysFee is true.
    Transaction feeEstimationTransaction;
    try {
        feeEstimationTransaction = btcWalletService.getFeeEstimationTransactionForMultipleAddresses(sourceAddresses, amountAsCoin);
    } catch (IllegalArgumentException e) {
        if (e.getMessage().contains("dust limit")) {
            throw new AmountTooLowException(e.getMessage());
        }
        throw e;
    }
    if (feeExcluded && feeEstimationTransaction != null) {
        sendersAmount = amountAsCoin.add(feeEstimationTransaction.getFee());
        feeEstimationTransaction = btcWalletService.getFeeEstimationTransactionForMultipleAddresses(sourceAddresses, sendersAmount);
    }
    checkNotNull(feeEstimationTransaction, "feeEstimationTransaction must not be null");
    Coin fee = feeEstimationTransaction.getFee();
    sendersAmount = feeExcluded ? amountAsCoin.add(fee) : amountAsCoin;
    Coin receiverAmount = feeExcluded ? amountAsCoin : amountAsCoin.subtract(fee);
    final Coin totalAvailableAmountOfSelectedItems = sourceAddressEntries.stream().map(address -> btcWalletService.getBalanceForAddress(address.getAddress())).reduce(Coin.ZERO, Coin::add);
    if (!sendersAmount.isPositive())
        throw new ValidationException("Senders amount must be positive");
    if (!new BtcAddressValidator().validate(targetAddress).isValid)
        throw new ValidationException("Invalid target address");
    if (sourceAddresses.isEmpty())
        throw new ValidationException("List of source addresses must not be empty");
    if (sendersAmount.compareTo(totalAvailableAmountOfSelectedItems) > 0)
        throw new InsufficientFundsException("Not enough funds in selected addresses");
    if (receiverAmount.isPositive()) {
        try {
            // TODO return completable future
            btcWalletService.sendFundsForMultipleAddresses(sourceAddresses, targetAddress, amountAsCoin, fee, null, null, new FutureCallback<Transaction>() {

                @Override
                public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
                    if (transaction != null) {
                        log.debug("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
                    } else {
                        log.error("onWithdraw transaction is null");
                    }
                    List<Trade> trades = new ArrayList<>(tradeManager.getTradableList());
                    trades.stream().filter(Trade::isPayoutPublished).forEach(trade -> btcWalletService.getAddressEntry(trade.getId(), AddressEntry.Context.TRADE_PAYOUT).ifPresent(addressEntry -> {
                        if (btcWalletService.getBalanceForAddress(addressEntry.getAddress()).isZero())
                            tradeManager.addTradeToClosedTrades(trade);
                    }));
                }

                @Override
                public void onFailure(@NotNull Throwable t) {
                    log.error("onWithdraw onFailure");
                }
            });
        } catch (org.bitcoinj.core.InsufficientMoneyException e) {
            throw new InsufficientFundsException(e.getMessage());
        }
    } else {
        throw new AmountTooLowException(Res.get("portfolio.pending.step5_buyer.amountTooLow"));
    }
}
Also used : Arrays(java.util.Arrays) OpenOffer(bisq.core.offer.OpenOffer) User(bisq.core.user.User) PriceFeed(network.bisq.api.model.PriceFeed) Statistic(bisq.network.p2p.network.Statistic) ZoneOffset(java.time.ZoneOffset) KeyParameter(org.spongycastle.crypto.params.KeyParameter) ClosedTradableDetails(network.bisq.api.model.ClosedTradableDetails) CurrencyList(network.bisq.api.model.CurrencyList) WalletAddress(network.bisq.api.model.WalletAddress) AddressEntryException(bisq.core.btc.AddressEntryException) Offer(bisq.core.offer.Offer) ClosedTradableManager(bisq.core.trade.closed.ClosedTradableManager) SellerAsMakerProtocol(bisq.core.trade.protocol.SellerAsMakerProtocol) WalletTransactionList(network.bisq.api.model.WalletTransactionList) InsufficientFundsException(bisq.core.btc.InsufficientFundsException) Set(java.util.Set) TokenRegistry(network.bisq.api.service.TokenRegistry) BlockChainExplorer(bisq.core.user.BlockChainExplorer) TradeProtocol(bisq.core.trade.protocol.TradeProtocol) ZoneId(java.time.ZoneId) ECKey(org.bitcoinj.core.ECKey) Slf4j(lombok.extern.slf4j.Slf4j) Stream(java.util.stream.Stream) AddressEntry(bisq.core.btc.AddressEntry) WalletsSetup(bisq.core.btc.wallet.WalletsSetup) CryptoCurrency(bisq.core.locale.CryptoCurrency) Currency(network.bisq.api.model.Currency) TradeManager(bisq.core.trade.TradeManager) NodeAddress(bisq.network.p2p.NodeAddress) SellerAsTakerProtocol(bisq.core.trade.protocol.SellerAsTakerProtocol) CountryUtil(bisq.core.locale.CountryUtil) BuyerAsTakerProtocol(bisq.core.trade.protocol.BuyerAsTakerProtocol) TransactionOutput(org.bitcoinj.core.TransactionOutput) FeeService(bisq.core.provider.fee.FeeService) ObservableList(javafx.collections.ObservableList) PaymentAccountHelper(network.bisq.api.model.payment.PaymentAccountHelper) Restrictions(bisq.core.btc.Restrictions) Arbitrator(bisq.core.arbitration.Arbitrator) TransactionConfidence(org.bitcoinj.core.TransactionConfidence) Wallet(org.bitcoinj.wallet.Wallet) Peer(org.bitcoinj.core.Peer) ArrayList(java.util.ArrayList) ClosedTradableConverter(network.bisq.api.model.ClosedTradableConverter) OfferPayload(bisq.core.offer.OfferPayload) Country(bisq.core.locale.Country) BitcoinNetworkStatus(network.bisq.api.model.BitcoinNetworkStatus) WalletDetails(network.bisq.api.model.WalletDetails) Nullable(javax.annotation.Nullable) IOException(java.io.IOException) OfferBookService(bisq.core.offer.OfferBookService) Names(com.google.inject.name.Names) BisqEnvironment(bisq.core.app.BisqEnvironment) SeedWords(network.bisq.api.model.SeedWords) FutureCallback(com.google.common.util.concurrent.FutureCallback) File(java.io.File) OpenOfferManager(bisq.core.offer.OpenOfferManager) InputValidator(bisq.core.util.validation.InputValidator) PriceFeedService(bisq.core.provider.price.PriceFeedService) PaymentAccountList(network.bisq.api.model.PaymentAccountList) KeyRing(bisq.common.crypto.KeyRing) PreferencesAvailableValues(network.bisq.api.model.PreferencesAvailableValues) Transaction(org.bitcoinj.core.Transaction) Preferences(network.bisq.api.model.Preferences) Date(java.util.Date) Coin(org.bitcoinj.core.Coin) Key(com.google.inject.Key) AltCoinAddressValidator(bisq.core.payment.validation.AltCoinAddressValidator) VersionDetails(network.bisq.api.model.VersionDetails) Res(bisq.core.locale.Res) ErrorMessageHandler(bisq.common.handlers.ErrorMessageHandler) KeyCrypterScrypt(org.bitcoinj.crypto.KeyCrypterScrypt) PaymentAccountUtil.isPaymentAccountValidForOffer(bisq.core.payment.PaymentAccountUtil.isPaymentAccountValidForOffer) OfferUtil(bisq.core.offer.OfferUtil) P2PService(bisq.network.p2p.P2PService) Predicate(java.util.function.Predicate) ArbitratorManager(bisq.core.arbitration.ArbitratorManager) Collection(java.util.Collection) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) FileNotFoundException(java.io.FileNotFoundException) BsqWalletService(bisq.core.btc.wallet.BsqWalletService) AccountAgeWitnessService(bisq.core.payment.AccountAgeWitnessService) FileUtil(bisq.common.storage.FileUtil) List(java.util.List) PaymentAccount(bisq.core.payment.PaymentAccount) DeterministicSeed(org.bitcoinj.wallet.DeterministicSeed) DevEnv(bisq.common.app.DevEnv) MarketList(network.bisq.api.model.MarketList) AppOptionKeys(bisq.core.app.AppOptionKeys) LocalDate(java.time.LocalDate) Optional(java.util.Optional) Address(org.bitcoinj.core.Address) NotNull(org.jetbrains.annotations.NotNull) MarketPrice(bisq.core.provider.price.MarketPrice) BtcWalletService(bisq.core.btc.wallet.BtcWalletService) TradeCurrency(bisq.core.locale.TradeCurrency) SellerAsMakerTrade(bisq.core.trade.SellerAsMakerTrade) Getter(lombok.Getter) WalletService(bisq.core.btc.wallet.WalletService) CompletableFuture(java.util.concurrent.CompletableFuture) FiatCurrency(bisq.core.locale.FiatCurrency) WalletsManager(bisq.core.btc.wallet.WalletsManager) Tuple2(bisq.common.util.Tuple2) BuyerAsMakerProtocol(bisq.core.trade.protocol.BuyerAsMakerProtocol) P2PNetworkStatus(network.bisq.api.model.P2PNetworkStatus) Market(network.bisq.api.model.Market) CurrencyUtil(bisq.core.locale.CurrencyUtil) BitcoinNodes(bisq.core.btc.BitcoinNodes) Version(bisq.common.app.Version) CryptoCurrencyAccount(bisq.core.payment.CryptoCurrencyAccount) P2PNetworkConnection(network.bisq.api.model.P2PNetworkConnection) BuyerAsMakerTrade(bisq.core.trade.BuyerAsMakerTrade) Trade(bisq.core.trade.Trade) WalletAddressList(network.bisq.api.model.WalletAddressList) ResultHandler(bisq.common.handlers.ResultHandler) FailedTradesManager(bisq.core.trade.failed.FailedTradesManager) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) FileInputStream(java.io.FileInputStream) WalletTransaction(network.bisq.api.model.WalletTransaction) Injector(com.google.inject.Injector) Collectors.toList(java.util.stream.Collectors.toList) AuthResult(network.bisq.api.model.AuthResult) ValidationException(javax.validation.ValidationException) Storage(bisq.common.storage.Storage) Comparator(java.util.Comparator) Collections(java.util.Collections) CoinUtil(bisq.core.util.CoinUtil) InputStream(java.io.InputStream) ValidationException(javax.validation.ValidationException) AddressEntry(bisq.core.btc.AddressEntry) Coin(org.bitcoinj.core.Coin) SellerAsMakerTrade(bisq.core.trade.SellerAsMakerTrade) BuyerAsMakerTrade(bisq.core.trade.BuyerAsMakerTrade) Trade(bisq.core.trade.Trade) Transaction(org.bitcoinj.core.Transaction) WalletTransaction(network.bisq.api.model.WalletTransaction) InsufficientFundsException(bisq.core.btc.InsufficientFundsException) CurrencyList(network.bisq.api.model.CurrencyList) WalletTransactionList(network.bisq.api.model.WalletTransactionList) ObservableList(javafx.collections.ObservableList) ArrayList(java.util.ArrayList) PaymentAccountList(network.bisq.api.model.PaymentAccountList) List(java.util.List) MarketList(network.bisq.api.model.MarketList) WalletAddressList(network.bisq.api.model.WalletAddressList) Collectors.toList(java.util.stream.Collectors.toList)

Aggregations

Address (org.bitcoinj.core.Address)78 Transaction (org.bitcoinj.core.Transaction)32 Coin (org.bitcoinj.core.Coin)28 TransactionOutput (org.bitcoinj.core.TransactionOutput)15 TransactionInput (org.bitcoinj.core.TransactionInput)13 ArrayList (java.util.ArrayList)12 AddressEntry (bisq.core.btc.AddressEntry)11 Wallet (org.bitcoinj.wallet.Wallet)11 BtcWalletService (bisq.core.btc.wallet.BtcWalletService)10 AddressFormatException (org.bitcoinj.core.AddressFormatException)10 TransactionConfidence (org.bitcoinj.core.TransactionConfidence)10 IOException (java.io.IOException)9 SendRequest (org.bitcoinj.wallet.SendRequest)9 WalletService (io.bitsquare.btc.WalletService)8 List (java.util.List)8 Collectors (java.util.stream.Collectors)8 Nullable (javax.annotation.Nullable)8 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)8 Script (org.bitcoinj.script.Script)8 Intent (android.content.Intent)7