use of com.samourai.wallet.segwit.SegwitAddress in project samourai-wallet-android by Samourai-Wallet.
the class APIFactory method lockXPUB.
public synchronized JSONObject lockXPUB(String xpub, boolean bip49) {
String _url = SamouraiWallet.getInstance().isTestNet() ? WebUtil.SAMOURAI_API2_TESTNET : WebUtil.SAMOURAI_API2;
JSONObject jsonObject = null;
try {
String response = null;
ECKey ecKey = null;
if (AddressFactory.getInstance(context).xpub2account().get(xpub) != null || xpub.equals(BIP49Util.getInstance(context).getWallet().getAccount(0).ypubstr())) {
HD_Address addr = null;
if (bip49) {
addr = BIP49Util.getInstance(context).getWallet().getAccountAt(0).getChange().getAddressAt(0);
} else {
addr = HD_WalletFactory.getInstance(context).get().getAccount(0).getChain(AddressFactory.CHANGE_CHAIN).getAddressAt(0);
}
ecKey = addr.getECKey();
if (ecKey != null && ecKey.hasPrivKey()) {
String sig = ecKey.signMessage("lock");
String address = null;
if (bip49) {
SegwitAddress segwitAddress = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
address = segwitAddress.getAddressAsString();
} else {
address = ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
}
if (!TorUtil.getInstance(context).statusFromBroadcast()) {
StringBuilder args = new StringBuilder();
args.append("address=");
args.append(address);
args.append("&signature=");
args.append(Uri.encode(sig));
args.append("&message=");
args.append("lock");
// Log.i("APIFactory", "lock XPUB:" + args.toString());
response = WebUtil.getInstance(context).postURL(_url + "xpub/" + xpub + "/lock/", args.toString());
// Log.i("APIFactory", "lock XPUB response:" + response);
} else {
HashMap<String, String> args = new HashMap<String, String>();
args.put("address", address);
args.put("signature", Uri.encode(sig));
args.put("message", "lock");
// Log.i("APIFactory", "lock XPUB:" + args.toString());
response = WebUtil.getInstance(context).tor_postURL(_url + "xpub" + xpub + "/lock/", args);
// Log.i("APIFactory", "lock XPUB response:" + response);
}
try {
jsonObject = new JSONObject(response);
if (jsonObject.has("status") && jsonObject.getString("status").equals("ok")) {
if (bip49) {
PrefsUtil.getInstance(context).setValue(PrefsUtil.XPUB49LOCK, true);
} else {
PrefsUtil.getInstance(context).setValue(PrefsUtil.XPUB44LOCK, true);
}
}
} catch (JSONException je) {
je.printStackTrace();
jsonObject = null;
}
}
}
} catch (Exception e) {
jsonObject = null;
e.printStackTrace();
}
return jsonObject;
}
use of com.samourai.wallet.segwit.SegwitAddress in project samourai-wallet-android by Samourai-Wallet.
the class UTXOActivity method onCreate.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_utxo);
setTitle(R.string.options_utxo);
data = new ArrayList<DisplayData>();
doNotSpend = new ArrayList<DisplayData>();
listView = (ListView) findViewById(R.id.list);
update(false);
adapter = new UTXOAdapter();
listView.setAdapter(adapter);
AdapterView.OnItemClickListener listener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
Log.d("UTXOActivity", "menu:" + data.get(position).addr);
Log.d("UTXOActivity", "menu:" + data.get(position).hash + "-" + data.get(position).idx);
PopupMenu menu = new PopupMenu(UTXOActivity.this, view, Gravity.RIGHT);
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
int id = item.getItemId();
switch(id) {
case R.id.item_do_not_spend:
{
if (data.get(position).amount < BlockedUTXO.BLOCKED_UTXO_THRESHOLD && BlockedUTXO.getInstance().contains(data.get(position).hash, data.get(position).idx)) {
AlertDialog.Builder builder = new AlertDialog.Builder(UTXOActivity.this);
builder.setTitle(R.string.dusting_tx);
builder.setMessage(R.string.dusting_tx_unblock);
builder.setCancelable(true);
builder.setPositiveButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, int whichButton) {
;
}
});
builder.setNegativeButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, int whichButton) {
BlockedUTXO.getInstance().remove(data.get(position).hash, data.get(position).idx);
BlockedUTXO.getInstance().addNotDusted(data.get(position).hash, data.get(position).idx);
update(true);
}
});
AlertDialog alert = builder.create();
alert.show();
} else if (BlockedUTXO.getInstance().contains(data.get(position).hash, data.get(position).idx)) {
AlertDialog.Builder builder = new AlertDialog.Builder(UTXOActivity.this);
builder.setTitle(R.string.mark_spend);
builder.setMessage(R.string.mark_utxo_spend);
builder.setCancelable(true);
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, int whichButton) {
BlockedUTXO.getInstance().remove(data.get(position).hash, data.get(position).idx);
Log.d("UTXOActivity", "removed:" + data.get(position).hash + "-" + data.get(position).idx);
update(true);
}
});
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, int whichButton) {
;
}
});
AlertDialog alert = builder.create();
alert.show();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(UTXOActivity.this);
builder.setTitle(R.string.mark_do_not_spend);
builder.setMessage(R.string.mark_utxo_do_not_spend);
builder.setCancelable(true);
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, int whichButton) {
BlockedUTXO.getInstance().add(data.get(position).hash, data.get(position).idx, data.get(position).amount);
Log.d("UTXOActivity", "added:" + data.get(position).hash + "-" + data.get(position).idx);
update(true);
}
});
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, int whichButton) {
;
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
break;
case R.id.item_sign:
{
String addr = data.get(position).addr;
ECKey ecKey = SendFactory.getPrivKey(addr);
String msg = null;
if (Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), addr).isP2SHAddress() || FormatsUtil.getInstance().isValidBech32(addr)) {
msg = UTXOActivity.this.getString(R.string.utxo_sign_text3);
try {
JSONObject obj = new JSONObject();
obj.put("pubkey", ecKey.getPublicKeyAsHex());
obj.put("address", addr);
msg += " " + obj.toString();
} catch (JSONException je) {
msg += ":";
msg += addr;
msg += ", ";
msg += "pubkey:";
msg += ecKey.getPublicKeyAsHex();
}
} else {
msg = UTXOActivity.this.getString(R.string.utxo_sign_text2);
}
if (ecKey != null) {
MessageSignUtil.getInstance(UTXOActivity.this).doSign(UTXOActivity.this.getString(R.string.utxo_sign), UTXOActivity.this.getString(R.string.utxo_sign_text1), msg, ecKey);
}
}
break;
case R.id.item_redeem:
{
String addr = data.get(position).addr;
ECKey ecKey = SendFactory.getPrivKey(addr);
SegwitAddress p2sh_p2wpkh = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
if (ecKey != null && p2sh_p2wpkh != null) {
String redeemScript = Hex.toHexString(p2sh_p2wpkh.segWitRedeemScript().getProgram());
TextView showText = new TextView(UTXOActivity.this);
showText.setText(redeemScript);
showText.setTextIsSelectable(true);
showText.setPadding(40, 10, 40, 10);
showText.setTextSize(18.0f);
new AlertDialog.Builder(UTXOActivity.this).setTitle(R.string.app_name).setView(showText).setCancelable(false).setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
;
}
}).show();
}
}
break;
case R.id.item_view:
{
int sel = PrefsUtil.getInstance(UTXOActivity.this).getValue(PrefsUtil.BLOCK_EXPLORER, 0);
if (sel >= BlockExplorerUtil.getInstance().getBlockExplorerAddressUrls().length) {
sel = 0;
}
CharSequence url = BlockExplorerUtil.getInstance().getBlockExplorerTxUrls()[sel];
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url + data.get(position).hash));
startActivity(browserIntent);
}
break;
case R.id.item_privkey:
{
String addr = data.get(position).addr;
ECKey ecKey = SendFactory.getPrivKey(addr);
String strPrivKey = ecKey.getPrivateKeyAsWiF(SamouraiWallet.getInstance().getCurrentNetworkParams());
ImageView showQR = new ImageView(UTXOActivity.this);
Bitmap bitmap = null;
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(strPrivKey, null, Contents.Type.TEXT, BarcodeFormat.QR_CODE.toString(), 500);
try {
bitmap = qrCodeEncoder.encodeAsBitmap();
} catch (WriterException e) {
e.printStackTrace();
}
showQR.setImageBitmap(bitmap);
TextView showText = new TextView(UTXOActivity.this);
showText.setText(strPrivKey);
showText.setTextIsSelectable(true);
showText.setPadding(40, 10, 40, 10);
showText.setTextSize(18.0f);
LinearLayout privkeyLayout = new LinearLayout(UTXOActivity.this);
privkeyLayout.setOrientation(LinearLayout.VERTICAL);
privkeyLayout.addView(showQR);
privkeyLayout.addView(showText);
new AlertDialog.Builder(UTXOActivity.this).setTitle(R.string.app_name).setView(privkeyLayout).setCancelable(false).setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
;
}
}).show();
}
break;
}
return true;
}
});
menu.inflate(R.menu.utxo_menu);
if (BlockedUTXO.getInstance().contains(data.get(position).hash, data.get(position).idx)) {
menu.getMenu().findItem(R.id.item_do_not_spend).setTitle(R.string.mark_spend);
} else {
menu.getMenu().findItem(R.id.item_do_not_spend).setTitle(R.string.mark_do_not_spend);
}
String addr = data.get(position).addr;
if (!Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), addr).isP2SHAddress()) {
menu.getMenu().findItem(R.id.item_redeem).setVisible(false);
}
menu.show();
}
};
listView.setOnItemClickListener(listener);
}
use of com.samourai.wallet.segwit.SegwitAddress in project samourai-wallet-android by Samourai-Wallet.
the class SweepUtil method sweep.
public void sweep(final PrivKeyReader privKeyReader, final boolean sweepBIP49) {
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
try {
if (privKeyReader == null || privKeyReader.getKey() == null || !privKeyReader.getKey().hasPrivKey()) {
Toast.makeText(context, R.string.cannot_recognize_privkey, Toast.LENGTH_SHORT).show();
return;
}
String address = null;
UTXO utxo = null;
if (sweepBIP49) {
utxo = utxoP2SH_P2WPKH;
address = addressP2SH_P2WPKH;
} else {
addressP2PKH = privKeyReader.getKey().toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
Log.d("SweepUtil", "address derived P2PKH:" + addressP2PKH);
addressP2SH_P2WPKH = addressP2SH_P2WPKH = new SegwitAddress(privKeyReader.getKey(), SamouraiWallet.getInstance().getCurrentNetworkParams()).getAddressAsString();
Log.d("SweepUtil", "address derived P2SH_P2WPKH:" + addressP2SH_P2WPKH);
utxoP2PKH = APIFactory.getInstance(context).getUnspentOutputsForSweep(addressP2PKH);
utxoP2SH_P2WPKH = APIFactory.getInstance(context).getUnspentOutputsForSweep(addressP2SH_P2WPKH);
utxo = utxoP2PKH;
address = addressP2PKH;
}
if (utxo != null) {
long total_value = 0L;
final List<MyTransactionOutPoint> outpoints = utxo.getOutpoints();
for (MyTransactionOutPoint outpoint : outpoints) {
total_value += outpoint.getValue().longValue();
}
final BigInteger fee;
if (sweepBIP49) {
fee = FeeUtil.getInstance().estimatedFeeSegwit(0, outpoints.size(), 1);
} else {
fee = FeeUtil.getInstance().estimatedFee(outpoints.size(), 1);
}
final long amount = total_value - fee.longValue();
// Log.d("BalanceActivity", "Total value:" + total_value);
// Log.d("BalanceActivity", "Amount:" + amount);
// Log.d("BalanceActivity", "Fee:" + fee.toString());
String message = "Sweep " + Coin.valueOf(amount).toPlainString() + " from " + address + " (fee:" + Coin.valueOf(fee.longValue()).toPlainString() + ")?";
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.app_name);
builder.setMessage(message);
builder.setCancelable(false);
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, int whichButton) {
final ProgressDialog progress = new ProgressDialog(context);
progress.setCancelable(false);
progress.setTitle(R.string.app_name);
progress.setMessage(context.getString(R.string.please_wait_sending));
progress.show();
String receive_address = null;
if (PrefsUtil.getInstance(context).getValue(PrefsUtil.USE_SEGWIT, true) == true) {
receive_address = AddressFactory.getInstance(context).getBIP49(AddressFactory.RECEIVE_CHAIN).getAddressAsString();
} else {
receive_address = AddressFactory.getInstance(context).get(AddressFactory.RECEIVE_CHAIN).getAddressString();
}
final HashMap<String, BigInteger> receivers = new HashMap<String, BigInteger>();
receivers.put(receive_address, BigInteger.valueOf(amount));
org.bitcoinj.core.Transaction tx = SendFactory.getInstance(context).makeTransaction(0, outpoints, receivers);
tx = SendFactory.getInstance(context).signTransactionForSweep(tx, privKeyReader);
final String hexTx = new String(Hex.encode(tx.bitcoinSerialize()));
// Log.d("BalanceActivity", hexTx);
String response = null;
try {
if (PrefsUtil.getInstance(context).getValue(PrefsUtil.USE_TRUSTED_NODE, false) == true) {
if (TrustedNodeUtil.getInstance().isSet()) {
response = PushTx.getInstance(context).trustedNode(hexTx);
JSONObject jsonObject = new org.json.JSONObject(response);
if (jsonObject.has("result")) {
if (jsonObject.getString("result").matches("^[A-Za-z0-9]{64}$")) {
Toast.makeText(context, R.string.tx_sent, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, R.string.trusted_node_tx_error, Toast.LENGTH_SHORT).show();
}
}
} else {
Toast.makeText(context, R.string.trusted_node_not_valid, Toast.LENGTH_SHORT).show();
}
} else {
response = PushTx.getInstance(context).samourai(hexTx);
if (response != null) {
JSONObject jsonObject = new org.json.JSONObject(response);
if (jsonObject.has("status")) {
if (jsonObject.getString("status").equals("ok")) {
Toast.makeText(context, R.string.tx_sent, Toast.LENGTH_SHORT).show();
}
}
} else {
Toast.makeText(context, R.string.pushtx_returns_null, Toast.LENGTH_SHORT).show();
}
}
} catch (JSONException je) {
Toast.makeText(context, "pushTx:" + je.getMessage(), Toast.LENGTH_SHORT).show();
}
if (progress != null && progress.isShowing()) {
progress.dismiss();
}
}
});
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, int whichButton) {
;
}
});
AlertDialog alert = builder.create();
alert.show();
} else {
// Toast.makeText(context, R.string.cannot_find_unspents, Toast.LENGTH_SHORT).show();
sweep(privKeyReader, true);
}
} catch (Exception e) {
Toast.makeText(context, R.string.cannot_sweep_privkey, Toast.LENGTH_SHORT).show();
}
Looper.loop();
}
}).start();
}
use of com.samourai.wallet.segwit.SegwitAddress in project samourai-wallet-android by Samourai-Wallet.
the class AndroidTx0Service method buildTx0Input.
@Override
protected void buildTx0Input(Transaction tx, UnspentOutputWithKey input, NetworkParameters params) {
ECKey spendFromKey = ECKey.fromPrivate(input.getKey());
TransactionOutPoint depositSpendFrom = input.computeOutpoint(params);
SegwitAddress segwitAddress = new SegwitAddress(spendFromKey.getPubKey(), params);
MyTransactionOutPoint _outpoint = new MyTransactionOutPoint(depositSpendFrom.getHash(), (int) depositSpendFrom.getIndex(), BigInteger.valueOf(depositSpendFrom.getValue().longValue()), segwitAddress.segWitRedeemScript().getProgram(), segwitAddress.getBech32AsString());
MyTransactionInput _input = new MyTransactionInput(params, null, new byte[0], _outpoint, depositSpendFrom.getHash().toString(), (int) depositSpendFrom.getIndex());
tx.addInput(_input);
}
use of com.samourai.wallet.segwit.SegwitAddress in project samourai-wallet-android by Samourai-Wallet.
the class SendActivity method processPCode.
private void processPCode(String pcode, String meta) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
setBalance();
}
}, 2000);
if (FormatsUtil.getInstance().isValidPaymentCode(pcode)) {
if (BIP47Meta.getInstance().getOutgoingStatus(pcode) == BIP47Meta.STATUS_SENT_CFM) {
try {
PaymentCode _pcode = new PaymentCode(pcode);
PaymentAddress paymentAddress = BIP47Util.getInstance(this).getSendAddress(_pcode, BIP47Meta.getInstance().getOutgoingIdx(pcode));
if (BIP47Meta.getInstance().getSegwit(pcode)) {
SegwitAddress segwitAddress = new SegwitAddress(paymentAddress.getSendECKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
strDestinationBTCAddress = segwitAddress.getBech32AsString();
} else {
strDestinationBTCAddress = paymentAddress.getSendECKey().toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
}
strPCode = _pcode.toString();
setToAddress(BIP47Meta.getInstance().getDisplayLabel(strPCode));
toAddressEditText.setEnabled(false);
validateSpend();
} catch (Exception e) {
Toast.makeText(this, R.string.error_payment_code, Toast.LENGTH_SHORT).show();
}
} else {
// Toast.makeText(SendActivity.this, "Payment must be added and notification tx sent", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, PayNymDetailsActivity.class);
intent.putExtra("pcode", pcode);
intent.putExtra("label", "");
if (meta != null && meta.startsWith("?") && meta.length() > 1) {
meta = meta.substring(1);
if (meta.length() > 0) {
String _meta = null;
Map<String, String> map = new HashMap<String, String>();
meta.length();
try {
_meta = URLDecoder.decode(meta, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
map = Splitter.on('&').trimResults().withKeyValueSeparator("=").split(_meta);
intent.putExtra("label", map.containsKey("title") ? map.get("title").trim() : "");
}
}
if (!openedPaynym) {
startActivity(intent);
openedPaynym = true;
}
}
} else {
Toast.makeText(this, R.string.invalid_payment_code, Toast.LENGTH_SHORT).show();
}
}
Aggregations