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));
}
}
}
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;
});
}
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);
}
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;
});
}
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;
}
Aggregations