Search in sources :

Example 1 with org.apache.commons.lang3

use of org.apache.commons.lang3 in project selenium_java by sergueik.

the class SuvianTest method test10.

@Test(enabled = true)
public void test10() {
    // Arrange
    driver.get("http://suvian.in/selenium/1.10selectElementFromDD.html");
    WebElement buttonDropDown = wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.cssSelector(".container .row .intro-message div.dropdown button.dropbtn"))));
    assertThat(buttonDropDown, notNullValue());
    // Act
    buttonDropDown.click();
    wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.cssSelector(".container .row .intro-message div.dropdown div#myDropdown"))));
    List<WebElement> optionElements = driver.findElements(By.cssSelector(".container .row .intro-message div.dropdown div#myDropdown")).stream().filter(o -> o.getText().contains("Option 2")).collect(Collectors.toList());
    assertTrue(optionElements.size() > 0);
    final String currentHandle = driver.getWindowHandle();
    final String text = "Congratulations.. You Selected option 2. Close this browser tab and proceed to end of Level 1.";
    optionElements.get(0).click();
    // Assert
    try {
        wait.until(new ExpectedCondition<Boolean>() {

            @Override
            public Boolean apply(WebDriver d) {
                Boolean result = false;
                System.err.println("Inspecting driver Window handles");
                Set<String> windowHandles = d.getWindowHandles();
                if (windowHandles.size() > 1) {
                    System.err.println("Found " + (windowHandles.size() - 1) + " additional tabs opened");
                } else {
                    System.out.println("No other tabs found");
                    return false;
                }
                // String handle = windowHandleIterator.next();
                for (String handle : windowHandles) {
                    if (!handle.equals(currentHandle)) {
                        System.err.println("Switch to: " + handle);
                        driver.switchTo().window(handle);
                        String t = d.getPageSource();
                        System.err.println(String.format("Page source: %s", t.substring(org.apache.commons.lang3.StringUtils.indexOf(t, "<body>"), t.length() - 1)));
                        if (t.contains(text)) {
                            System.err.println("Found text: " + text);
                            result = true;
                        }
                        if (result) {
                            System.err.println("Close the browser tab: " + handle);
                            d.close();
                        }
                        System.err.println("Switch to the main window.");
                        driver.switchTo().window(currentHandle);
                        driver.switchTo().defaultContent();
                    }
                }
                return result;
            }
        });
    } catch (Exception e) {
        System.err.println("Exception: " + e.toString());
        verificationErrors.append(e.toString());
    // throw new RuntimeException(e.toString());
    }
}
Also used : CoreMatchers.is(org.hamcrest.CoreMatchers.is) Arrays(java.util.Arrays) Enumeration(java.util.Enumeration) WebElement(org.openqa.selenium.WebElement) Test(org.testng.annotations.Test) AfterMethod(org.testng.annotations.AfterMethod) StringUtils(org.apache.commons.lang3.StringUtils) Locatable(org.openqa.selenium.internal.Locatable) Coordinates(org.openqa.selenium.interactions.internal.Coordinates) CoreMatchers.notNullValue(org.hamcrest.CoreMatchers.notNullValue) JavascriptExecutor(org.openqa.selenium.JavascriptExecutor) Matcher(java.util.regex.Matcher) Point(org.openqa.selenium.Point) Map(java.util.Map) Method(java.lang.reflect.Method) HasInputDevices(org.openqa.selenium.interactions.HasInputDevices) FindBy(org.openqa.selenium.support.FindBy) SoftAssert(org.testng.asserts.SoftAssert) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) ExpectedConditions(org.openqa.selenium.support.ui.ExpectedConditions) Predicate(java.util.function.Predicate) BeforeMethod(org.testng.annotations.BeforeMethod) Set(java.util.Set) Mouse(org.openqa.selenium.interactions.Mouse) Collectors(java.util.stream.Collectors) FindBys(org.openqa.selenium.support.FindBys) List(java.util.List) Stream(java.util.stream.Stream) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) WebDriverWait(org.openqa.selenium.support.ui.WebDriverWait) CoreMatchers.equalTo(org.hamcrest.CoreMatchers.equalTo) UnreachableBrowserException(org.openqa.selenium.remote.UnreachableBrowserException) WebDriver(org.openqa.selenium.WebDriver) WebDriverException(org.openqa.selenium.WebDriverException) ExpectedCondition(org.openqa.selenium.support.ui.ExpectedCondition) InvalidSelectorException(org.openqa.selenium.InvalidSelectorException) ITestResult(org.testng.ITestResult) ArrayList(java.util.ArrayList) Select(org.openqa.selenium.support.ui.Select) NoAlertPresentException(org.openqa.selenium.NoAlertPresentException) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) LinkedList(java.util.LinkedList) CoreMatchers.nullValue(org.hamcrest.CoreMatchers.nullValue) ByChained(org.openqa.selenium.support.pagefactory.ByChained) Iterator(java.util.Iterator) Keys(org.openqa.selenium.Keys) By(org.openqa.selenium.By) Consumer(java.util.function.Consumer) Assert.assertTrue(org.testng.Assert.assertTrue) Comparator(java.util.Comparator) Collections(java.util.Collections) WebDriver(org.openqa.selenium.WebDriver) Set(java.util.Set) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) WebElement(org.openqa.selenium.WebElement) UnreachableBrowserException(org.openqa.selenium.remote.UnreachableBrowserException) WebDriverException(org.openqa.selenium.WebDriverException) InvalidSelectorException(org.openqa.selenium.InvalidSelectorException) NoAlertPresentException(org.openqa.selenium.NoAlertPresentException) Test(org.testng.annotations.Test)

Example 2 with org.apache.commons.lang3

use of org.apache.commons.lang3 in project mule by mulesoft.

the class SerializationUtils method deserialize.

/**
 * <p>
 * Deserializes an <code>Object</code> from the specified stream.
 * </p>
 * <p/>
 * <p>
 * The stream will be closed once the object is written. This avoids the need for a finally clause, and maybe also exception
 * handling, in the application code.
 * </p>
 * <p/>
 * <p>
 * The stream passed in is not buffered internally within this method. This is the responsibility of your application if
 * desired.
 * </p>
 *
 * @param inputStream the serialized object input stream, must not be null
 * @param cl classloader which can load custom classes from the stream
 * @return the deserialized object
 * @throws IllegalArgumentException if <code>inputStream</code> is <code>null</code>
 * @throws org.apache.commons.lang3.SerializationException (runtime) if the serialization fails
 */
public static Object deserialize(InputStream inputStream, ClassLoader cl, MuleContext muleContext) {
    if (inputStream == null) {
        throw new IllegalArgumentException("The InputStream must not be null");
    }
    if (cl == null) {
        throw new IllegalArgumentException("The ClassLoader must not be null");
    }
    ObjectInputStream in = null;
    try {
        // stream closed in the finally
        in = new ClassLoaderObjectInputStream(cl, inputStream);
        Object obj = in.readObject();
        if (obj instanceof DeserializationPostInitialisable) {
            DeserializationPostInitialisable.Implementation.init(obj, muleContext);
        }
        return obj;
    } catch (ClassNotFoundException ex) {
        throw new SerializationException(ex);
    } catch (IOException ex) {
        throw new SerializationException(ex);
    } catch (Exception ex) {
        throw new SerializationException(ex);
    } finally {
        try {
            if (in != null) {
                in.close();
            }
        } catch (IOException ex) {
        // ignore close exception
        }
    }
}
Also used : SerializationException(org.apache.commons.lang3.SerializationException) DeserializationPostInitialisable(org.mule.runtime.core.privileged.store.DeserializationPostInitialisable) ClassLoaderObjectInputStream(org.apache.commons.io.input.ClassLoaderObjectInputStream) IOException(java.io.IOException) SerializationException(org.apache.commons.lang3.SerializationException) IOException(java.io.IOException) ObjectInputStream(java.io.ObjectInputStream) ClassLoaderObjectInputStream(org.apache.commons.io.input.ClassLoaderObjectInputStream)

Example 3 with org.apache.commons.lang3

use of org.apache.commons.lang3 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 4 with org.apache.commons.lang3

use of org.apache.commons.lang3 in project flink by apache.

the class EmulatedFullTopologyTest method testFullTopology.

// ======================================================================================================
// IMPORTANT: This test makes use of things that happen in the emulated PubSub that
// are GUARANTEED to be different in the real Google hosted PubSub.
// So running these tests against the real thing will have a very high probability of
// failing.
// The assumptions:
// 1) The ordering of the messages is maintained.
// We are inserting a STOP_MARKER _after_ the set of test measurements and we assume this
// STOP event will
// arrive after the actual test data so we can stop the processing. In the real PubSub this
// is NOT true.
// 2) Exactly once: We assume that every message we put in comes out exactly once.
// In the real PubSub there are a lot of situations (mostly failure/retry) where this is not
// true.
@Test
public void testFullTopology() throws Exception {
    // ===============================================================================
    // Step 0: The test data
    List<String> input = new ArrayList<>(Arrays.asList("One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"));
    List<String> messagesToSend = new ArrayList<>(input);
    // Now add some stream termination messages.
    // NOTE: Messages are pulled from PubSub in batches by the source.
    // So we need enough STOP_MARKERs to ensure ALL parallel tasks get at least one
    // STOP_MARKER
    // If not then at least one task will not terminate and the test will not end.
    // We pull 3 at a time, have 4 parallel: We need at least 12 STOP_MARKERS
    IntStream.rangeClosed(1, 20).forEach(i -> messagesToSend.add(STOP_MARKER));
    // IMPORTANT NOTE: This way of testing uses an effect of the PubSub emulator that is
    // absolutely
    // guaranteed NOT to work in the real PubSub: The ordering of the messages is maintained in
    // the topic.
    // So here we can assume that if we add a stop message LAST we can terminate the test stream
    // when we see it.
    // ===============================================================================
    // Step 1: We put test data into the topic
    // Publish the test messages into the input topic
    Publisher publisher = pubsubHelper.createPublisher(PROJECT_NAME, INPUT_TOPIC_NAME);
    for (String s : messagesToSend) {
        publisher.publish(PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8(s)).build()).get();
    }
    publisher.shutdown();
    // ===============================================================================
    // Step 2: Now we run our topology
    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    env.enableCheckpointing(100);
    env.setParallelism(4);
    env.setRestartStrategy(RestartStrategies.noRestart());
    // Silly topology
    env.addSource(// a self termination feature.
    PubSubSource.newBuilder().withDeserializationSchema(new SimpleStringSchemaWithStopMarkerDetection()).withProjectName(PROJECT_NAME).withSubscriptionName(INPUT_SUBSCRIPTION_NAME).withCredentials(EmulatorCredentials.getInstance()).withPubSubSubscriberFactory(new PubSubSubscriberFactoryForEmulator(getPubSubHostPort(), PROJECT_NAME, INPUT_SUBSCRIPTION_NAME, 1, Duration.ofSeconds(1), 3)).build()).map((MapFunction<String, String>) StringUtils::reverse).addSink(PubSubSink.newBuilder().withSerializationSchema(new SimpleStringSchema()).withProjectName(PROJECT_NAME).withTopicName(OUTPUT_TOPIC_NAME).withCredentials(EmulatorCredentials.getInstance()).withHostAndPortForEmulator(getPubSubHostPort()).build());
    env.execute("Running unit test");
    // ===============================================================================
    // Now we should have all the resulting data in the output topic.
    // Step 3: Get the result from the output topic and verify if everything is there
    List<ReceivedMessage> receivedMessages = pubsubHelper.pullMessages(PROJECT_NAME, OUTPUT_SUBSCRIPTION_NAME, 100);
    assertEquals("Wrong number of elements", input.size(), receivedMessages.size());
    // Check output strings
    List<String> output = new ArrayList<>();
    // Extract the actual Strings from the ReceivedMessages
    receivedMessages.forEach(msg -> output.add(msg.getMessage().getData().toStringUtf8()));
    for (String test : input) {
        String reversedTest = org.apache.commons.lang3.StringUtils.reverse(test);
        LOG.info("Checking if \"{}\" --> \"{}\" exists", test, reversedTest);
        assertTrue("Missing " + test, output.contains(reversedTest));
    }
// ===============================================================================
}
Also used : StringUtils(org.apache.commons.lang3.StringUtils) PubSubSubscriberFactoryForEmulator(org.apache.flink.streaming.connectors.gcp.pubsub.emulator.PubSubSubscriberFactoryForEmulator) ArrayList(java.util.ArrayList) SimpleStringSchema(org.apache.flink.api.common.serialization.SimpleStringSchema) StreamExecutionEnvironment(org.apache.flink.streaming.api.environment.StreamExecutionEnvironment) ByteString(com.google.protobuf.ByteString) Publisher(com.google.cloud.pubsub.v1.Publisher) MapFunction(org.apache.flink.api.common.functions.MapFunction) ReceivedMessage(com.google.pubsub.v1.ReceivedMessage) Test(org.junit.Test)

Example 5 with org.apache.commons.lang3

use of org.apache.commons.lang3 in project samourai-wallet-android by Samourai-Wallet.

the class SendActivity method prepareSpend.

private boolean prepareSpend() {
    restoreChangeIndexes();
    double btc_amount = 0.0;
    try {
        btc_amount = NumberFormat.getInstance(Locale.US).parse(btcEditText.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;
    amount = (long) (Math.round(dAmount * 1e8));
    if (selectedCahootsType == SelectCahootsType.type.STOWAWAY) {
        setButtonForStowaway(true);
        return true;
    } else {
        setButtonForStowaway(false);
    }
    address = strDestinationBTCAddress == null ? toAddressEditText.getText().toString().trim() : strDestinationBTCAddress;
    if (account == WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()) {
        changeType = 84;
    } else if (PrefsUtil.getInstance(SendActivity.this).getValue(PrefsUtil.USE_LIKE_TYPED_CHANGE, true) == false) {
        changeType = 84;
    } else if (FormatsUtil.getInstance().isValidBech32(address) || Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
        changeType = FormatsUtil.getInstance().isValidBech32(address) ? 84 : 49;
    } else {
        changeType = 44;
    }
    receivers = new HashMap<String, BigInteger>();
    receivers.put(address, BigInteger.valueOf(amount));
    if (account == WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()) {
        change_index = idxBIP84PostMixInternal;
    } else if (changeType == 84) {
        change_index = idxBIP84Internal;
    } else if (changeType == 49) {
        change_index = idxBIP49Internal;
    } else {
        change_index = idxBIP44Internal;
    }
    // if possible, get UTXO by input 'type': p2pkh, p2sh-p2wpkh or p2wpkh, else get all UTXO
    long neededAmount = 0L;
    if (FormatsUtil.getInstance().isValidBech32(address) || account == WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()) {
        neededAmount += FeeUtil.getInstance().estimatedFeeSegwit(0, 0, UTXOFactory.getInstance().getCountP2WPKH(), 4).longValue();
    // Log.d("SendActivity", "segwit:" + neededAmount);
    } else if (Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
        neededAmount += FeeUtil.getInstance().estimatedFeeSegwit(0, UTXOFactory.getInstance().getCountP2SH_P2WPKH(), 0, 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();
    // get all UTXO
    List<UTXO> utxos = new ArrayList<>();
    if (preselectedUTXOs != null && preselectedUTXOs.size() > 0) {
        // sort in descending order by value
        for (UTXOCoin utxoCoin : preselectedUTXOs) {
            UTXO u = new UTXO();
            List<MyTransactionOutPoint> outs = new ArrayList<MyTransactionOutPoint>();
            outs.add(utxoCoin.getOutPoint());
            u.setOutpoints(outs);
            utxos.add(u);
        }
    } else {
        utxos = SpendUtil.getUTXOS(SendActivity.this, address, neededAmount, account);
    }
    List<UTXO> utxosP2WPKH = new ArrayList<UTXO>(UTXOFactory.getInstance().getAllP2WPKH().values());
    List<UTXO> utxosP2SH_P2WPKH = new ArrayList<UTXO>(UTXOFactory.getInstance().getAllP2SH_P2WPKH().values());
    List<UTXO> utxosP2PKH = new ArrayList<UTXO>(UTXOFactory.getInstance().getAllP2PKH().values());
    if ((preselectedUTXOs == null || preselectedUTXOs.size() == 0) && account == WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()) {
        utxos = new ArrayList<UTXO>(UTXOFactory.getInstance().getAllPostMix().values());
        utxosP2WPKH = new ArrayList<UTXO>(UTXOFactory.getInstance().getAllPostMix().values());
        utxosP2PKH.clear();
        utxosP2SH_P2WPKH.clear();
    }
    selectedUTXO = new ArrayList<UTXO>();
    long totalValueSelected = 0L;
    long change = 0L;
    BigInteger fee = null;
    boolean canDoBoltzmann = true;
    // insufficient funds
    if (amount > balance) {
        Toast.makeText(SendActivity.this, R.string.insufficient_funds, Toast.LENGTH_SHORT).show();
    }
    if (preselectedUTXOs != null) {
        canDoBoltzmann = false;
        SPEND_TYPE = SPEND_SIMPLE;
    } else // entire balance (can only be simple spend)
    if (amount == balance) {
        // make sure we are using simple spend
        SPEND_TYPE = SPEND_SIMPLE;
        canDoBoltzmann = false;
        // 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;
        }
        ricochetJsonObj = RicochetMeta.getInstance(SendActivity.this).script(amount, FeeUtil.getInstance().getSuggestedFee().getDefaultPerKB().longValue(), address, 4, strPCode, samouraiFeeViaBIP47, ricochetStaggeredDelivery.isChecked());
        if (ricochetJsonObj != null) {
            try {
                long totalAmount = ricochetJsonObj.getLong("total_spend");
                if (totalAmount > balance) {
                    Toast.makeText(SendActivity.this, R.string.insufficient_funds, Toast.LENGTH_SHORT).show();
                    ricochetHopsSwitch.setChecked(false);
                    return false;
                }
                long hop0Fee = ricochetJsonObj.getJSONArray("hops").getJSONObject(0).getLong("fee");
                long perHopFee = ricochetJsonObj.getJSONArray("hops").getJSONObject(0).getLong("fee_per_hop");
                long ricochetFee = hop0Fee + (RicochetMeta.defaultNbHops * perHopFee);
                if (selectedCahootsType == SelectCahootsType.type.NONE) {
                    tvTotalFee.setText(Coin.valueOf(ricochetFee).toPlainString().concat(" BTC"));
                } else {
                    tvTotalFee.setText("__");
                }
                ricochetMessage = getText(R.string.ricochet_spend1) + " " + address + " " + getText(R.string.ricochet_spend2) + " " + Coin.valueOf(totalAmount).toPlainString() + " " + getText(R.string.ricochet_spend3);
                btnSend.setText("send ".concat(String.format(Locale.ENGLISH, "%.8f", getBtcValue((double) totalAmount)).concat(" BTC")));
                return true;
            } catch (JSONException je) {
                return false;
            }
        }
        return true;
    } else if (SPEND_TYPE == SPEND_BOLTZMANN) {
        Log.d("SendActivity", "needed amount:" + neededAmount);
        List<UTXO> _utxos1 = null;
        List<UTXO> _utxos2 = null;
        long valueP2WPKH = UTXOFactory.getInstance().getTotalP2WPKH();
        long valueP2SH_P2WPKH = UTXOFactory.getInstance().getTotalP2SH_P2WPKH();
        long valueP2PKH = UTXOFactory.getInstance().getTotalP2PKH();
        if (account == WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()) {
            valueP2WPKH = UTXOFactory.getInstance().getTotalPostMix();
            valueP2SH_P2WPKH = 0L;
            valueP2PKH = 0L;
            utxosP2SH_P2WPKH.clear();
            utxosP2PKH.clear();
        }
        Log.d("SendActivity", "value P2WPKH:" + valueP2WPKH);
        Log.d("SendActivity", "value P2SH_P2WPKH:" + valueP2SH_P2WPKH);
        Log.d("SendActivity", "value P2PKH:" + valueP2PKH);
        boolean selectedP2WPKH = false;
        boolean selectedP2SH_P2WPKH = false;
        boolean selectedP2PKH = false;
        if ((valueP2WPKH > (neededAmount * 2)) && account == WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()) {
            Log.d("SendActivity", "set 1 P2WPKH 2x");
            _utxos1 = utxosP2WPKH;
            selectedP2WPKH = true;
        } else if ((valueP2WPKH > (neededAmount * 2)) && FormatsUtil.getInstance().isValidBech32(address)) {
            Log.d("SendActivity", "set 1 P2WPKH 2x");
            _utxos1 = utxosP2WPKH;
            selectedP2WPKH = true;
        } else if (!FormatsUtil.getInstance().isValidBech32(address) && (valueP2SH_P2WPKH > (neededAmount * 2)) && Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
            Log.d("SendActivity", "set 1 P2SH_P2WPKH 2x");
            _utxos1 = utxosP2SH_P2WPKH;
            selectedP2SH_P2WPKH = true;
        } else if (!FormatsUtil.getInstance().isValidBech32(address) && (valueP2PKH > (neededAmount * 2)) && !Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
            Log.d("SendActivity", "set 1 P2PKH 2x");
            _utxos1 = utxosP2PKH;
            selectedP2PKH = true;
        } else if (valueP2WPKH > (neededAmount * 2)) {
            Log.d("SendActivity", "set 1 P2WPKH 2x");
            _utxos1 = utxosP2WPKH;
            selectedP2WPKH = true;
        } else if (valueP2SH_P2WPKH > (neededAmount * 2)) {
            Log.d("SendActivity", "set 1 P2SH_P2WPKH 2x");
            _utxos1 = utxosP2SH_P2WPKH;
            selectedP2SH_P2WPKH = true;
        } else if (valueP2PKH > (neededAmount * 2)) {
            Log.d("SendActivity", "set 1 P2PKH 2x");
            _utxos1 = utxosP2PKH;
            selectedP2PKH = true;
        } else {
            ;
        }
        if (_utxos1 == null || _utxos1.size() == 0) {
            if (valueP2SH_P2WPKH > neededAmount) {
                Log.d("SendActivity", "set 1 P2SH_P2WPKH");
                _utxos1 = utxosP2SH_P2WPKH;
                selectedP2SH_P2WPKH = true;
            } else if (valueP2WPKH > neededAmount) {
                Log.d("SendActivity", "set 1 P2WPKH");
                _utxos1 = utxosP2WPKH;
                selectedP2WPKH = true;
            } else if (valueP2PKH > neededAmount) {
                Log.d("SendActivity", "set 1 P2PKH");
                _utxos1 = utxosP2PKH;
                selectedP2PKH = true;
            } else {
                ;
            }
        }
        if (_utxos1 != null && _utxos1.size() > 0) {
            if (!selectedP2SH_P2WPKH && valueP2SH_P2WPKH > neededAmount) {
                Log.d("SendActivity", "set 2 P2SH_P2WPKH");
                _utxos2 = utxosP2SH_P2WPKH;
                selectedP2SH_P2WPKH = true;
            }
            if (!selectedP2SH_P2WPKH && !selectedP2WPKH && valueP2WPKH > neededAmount) {
                Log.d("SendActivity", "set 2 P2WPKH");
                _utxos2 = utxosP2WPKH;
                selectedP2WPKH = true;
            }
            if (!selectedP2SH_P2WPKH && !selectedP2WPKH && !selectedP2PKH && valueP2PKH > neededAmount) {
                Log.d("SendActivity", "set 2 P2PKH");
                _utxos2 = utxosP2PKH;
                selectedP2PKH = true;
            } else {
                ;
            }
        }
        if ((_utxos1 == null || _utxos1.size() == 0) && (_utxos2 == null || _utxos2.size() == 0)) {
            // can't do boltzmann, revert to SPEND_SIMPLE
            canDoBoltzmann = false;
            SPEND_TYPE = SPEND_SIMPLE;
        } else {
            Log.d("SendActivity", "boltzmann spend");
            Collections.shuffle(_utxos1);
            if (_utxos2 != null && _utxos2.size() > 0) {
                Collections.shuffle(_utxos2);
            }
            // boltzmann spend (STONEWALL)
            pair = SendFactory.getInstance(SendActivity.this).boltzmann(_utxos1, _utxos2, BigInteger.valueOf(amount), address, account);
            if (pair == null) {
                // can't do boltzmann, revert to SPEND_SIMPLE
                canDoBoltzmann = false;
                restoreChangeIndexes();
                SPEND_TYPE = SPEND_SIMPLE;
            } else {
                canDoBoltzmann = true;
            }
        }
    } else {
        ;
    }
    if (SPEND_TYPE == SPEND_SIMPLE && amount == balance && preselectedUTXOs == null) {
        // do nothing, utxo selection handles above
        ;
    } 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) {
            Triple<Integer, Integer, Integer> outpointTypes = FeeUtil.getInstance().getOutpointCount(new Vector(u.getOutpoints()));
            if (u.getValue() >= (amount + SamouraiWallet.bDust.longValue() + FeeUtil.getInstance().estimatedFeeSegwit(outpointTypes.getLeft(), outpointTypes.getMiddle(), outpointTypes.getRight(), 2).longValue())) {
                selectedUTXO.add(u);
                totalValueSelected += u.getValue();
                Log.d("SendActivity", "spend type:" + SPEND_TYPE);
                Log.d("SendActivity", "single output");
                Log.d("SendActivity", "amount:" + amount);
                Log.d("SendActivity", "value selected:" + u.getValue());
                Log.d("SendActivity", "total value selected:" + totalValueSelected);
                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 p2sh_p2wpkh = 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()));
                Triple<Integer, Integer, Integer> outpointTypes = FeeUtil.getInstance().getOutpointCount(new Vector<MyTransactionOutPoint>(u.getOutpoints()));
                p2pkh += outpointTypes.getLeft();
                p2sh_p2wpkh += outpointTypes.getMiddle();
                p2wpkh += outpointTypes.getRight();
                if (totalValueSelected >= (amount + SamouraiWallet.bDust.longValue() + FeeUtil.getInstance().estimatedFeeSegwit(p2pkh, p2sh_p2wpkh, p2wpkh, 2).longValue())) {
                    Log.d("SendActivity", "spend type:" + SPEND_TYPE);
                    Log.d("SendActivity", "multiple outputs");
                    Log.d("SendActivity", "amount:" + amount);
                    Log.d("SendActivity", "total value selected:" + totalValueSelected);
                    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());
                if (Bech32Util.getInstance().isP2WPKHScript(Hex.toHexString(output.getScriptBytes()))) {
                    receivers.put(Bech32Util.getInstance().getAddressFromScript(script), BigInteger.valueOf(output.getValue().longValue()));
                } else {
                    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 false;
            }
        }
        fee = BigInteger.valueOf(inputAmount - outputAmount);
    } else {
        Toast.makeText(SendActivity.this, R.string.cannot_select_utxo, Toast.LENGTH_SHORT).show();
        return false;
    }
    // do spend here
    if (selectedUTXO.size() > 0) {
        // estimate fee for simple spend, already done if boltzmann
        if (SPEND_TYPE == SPEND_SIMPLE) {
            List<MyTransactionOutPoint> outpoints = new ArrayList<MyTransactionOutPoint>();
            for (UTXO utxo : selectedUTXO) {
                outpoints.addAll(utxo.getOutpoints());
            }
            Triple<Integer, Integer, Integer> outpointTypes = FeeUtil.getInstance().getOutpointCount(new Vector(outpoints));
            if (amount == balance) {
                fee = FeeUtil.getInstance().estimatedFeeSegwit(outpointTypes.getLeft(), outpointTypes.getMiddle(), outpointTypes.getRight(), 1);
                amount -= fee.longValue();
                receivers.clear();
                receivers.put(address, BigInteger.valueOf(amount));
                // 
                // fee sanity check
                // 
                restoreChangeIndexes();
                Transaction tx = SendFactory.getInstance(SendActivity.this).makeTransaction(account, outpoints, receivers);
                tx = SendFactory.getInstance(SendActivity.this).signTransaction(tx, account);
                byte[] serialized = tx.bitcoinSerialize();
                Log.d("SendActivity", "size:" + serialized.length);
                Log.d("SendActivity", "vsize:" + tx.getVirtualTransactionSize());
                Log.d("SendActivity", "fee:" + fee.longValue());
                if ((tx.hasWitness() && (fee.longValue() < tx.getVirtualTransactionSize())) || (!tx.hasWitness() && (fee.longValue() < serialized.length))) {
                    Toast.makeText(SendActivity.this, R.string.insufficient_fee, Toast.LENGTH_SHORT).show();
                    return false;
                }
            // 
            // 
            // 
            } else {
                fee = FeeUtil.getInstance().estimatedFeeSegwit(outpointTypes.getLeft(), outpointTypes.getMiddle(), 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());
        if (change > 0L && change < SamouraiWallet.bDust.longValue() && SPEND_TYPE == SPEND_SIMPLE) {
            AlertDialog.Builder dlg = new AlertDialog.Builder(SendActivity.this).setTitle(R.string.app_name).setMessage(R.string.change_is_dust).setCancelable(false).setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int whichButton) {
                    dialog.dismiss();
                }
            });
            if (!isFinishing()) {
                dlg.show();
            }
            return false;
        }
        _change = change;
        final BigInteger _fee = fee;
        String dest = null;
        if (strPCode != null && strPCode.length() > 0) {
            dest = BIP47Meta.getInstance().getDisplayLabel(strPCode);
        } else {
            dest = address;
        }
        strCannotDoBoltzmann = "";
        if (SendAddressUtil.getInstance().get(address) == 1) {
            strPrivacyWarning = getString(R.string.send_privacy_warning) + "\n\n";
        } else {
            strPrivacyWarning = "";
        }
        if (!canDoBoltzmann) {
            restoreChangeIndexes();
            sendTransactionDetailsView.getStoneWallSwitch().setOnClickListener(null);
            sendTransactionDetailsView.getStoneWallSwitch().setEnabled(false);
            sendTransactionDetailsView.enableStonewall(false);
            sendTransactionDetailsView.setEntropyBarStoneWallX1(null);
            sendTransactionDetailsView.getStoneWallSwitch().setOnCheckedChangeListener(onCheckedChangeListener);
            if (account == WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()) {
                strCannotDoBoltzmann = getString(R.string.boltzmann_cannot) + "\n\n";
            }
        }
        message = strCannotDoBoltzmann + strPrivacyWarning + "Send " + Coin.valueOf(amount).toPlainString() + " to " + dest + " (fee:" + Coin.valueOf(_fee.longValue()).toPlainString() + ")?\n";
        if (selectedCahootsType == SelectCahootsType.type.NONE) {
            tvTotalFee.setText(Coin.valueOf(_fee.longValue()).toPlainString().concat(" BTC"));
        } else {
            tvTotalFee.setText("__");
        }
        double value = Double.parseDouble(String.valueOf(_fee.add(BigInteger.valueOf(amount))));
        btnSend.setText("send ".concat(String.format(Locale.ENGLISH, "%.8f", getBtcValue(value))).concat(" BTC"));
        switch(selectedCahootsType) {
            case STONEWALLX2_MANUAL:
                {
                    sendTransactionDetailsView.showStonewallX2Layout("Manual", 1000);
                    btnSend.setBackgroundResource(R.drawable.button_blue);
                    btnSend.setText(getString(R.string.begin_stonewallx2));
                    break;
                }
            case STONEWALLX2_SAMOURAI:
                {
                    sendTransactionDetailsView.showStonewallX2Layout("Samourai Wallet", 1000);
                    break;
                }
            case STOWAWAY:
                {
                    // mixingPartner.setText("Samourai Wallet");
                    sendTransactionDetailsView.showStowawayLayout(address, null, 1000);
                    btnSend.setBackgroundResource(R.drawable.button_blue);
                    btnSend.setText(getString(R.string.begin_stowaway));
                    break;
                }
            case NONE:
                {
                    sendTransactionDetailsView.showStonewallx1Layout(null);
                    // for ricochet entropy will be 0 always
                    if (SPEND_TYPE == SPEND_RICOCHET) {
                        break;
                    }
                    if (receivers.size() <= 1) {
                        sendTransactionDetailsView.setEntropyBarStoneWallX1ZeroBits();
                        break;
                    }
                    if (receivers.size() > 8) {
                        sendTransactionDetailsView.setEntropyBarStoneWallX1(null);
                        break;
                    }
                    CalculateEntropy(selectedUTXO, receivers).subscribeOn(Schedulers.computation()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<TxProcessorResult>() {

                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(TxProcessorResult entropyResult) {
                            sendTransactionDetailsView.setEntropyBarStoneWallX1(entropyResult);
                        }

                        @Override
                        public void onError(Throwable e) {
                            sendTransactionDetailsView.setEntropyBarStoneWallX1(null);
                            e.printStackTrace();
                        }

                        @Override
                        public void onComplete() {
                        }
                    });
                    break;
                }
            default:
                {
                    btnSend.setBackgroundResource(R.drawable.button_green);
                    btnSend.setText("send ".concat(String.format(Locale.ENGLISH, "%.8f", getBtcValue((double) amount))).concat(" BTC"));
                }
        }
        return true;
    }
    return false;
}
Also used : AlertDialog(android.app.AlertDialog) TransactionOutput(org.bitcoinj.core.TransactionOutput) DialogInterface(android.content.DialogInterface) ArrayList(java.util.ArrayList) TxProcessorResult(com.samourai.boltzmann.processor.TxProcessorResult) Observer(io.reactivex.Observer) ArrayList(java.util.ArrayList) List(java.util.List) Vector(java.util.Vector) CompositeDisposable(io.reactivex.disposables.CompositeDisposable) Disposable(io.reactivex.disposables.Disposable) Script(org.bitcoinj.script.Script) JSONException(org.json.JSONException) JSONException(org.json.JSONException) IOException(java.io.IOException) ParseException(java.text.ParseException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) MnemonicException(org.bitcoinj.crypto.MnemonicException) Triple(org.apache.commons.lang3.tuple.Triple) BigInteger(java.math.BigInteger) UTXOCoin(com.samourai.wallet.utxos.models.UTXOCoin) Transaction(org.bitcoinj.core.Transaction) BigInteger(java.math.BigInteger) ParseException(java.text.ParseException)

Aggregations

ArrayList (java.util.ArrayList)4 IOException (java.io.IOException)3 List (java.util.List)3 AlertDialog (android.app.AlertDialog)2 DialogInterface (android.content.DialogInterface)2 BigInteger (java.math.BigInteger)2 ParseException (java.text.ParseException)2 Transaction (org.bitcoinj.core.Transaction)2 TransactionOutput (org.bitcoinj.core.TransactionOutput)2 MnemonicException (org.bitcoinj.crypto.MnemonicException)2 Script (org.bitcoinj.script.Script)2 JSONException (org.json.JSONException)2 ProgressDialog (android.app.ProgressDialog)1 Intent (android.content.Intent)1 Point (android.graphics.Point)1 Bundle (android.os.Bundle)1 Editable (android.text.Editable)1 TextWatcher (android.text.TextWatcher)1 MotionEvent (android.view.MotionEvent)1 View (android.view.View)1