Search in sources :

Example 6 with Tx

use of com.samourai.wallet.api.Tx in project samourai-wallet-android by Samourai-Wallet.

the class TxAdapter method onBindViewHolder.

@Override
public void onBindViewHolder(TxViewHolder holder, int position) {
    Tx tx = txes.get(position);
    if (tx.section == null) {
        long _amount = 0L;
        if (tx.getAmount() < 0.0) {
            _amount = Math.abs((long) tx.getAmount());
        } else {
            _amount = (long) tx.getAmount();
        }
        SimpleDateFormat sdf = new SimpleDateFormat("H:mm", Locale.US);
        sdf.setTimeZone(TimeZone.getDefault());
        holder.tvDateView.setText(sdf.format(tx.getTS() * 1000L));
        if (tx.getPaymentCode() != null) {
            holder.tvPaynymId.setVisibility(View.VISIBLE);
            holder.tvPaynymId.setText(BIP47Meta.getInstance().getDisplayLabel(tx.getPaymentCode()));
        } else {
            holder.tvPaynymId.setVisibility(View.INVISIBLE);
        }
        if (this.listener != null)
            holder.itemView.setOnClickListener(view -> {
                listener.onClick(position, tx);
            });
        if (tx.getAmount() < 0.0) {
            holder.tvDirection.setImageDrawable(mContext.getDrawable(R.drawable.out_going_tx_whtie_arrow));
            holder.tvAmount.setTextColor(ContextCompat.getColor(mContext, R.color.white));
            holder.tvAmount.setText("-".concat(displaySatUnit ? getSatoshiDisplayAmount(_amount).concat(" sat") : getBTCDisplayAmount(_amount).concat(" BTC")));
        } else {
            TransitionManager.beginDelayedTransition((ViewGroup) holder.tvAmount.getRootView(), new ChangeBounds());
            holder.tvDirection.setImageDrawable(mContext.getDrawable(R.drawable.incoming_tx_green));
            String amount = displaySatUnit ? getSatoshiDisplayAmount(_amount).concat(" sat") : getBTCDisplayAmount(_amount).concat(" BTC");
            if (this.account == WhirlpoolMeta.getInstance(mContext).getWhirlpoolPostmix() && _amount == 0) {
                amount = amount.concat(" (Remix)");
            }
            holder.tvAmount.setText(amount);
            holder.tvAmount.setTextColor(ContextCompat.getColor(mContext, R.color.green_ui_2));
        }
        if (this.account == WhirlpoolMeta.getInstance(mContext).getWhirlpoolPostmix() && _amount == 0) {
            holder.tvDirection.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_repeat_24dp));
        }
        if (UTXOUtil.getInstance().getNote(tx.getHash()) != null) {
            holder.txNoteGroup.setVisibility(View.VISIBLE);
            holder.tvNoteView.setText(UTXOUtil.getInstance().getNote(tx.getHash()));
        } else {
            holder.txNoteGroup.setVisibility(View.INVISIBLE);
        }
    } else {
        SimpleDateFormat fmt = new SimpleDateFormat("dd MMM yyyy", Locale.getDefault());
        fmt.setTimeZone(TimeZone.getDefault());
        Date date = new Date(tx.getTS());
        if (tx.getTS() == -1L) {
            holder.tvSection.setText("  Pending");
        } else {
            holder.tvSection.setText(fmt.format(date));
        }
    }
}
Also used : Context(android.content.Context) DateUtils(android.text.format.DateUtils) Coin(org.bitcoinj.core.Coin) DecimalFormatSymbols(java.text.DecimalFormatSymbols) Date(java.util.Date) ImageView(android.widget.ImageView) SimpleDateFormat(java.text.SimpleDateFormat) TransitionManager(android.transition.TransitionManager) Group(android.support.constraint.Group) AndroidSchedulers(io.reactivex.android.schedulers.AndroidSchedulers) WhirlpoolMeta(com.samourai.wallet.whirlpool.WhirlpoolMeta) ArrayList(java.util.ArrayList) ChangeBounds(android.transition.ChangeBounds) JSONObject(org.json.JSONObject) Calendar(java.util.Calendar) Locale(java.util.Locale) View(android.view.View) Observable(io.reactivex.Observable) Schedulers(io.reactivex.schedulers.Schedulers) UTXOUtil(com.samourai.wallet.utxos.UTXOUtil) Tx(com.samourai.wallet.api.Tx) LayoutInflater(android.view.LayoutInflater) TimeZone(java.util.TimeZone) DiffUtil(android.support.v7.util.DiffUtil) ContextCompat(android.support.v4.content.ContextCompat) DecimalFormat(java.text.DecimalFormat) R(com.samourai.wallet.R) ViewGroup(android.view.ViewGroup) RecyclerView(android.support.v7.widget.RecyclerView) List(java.util.List) CompositeDisposable(io.reactivex.disposables.CompositeDisposable) Disposable(io.reactivex.disposables.Disposable) TextView(android.widget.TextView) BIP47Meta(com.samourai.wallet.bip47.BIP47Meta) Collections(java.util.Collections) Tx(com.samourai.wallet.api.Tx) ChangeBounds(android.transition.ChangeBounds) SimpleDateFormat(java.text.SimpleDateFormat) Date(java.util.Date)

Example 7 with Tx

use of com.samourai.wallet.api.Tx in project samourai-wallet-android by Samourai-Wallet.

the class TxAdapter method makeSectionedDataSet.

private synchronized Observable<List<Tx>> makeSectionedDataSet(List<Tx> txes) {
    return Observable.fromCallable(() -> {
        Collections.sort(txes, (tx, t1) -> Long.compare(tx.getTS(), t1.getTS()));
        ArrayList<Long> sectionDates = new ArrayList<>();
        List<Tx> sectioned = new ArrayList<>();
        // for pending state
        boolean contains_pending = false;
        // if there is only pending tx today we don't want to add today's section
        boolean show_todays_tx = false;
        for (int i = 0; i < txes.size(); i++) {
            Tx tx = txes.get(i);
            if (tx.getConfirmations() < MAX_CONFIRM_COUNT) {
                contains_pending = true;
            }
            if (tx.getConfirmations() >= MAX_CONFIRM_COUNT && DateUtils.isToday(tx.getTS() * 1000)) {
                show_todays_tx = true;
            }
        }
        for (Tx tx : txes) {
            Date date = new Date();
            date.setTime(tx.getTS() * 1000);
            Calendar calendarDM = Calendar.getInstance();
            calendarDM.setTimeZone(TimeZone.getDefault());
            calendarDM.setTime(date);
            calendarDM.set(Calendar.HOUR_OF_DAY, 0);
            calendarDM.set(Calendar.MINUTE, 0);
            calendarDM.set(Calendar.SECOND, 0);
            calendarDM.set(Calendar.MILLISECOND, 0);
            if (!sectionDates.contains(calendarDM.getTime().getTime())) {
                if (DateUtils.isToday(calendarDM.getTime().getTime())) {
                    if (show_todays_tx)
                        sectionDates.add(calendarDM.getTime().getTime());
                } else {
                    sectionDates.add(calendarDM.getTime().getTime());
                }
            }
        }
        Collections.sort(sectionDates, Long::compare);
        if (contains_pending)
            sectionDates.add(-1L);
        for (Long key : sectionDates) {
            Tx section = new Tx(new JSONObject());
            if (key != -1) {
                section.section = new Date(key).toString();
            } else {
                section.section = "pending";
            }
            section.setTS(key);
            for (Tx tx : txes) {
                Date date = new Date();
                date.setTime(tx.getTS() * 1000);
                SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
                fmt.setTimeZone(TimeZone.getDefault());
                if (key == -1) {
                    if (tx.getConfirmations() < MAX_CONFIRM_COUNT) {
                        sectioned.add(tx);
                    }
                } else if (fmt.format(key).equals(fmt.format(date))) {
                    if (tx.getConfirmations() >= MAX_CONFIRM_COUNT) {
                        sectioned.add(tx);
                    }
                }
            }
            sectioned.add(section);
        }
        Collections.reverse(sectioned);
        return sectioned;
    });
}
Also used : Tx(com.samourai.wallet.api.Tx) JSONObject(org.json.JSONObject) Calendar(java.util.Calendar) ArrayList(java.util.ArrayList) SimpleDateFormat(java.text.SimpleDateFormat) Date(java.util.Date)

Example 8 with Tx

use of com.samourai.wallet.api.Tx in project samourai-wallet-android by Samourai-Wallet.

the class PayNymDetailsActivity method loadTxes.

private void loadTxes() {
    Disposable disposable = Observable.fromCallable(() -> {
        List<Tx> txesListSelected = new ArrayList<>();
        List<Tx> txs = APIFactory.getInstance(this).getAllXpubTxs();
        try {
            APIFactory.getInstance(getApplicationContext()).getXpubAmounts().get(HD_WalletFactory.getInstance(getApplicationContext()).get().getAccount(0).xpubstr());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MnemonicException.MnemonicLengthException e) {
            e.printStackTrace();
        }
        if (txs != null)
            for (Tx tx : txs) {
                if (tx.getPaymentCode() != null) {
                    if (tx.getPaymentCode().equals(pcode)) {
                        txesListSelected.add(tx);
                    }
                }
                List<String> hashes = SentToFromBIP47Util.getInstance().get(pcode);
                if (hashes != null)
                    for (String hash : hashes) {
                        if (hash.equals(tx.getHash())) {
                            if (!txesListSelected.contains(tx)) {
                                txesListSelected.add(tx);
                            }
                        }
                    }
            }
        return txesListSelected;
    }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(txes -> {
        this.txesList.clear();
        this.txesList.addAll(txes);
        paynymTxListAdapter.notifyDataSetChanged();
    });
    disposables.add(disposable);
}
Also used : CompositeDisposable(io.reactivex.disposables.CompositeDisposable) Disposable(io.reactivex.disposables.Disposable) Tx(com.samourai.wallet.api.Tx) PushTx(com.samourai.wallet.send.PushTx) List(java.util.List) ArrayList(java.util.ArrayList) IOException(java.io.IOException)

Example 9 with Tx

use of com.samourai.wallet.api.Tx in project samourai-wallet-android by Samourai-Wallet.

the class BalanceViewModel method parseXPUB.

private Observable<Boolean> parseXPUB(JSONObject jsonObject) throws JSONException {
    return Observable.fromCallable(() -> {
        if (jsonObject != null) {
            HashMap<String, Integer> pubkeys = new HashMap<String, Integer>();
            if (jsonObject.has("wallet")) {
                JSONObject walletObj = (JSONObject) jsonObject.get("wallet");
                if (walletObj.has("final_balance")) {
                    xpub_balance = walletObj.getLong("final_balance");
                    Log.d("APIFactory", "xpub_balance:" + xpub_balance);
                }
            }
            if (jsonObject.has("info")) {
                JSONObject infoObj = (JSONObject) jsonObject.get("info");
                if (infoObj.has("latest_block")) {
                    JSONObject blockObj = (JSONObject) infoObj.get("latest_block");
                    if (blockObj.has("height")) {
                        latest_block_height = blockObj.getLong("height");
                    }
                    if (blockObj.has("hash")) {
                        latest_block_hash = blockObj.getString("hash");
                    }
                }
            }
            if (jsonObject.has("addresses")) {
                JSONArray addressesArray = (JSONArray) jsonObject.get("addresses");
                JSONObject addrObj = null;
                for (int i = 0; i < addressesArray.length(); i++) {
                    addrObj = (JSONObject) addressesArray.get(i);
                    if (addrObj != null && addrObj.has("final_balance") && addrObj.has("address")) {
                        if (FormatsUtil.getInstance().isValidXpub((String) addrObj.get("address"))) {
                            xpub_amounts.put((String) addrObj.get("address"), addrObj.getLong("final_balance"));
                            if (addrObj.getString("address").equals(BIP84Util.getInstance(getApplication()).getWallet().getAccount(0).xpubstr()) || addrObj.getString("address").equals(BIP84Util.getInstance(getApplication()).getWallet().getAccount(0).zpubstr())) {
                                AddressFactory.getInstance().setHighestBIP84ReceiveIdx(addrObj.has("account_index") ? addrObj.getInt("account_index") : 0);
                                AddressFactory.getInstance().setHighestBIP84ChangeIdx(addrObj.has("change_index") ? addrObj.getInt("change_index") : 0);
                                BIP84Util.getInstance(getApplication()).getWallet().getAccount(0).getChain(0).setAddrIdx(addrObj.has("account_index") ? addrObj.getInt("account_index") : 0);
                                BIP84Util.getInstance(getApplication()).getWallet().getAccount(0).getChain(1).setAddrIdx(addrObj.has("change_index") ? addrObj.getInt("change_index") : 0);
                            } else if (addrObj.getString("address").equals(BIP49Util.getInstance(getApplication()).getWallet().getAccount(0).xpubstr()) || addrObj.getString("address").equals(BIP49Util.getInstance(getApplication()).getWallet().getAccount(0).ypubstr())) {
                                AddressFactory.getInstance().setHighestBIP49ReceiveIdx(addrObj.has("account_index") ? addrObj.getInt("account_index") : 0);
                                AddressFactory.getInstance().setHighestBIP49ChangeIdx(addrObj.has("change_index") ? addrObj.getInt("change_index") : 0);
                                BIP49Util.getInstance(getApplication()).getWallet().getAccount(0).getChain(0).setAddrIdx(addrObj.has("account_index") ? addrObj.getInt("account_index") : 0);
                                BIP49Util.getInstance(getApplication()).getWallet().getAccount(0).getChain(1).setAddrIdx(addrObj.has("change_index") ? addrObj.getInt("change_index") : 0);
                            } else if (AddressFactory.getInstance().xpub2account().get((String) addrObj.get("address")) != null) {
                                AddressFactory.getInstance().setHighestTxReceiveIdx(AddressFactory.getInstance().xpub2account().get((String) addrObj.get("address")), addrObj.has("account_index") ? addrObj.getInt("account_index") : 0);
                                AddressFactory.getInstance().setHighestTxChangeIdx(AddressFactory.getInstance().xpub2account().get((String) addrObj.get("address")), addrObj.has("change_index") ? addrObj.getInt("change_index") : 0);
                                try {
                                    HD_WalletFactory.getInstance(getApplication()).get().getAccount(0).getChain(0).setAddrIdx(addrObj.has("account_index") ? addrObj.getInt("account_index") : 0);
                                    HD_WalletFactory.getInstance(getApplication()).get().getAccount(0).getChain(1).setAddrIdx(addrObj.has("change_index") ? addrObj.getInt("change_index") : 0);
                                } catch (IOException | MnemonicException.MnemonicLengthException e) {
                                    ;
                                }
                            } else {
                                ;
                            }
                        } else {
                            long amount = 0L;
                            String addr = null;
                            addr = (String) addrObj.get("address");
                            amount = addrObj.getLong("final_balance");
                            String pcode = BIP47Meta.getInstance().getPCode4Addr(addr);
                            if (addr != null && addr.length() > 0 && pcode != null && pcode.length() > 0 && BIP47Meta.getInstance().getIdx4Addr(addr) != null) {
                                int idx = BIP47Meta.getInstance().getIdx4Addr(addr);
                                if (amount > 0L) {
                                    BIP47Meta.getInstance().addUnspent(pcode, idx);
                                    if (idx > BIP47Meta.getInstance().getIncomingIdx(pcode)) {
                                        BIP47Meta.getInstance().setIncomingIdx(pcode, idx);
                                    }
                                } else {
                                    if (addrObj.has("pubkey")) {
                                        String pubkey = addrObj.getString("pubkey");
                                        if (pubkeys.containsKey(pubkey)) {
                                            int count = pubkeys.get(pubkey);
                                            count++;
                                            if (count == 3) {
                                                BIP47Meta.getInstance().removeUnspent(pcode, Integer.valueOf(idx));
                                            } else {
                                                pubkeys.put(pubkey, count + 1);
                                            }
                                        } else {
                                            pubkeys.put(pubkey, 1);
                                        }
                                    } else {
                                        BIP47Meta.getInstance().removeUnspent(pcode, Integer.valueOf(idx));
                                    }
                                }
                                if (addr != null) {
                                    bip47_amounts.put(addr, amount);
                                }
                            }
                        }
                    }
                }
            }
            if (jsonObject.has("txs")) {
                List<String> seenHashes = new ArrayList<String>();
                JSONArray txArray = (JSONArray) jsonObject.get("txs");
                JSONObject txObj = null;
                for (int i = 0; i < txArray.length(); i++) {
                    txObj = (JSONObject) txArray.get(i);
                    long height = 0L;
                    long amount = 0L;
                    long ts = 0L;
                    String hash = null;
                    String addr = null;
                    String _addr = null;
                    if (txObj.has("block_height")) {
                        height = txObj.getLong("block_height");
                    } else {
                        // 0 confirmations
                        height = -1L;
                    }
                    if (txObj.has("hash")) {
                        hash = (String) txObj.get("hash");
                    }
                    if (txObj.has("result")) {
                        amount = txObj.getLong("result");
                    }
                    if (txObj.has("time")) {
                        ts = txObj.getLong("time");
                    }
                    if (!seenHashes.contains(hash)) {
                        seenHashes.add(hash);
                    }
                    if (txObj.has("inputs")) {
                        JSONArray inputArray = (JSONArray) txObj.get("inputs");
                        JSONObject inputObj = null;
                        for (int j = 0; j < inputArray.length(); j++) {
                            inputObj = (JSONObject) inputArray.get(j);
                            if (inputObj.has("prev_out")) {
                                JSONObject prevOutObj = (JSONObject) inputObj.get("prev_out");
                                if (prevOutObj.has("xpub")) {
                                    JSONObject xpubObj = (JSONObject) prevOutObj.get("xpub");
                                    addr = (String) xpubObj.get("m");
                                } else if (prevOutObj.has("addr") && BIP47Meta.getInstance().getPCode4Addr((String) prevOutObj.get("addr")) != null) {
                                    _addr = (String) prevOutObj.get("addr");
                                } else {
                                    _addr = (String) prevOutObj.get("addr");
                                }
                            }
                        }
                    }
                    if (txObj.has("out")) {
                        JSONArray outArray = (JSONArray) txObj.get("out");
                        JSONObject outObj = null;
                        for (int j = 0; j < outArray.length(); j++) {
                            outObj = (JSONObject) outArray.get(j);
                            if (outObj.has("xpub")) {
                                JSONObject xpubObj = (JSONObject) outObj.get("xpub");
                                addr = (String) xpubObj.get("m");
                            } else {
                                _addr = (String) outObj.get("addr");
                            }
                        }
                    }
                    if (addr != null || _addr != null) {
                        if (addr == null) {
                            addr = _addr;
                        }
                        Tx tx = new Tx(hash, addr, amount, ts, (latest_block_height > 0L && height > 0L) ? (latest_block_height - height) + 1 : 0);
                        if (SentToFromBIP47Util.getInstance().getByHash(hash) != null) {
                            tx.setPaymentCode(SentToFromBIP47Util.getInstance().getByHash(hash));
                        }
                        if (BIP47Meta.getInstance().getPCode4Addr(addr) != null) {
                            tx.setPaymentCode(BIP47Meta.getInstance().getPCode4Addr(addr));
                        }
                        if (!xpub_txs.containsKey(addr)) {
                            xpub_txs.put(addr, new ArrayList<Tx>());
                        }
                        if (FormatsUtil.getInstance().isValidXpub(addr)) {
                            xpub_txs.get(addr).add(tx);
                        } else {
                        // xpub_txs.get(AddressFactory.getInstance().account2xpub().get(0)).add(tx);
                        }
                        if (height > 0L) {
                            RBFUtil.getInstance().remove(hash);
                        }
                    }
                }
                List<String> hashesSentToViaBIP47 = SentToFromBIP47Util.getInstance().getAllHashes();
                if (hashesSentToViaBIP47.size() > 0) {
                    for (String s : hashesSentToViaBIP47) {
                        if (!seenHashes.contains(s)) {
                            SentToFromBIP47Util.getInstance().removeHash(s);
                        }
                    }
                }
            }
            try {
                PayloadUtil.getInstance(getApplication()).serializeMultiAddr(jsonObject);
            } catch (IOException | DecryptionException e) {
                ;
            }
            return true;
        }
        return false;
    });
}
Also used : Tx(com.samourai.wallet.api.Tx) HashMap(java.util.HashMap) JSONArray(org.json.JSONArray) ArrayList(java.util.ArrayList) IOException(java.io.IOException) JSONObject(org.json.JSONObject) DecryptionException(com.samourai.wallet.crypto.DecryptionException)

Example 10 with Tx

use of com.samourai.wallet.api.Tx in project samourai-wallet-android by Samourai-Wallet.

the class TxDiffUtil method areContentsTheSame.

@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
    Tx oldItem;
    Tx newItem;
    try {
        oldItem = oldTxes.get(oldItemPosition);
        newItem = oldTxes.get(newItemPosition);
    } catch (Exception e) {
        // IndexOutOfBoundsException
        return false;
    }
    if (oldItem.section != null || newItem.section != null) {
        return true;
    }
    boolean reRender = false;
    if (oldItem.getConfirmations() != newItem.getConfirmations()) {
        reRender = true;
    }
    if (!oldItem.getHash().equals(newItem.getHash())) {
        reRender = true;
    }
    return reRender;
}
Also used : Tx(com.samourai.wallet.api.Tx)

Aggregations

Tx (com.samourai.wallet.api.Tx)10 ArrayList (java.util.ArrayList)6 JSONObject (org.json.JSONObject)5 Disposable (io.reactivex.disposables.Disposable)4 Intent (android.content.Intent)3 View (android.view.View)3 TextView (android.widget.TextView)3 Bundle (android.os.Bundle)2 ContextCompat (android.support.v4.content.ContextCompat)2 TransitionManager (android.transition.TransitionManager)2 LayoutInflater (android.view.LayoutInflater)2 ViewGroup (android.view.ViewGroup)2 ImageView (android.widget.ImageView)2 R (com.samourai.wallet.R)2 APIFactory (com.samourai.wallet.api.APIFactory)2 BIP47Meta (com.samourai.wallet.bip47.BIP47Meta)2 PushTx (com.samourai.wallet.send.PushTx)2 CompositeDisposable (io.reactivex.disposables.CompositeDisposable)2 IOException (java.io.IOException)2 SimpleDateFormat (java.text.SimpleDateFormat)2