use of com.samourai.wallet.hd.HD_Address in project samourai-wallet-android by Samourai-Wallet.
the class APIFactory method lockXPUB.
/*
public synchronized JSONObject deleteXPUB(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(xpub);
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("message=");
args.append(xpub);
args.append("address=");
args.append(address);
args.append("&signature=");
args.append(Uri.encode(sig));
info("APIFactory", "delete XPUB:" + args.toString());
response = WebUtil.getInstance(context).deleteURL(_url + "delete/" + xpub, args.toString());
info("APIFactory", "delete XPUB response:" + response);
}
else {
HashMap<String,String> args = new HashMap<String,String>();
args.put("message", xpub);
args.put("address", address);
args.put("signature", Uri.encode(sig));
info("APIFactory", "delete XPUB:" + args.toString());
response = WebUtil.getInstance(context).tor_deleteURL(_url + "delete", args);
info("APIFactory", "delete XPUB response:" + response);
}
try {
jsonObject = new JSONObject(response);
if(jsonObject.has("status") && jsonObject.getString("status").equals("ok")) {
;
}
}
catch(JSONException je) {
je.printStackTrace();
jsonObject = null;
}
}
}
}
catch(Exception e) {
jsonObject = null;
e.printStackTrace();
}
return jsonObject;
}
*/
public synchronized JSONObject lockXPUB(String xpub, int purpose, String tag) {
String _url = WebUtil.getAPIUrl(context);
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()) || xpub.equals(BIP84Util.getInstance(context).getWallet().getAccount(0).zpubstr()) || xpub.equals(BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPremixAccount()).zpubstr()) || xpub.equals(BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).zpubstr())) {
HD_Address addr = null;
switch(purpose) {
case 49:
addr = BIP49Util.getInstance(context).getWallet().getAccountAt(0).getChange().getAddressAt(0);
break;
case 84:
if (tag != null && tag.equals(PrefsUtil.XPUBPRELOCK)) {
addr = BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPremixAccount()).getChange().getAddressAt(0);
} else if (tag != null && tag.equals(PrefsUtil.XPUBPOSTLOCK)) {
addr = BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).getChange().getAddressAt(0);
} else {
addr = BIP84Util.getInstance(context).getWallet().getAccountAt(0).getChange().getAddressAt(0);
}
break;
default:
addr = HD_WalletFactory.getInstance(context).get().getAccount(0).getChain(AddressFactory.CHANGE_CHAIN).getAddressAt(0);
break;
}
ecKey = addr.getECKey();
if (ecKey != null && ecKey.hasPrivKey()) {
String sig = ecKey.signMessage("lock");
String address = null;
switch(purpose) {
case 49:
SegwitAddress p2shp2wpkh = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
address = p2shp2wpkh.getAddressAsString();
break;
case 84:
SegwitAddress segwitAddress = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
address = segwitAddress.getBech32AsString();
break;
default:
address = ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
break;
}
if (!TorManager.getInstance(context).isRequired()) {
StringBuilder args = new StringBuilder();
args.append("address=");
args.append(address);
args.append("&signature=");
args.append(Uri.encode(sig));
args.append("&message=");
args.append("lock");
// info("APIFactory", "lock XPUB:" + args.toString());
args.append("&at=");
args.append(getAccessToken());
response = WebUtil.getInstance(context).postURL(_url + "xpub/" + xpub + "/lock/", args.toString());
// info("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("signature", sig);
args.put("message", "lock");
args.put("at", getAccessToken());
info("APIFactory", "lock XPUB:" + _url);
info("APIFactory", "lock XPUB:" + args.toString());
response = WebUtil.getInstance(context).tor_postURL(_url + "xpub/" + xpub + "/lock/", args);
info("APIFactory", "lock XPUB response:" + response);
}
try {
jsonObject = new JSONObject(response);
if (jsonObject.has("status") && jsonObject.getString("status").equals("ok")) {
if (tag != null) {
PrefsUtil.getInstance(context).setValue(tag, true);
} else {
switch(purpose) {
case 49:
PrefsUtil.getInstance(context).setValue(PrefsUtil.XPUB49LOCK, true);
break;
case 84:
PrefsUtil.getInstance(context).setValue(PrefsUtil.XPUB84LOCK, true);
break;
default:
PrefsUtil.getInstance(context).setValue(PrefsUtil.XPUB44LOCK, true);
break;
}
}
}
} catch (JSONException je) {
je.printStackTrace();
jsonObject = null;
}
}
}
} catch (Exception e) {
jsonObject = null;
e.printStackTrace();
}
return jsonObject;
}
use of com.samourai.wallet.hd.HD_Address in project samourai-wallet-android by Samourai-Wallet.
the class CahootsUtil method doStowaway2.
//
// sender
//
public Cahoots doStowaway2(Stowaway stowaway1) throws Exception {
debug("CahootsUtil", "sender account (2):" + stowaway1.getAccount());
Transaction transaction = stowaway1.getTransaction();
debug("CahootsUtil", "step2 tx:" + org.spongycastle.util.encoders.Hex.toHexString(transaction.bitcoinSerialize()));
int nbIncomingInputs = transaction.getInputs().size();
List<UTXO> utxos = getCahootsUTXO(stowaway1.getAccount());
// sort in ascending order by value
Collections.sort(utxos, new UTXO.UTXOComparator());
Collections.reverse(utxos);
debug("CahootsUtil", "BIP84 utxos:" + utxos.size());
List<UTXO> selectedUTXO = new ArrayList<UTXO>();
int nbTotalSelectedOutPoints = 0;
long totalSelectedAmount = 0L;
List<UTXO> lowUTXO = new ArrayList<UTXO>();
for (UTXO utxo : utxos) {
if (utxo.getValue() < stowaway1.getSpendAmount()) {
lowUTXO.add(utxo);
}
}
List<List<UTXO>> listOfLists = new ArrayList<List<UTXO>>();
Collections.shuffle(lowUTXO);
listOfLists.add(lowUTXO);
listOfLists.add(utxos);
for (List<UTXO> list : listOfLists) {
selectedUTXO.clear();
totalSelectedAmount = 0L;
nbTotalSelectedOutPoints = 0;
for (UTXO utxo : list) {
selectedUTXO.add(utxo);
totalSelectedAmount += utxo.getValue();
debug("BIP84 selected utxo:", "" + utxo.getValue());
nbTotalSelectedOutPoints += utxo.getOutpoints().size();
if (totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
// discard "extra" utxo, if any
List<UTXO> _selectedUTXO = new ArrayList<UTXO>();
Collections.reverse(selectedUTXO);
int _nbTotalSelectedOutPoints = 0;
long _totalSelectedAmount = 0L;
for (UTXO utxoSel : selectedUTXO) {
_selectedUTXO.add(utxoSel);
_totalSelectedAmount += utxoSel.getValue();
debug("CahootsUtil", "BIP84 post selected utxo:" + utxoSel.getValue());
_nbTotalSelectedOutPoints += utxoSel.getOutpoints().size();
if (_totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, _nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
selectedUTXO.clear();
selectedUTXO.addAll(_selectedUTXO);
totalSelectedAmount = _totalSelectedAmount;
nbTotalSelectedOutPoints = _nbTotalSelectedOutPoints;
break;
}
}
break;
}
}
if (totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
break;
}
}
/*
if(lowUTXO.size() > 0) {
Collections.shuffle(lowUTXO);
for (UTXO utxo : lowUTXO) {
selectedUTXO.add(utxo);
totalSelectedAmount += utxo.getValue();
debug("BIP84 selected utxo:", "" + utxo.getValue());
nbTotalSelectedOutPoints += utxo.getOutpoints().size();
if (totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
// discard "extra" utxo, if any
List<UTXO> _selectedUTXO = new ArrayList<UTXO>();
Collections.reverse(selectedUTXO);
int _nbTotalSelectedOutPoints = 0;
long _totalSelectedAmount = 0L;
for (UTXO utxoSel : selectedUTXO) {
_selectedUTXO.add(utxoSel);
_totalSelectedAmount += utxoSel.getValue();
debug("CahootsUtil", "BIP84 post selected utxo:" + utxoSel.getValue());
_nbTotalSelectedOutPoints += utxoSel.getOutpoints().size();
if (_totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, _nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
selectedUTXO.clear();
selectedUTXO.addAll(_selectedUTXO);
totalSelectedAmount = _totalSelectedAmount;
nbTotalSelectedOutPoints = _nbTotalSelectedOutPoints;
break;
}
}
break;
}
}
}
if (!(totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue())) {
selectedUTXO.clear();
totalSelectedAmount = 0L;
nbTotalSelectedOutPoints = 0;
for (UTXO utxo : utxos) {
selectedUTXO.add(utxo);
totalSelectedAmount += utxo.getValue();
debug("BIP84 selected utxo:", "" + utxo.getValue());
nbTotalSelectedOutPoints += utxo.getOutpoints().size();
if (totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
// discard "extra" utxo, if any
List<UTXO> _selectedUTXO = new ArrayList<UTXO>();
Collections.reverse(selectedUTXO);
int _nbTotalSelectedOutPoints = 0;
long _totalSelectedAmount = 0L;
for (UTXO utxoSel : selectedUTXO) {
_selectedUTXO.add(utxoSel);
_totalSelectedAmount += utxoSel.getValue();
debug("CahootsUtil", "BIP84 post selected utxo:" + utxoSel.getValue());
_nbTotalSelectedOutPoints += utxoSel.getOutpoints().size();
if (_totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, _nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue()) {
selectedUTXO.clear();
selectedUTXO.addAll(_selectedUTXO);
totalSelectedAmount = _totalSelectedAmount;
nbTotalSelectedOutPoints = _nbTotalSelectedOutPoints;
break;
}
}
break;
}
}
}
*/
if (!(totalSelectedAmount > FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue() + stowaway1.getSpendAmount() + SamouraiWallet.bDust.longValue())) {
return null;
}
debug("CahootsUtil", "BIP84 selected utxos:" + selectedUTXO.size());
long fee = FeeUtil.getInstance().estimatedFeeSegwit(0, 0, nbTotalSelectedOutPoints + nbIncomingInputs, 2).longValue();
debug("CahootsUtil", "fee:" + fee);
NetworkParameters params = stowaway1.getParams();
//
//
// step2: B verif, utxos -> A (take smallest that cover amount)
//
//
String zpub = BIP84Util.getInstance(context).getWallet().getAccountAt(stowaway1.getAccount()).zpubstr();
HashMap<_TransactionOutPoint, Triple<byte[], byte[], String>> inputsB = new HashMap<_TransactionOutPoint, Triple<byte[], byte[], String>>();
for (UTXO utxo : selectedUTXO) {
for (MyTransactionOutPoint outpoint : utxo.getOutpoints()) {
_TransactionOutPoint _outpoint = new _TransactionOutPoint(outpoint);
ECKey eckey = SendFactory.getPrivKey(_outpoint.getAddress(), stowaway1.getAccount());
String path = APIFactory.getInstance(context).getUnspentPaths().get(_outpoint.getAddress());
inputsB.put(_outpoint, Triple.of(eckey.getPubKey(), stowaway1.getFingerprint(), path));
}
}
debug("CahootsUtil", "inputsB:" + inputsB.size());
// change output
SegwitAddress segwitAddress = null;
int idx = 0;
if (stowaway1.getAccount() == WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()) {
idx = AddressFactory.getInstance(context).getHighestPostChangeIdx();
HD_Address addr = BIP84Util.getInstance(context).getWallet().getAccountAt(stowaway1.getAccount()).getChange().getAddressAt(idx);
segwitAddress = new SegwitAddress(addr.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
} else {
idx = BIP84Util.getInstance(context).getWallet().getAccount(0).getChange().getAddrIdx();
segwitAddress = BIP84Util.getInstance(context).getAddressAt(1, idx);
}
HashMap<_TransactionOutput, Triple<byte[], byte[], String>> outputsB = new HashMap<_TransactionOutput, Triple<byte[], byte[], String>>();
Pair<Byte, byte[]> pair = Bech32Segwit.decode(SamouraiWallet.getInstance().isTestNet() ? "tb" : "bc", segwitAddress.getBech32AsString());
byte[] scriptPubKey_B = Bech32Segwit.getScriptPubkey(pair.getLeft(), pair.getRight());
_TransactionOutput output_B0 = new _TransactionOutput(params, null, Coin.valueOf((totalSelectedAmount - stowaway1.getSpendAmount()) - fee), scriptPubKey_B);
outputsB.put(output_B0, Triple.of(segwitAddress.getECKey().getPubKey(), stowaway1.getFingerprint(), "M/1/" + idx));
debug("CahootsUtil", "outputsB:" + outputsB.size());
Stowaway stowaway2 = new Stowaway(stowaway1);
stowaway2.inc(inputsB, outputsB, null);
stowaway2.setFeeAmount(fee);
return stowaway2;
}
Aggregations