Commit 5c12dc86 authored by T Dev. D's avatar T Dev. D 😎
Browse files

Post-mix like type change

parent 55af74a3
......@@ -138,6 +138,16 @@ public class AddressCalcActivity extends SamouraiActivity {
segwitAddress = new SegwitAddress(hd_addr.getECKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
}
else if(spType.getSelectedItemPosition() == 6) {
segwitAddress = null;
chain = 1;
hd_addr = BIP84Util.getInstance(AddressCalcActivity.this).getWallet().getAccountAt(WhirlpoolMeta.getInstance(AddressCalcActivity.this).getWhirlpoolPostmix()).getChain(chain).getAddressAt(index);
}
else if(spType.getSelectedItemPosition() == 7) {
chain = 1;
hd_addr = BIP84Util.getInstance(AddressCalcActivity.this).getWallet().getAccountAt(WhirlpoolMeta.getInstance(AddressCalcActivity.this).getWhirlpoolPostmix()).getChain(chain).getAddressAt(index);
segwitAddress = new SegwitAddress(hd_addr.getECKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
}
else if(spType.getSelectedItemPosition() == 8) {
hd_addr = BIP84Util.getInstance(AddressCalcActivity.this).getWallet().getAccountAt(WhirlpoolMeta.getInstance(AddressCalcActivity.this).getWhirlpoolBadBank()).getChain(chain).getAddressAt(index);
segwitAddress = new SegwitAddress(hd_addr.getECKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
}
......@@ -148,13 +158,13 @@ public class AddressCalcActivity extends SamouraiActivity {
final ECKey ecKey;
final String strAddress;
if(spType.getSelectedItemPosition() == 2) {
if(spType.getSelectedItemPosition() == 2 || spType.getSelectedItemPosition() == 6) {
ecKey = hd_addr.getECKey();
strAddress = hd_addr.getAddressString();
}
else {
ecKey = segwitAddress.getECKey();
if(spType.getSelectedItemPosition() == 0) {
if(spType.getSelectedItemPosition() == 0 || spType.getSelectedItemPosition() == 7) {
strAddress = segwitAddress.getAddressAsString();
}
else {
......
......@@ -2576,12 +2576,13 @@ public class APIFactory {
String path = null;
try {
String address = Bech32Util.getInstance().getAddressFromScript(script);
String address = outDict.getString("addr");
if(outDict.has("xpub")) {
JSONObject xpubObj = (JSONObject)outDict.get("xpub");
path = (String)xpubObj.get("path");
String m = (String)xpubObj.get("m");
unspentPaths.put(address, path);
if(m.equals(BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).xpubstr())) {
unspentBIP84PostMix.put(address, WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix());
......
......@@ -60,6 +60,7 @@ import com.samourai.wallet.cahoots.CahootsType;
import com.samourai.wallet.cahoots.psbt.PSBTUtil;
import com.samourai.wallet.fragments.CameraFragmentBottomSheet;
import com.samourai.wallet.fragments.PaynymSelectModalFragment;
import com.samourai.wallet.hd.HD_Address;
import com.samourai.wallet.hd.HD_WalletFactory;
import com.samourai.wallet.payload.PayloadUtil;
import com.samourai.wallet.paynym.paynymDetails.PayNymDetailsActivity;
......@@ -95,6 +96,7 @@ import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionOutput;
import org.bitcoinj.script.Script;
......@@ -1194,13 +1196,13 @@ public class SendActivity extends SamouraiActivity {
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) {
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()) {
}
else if (FormatsUtil.getInstance().isValidBech32(address) || Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
changeType = FormatsUtil.getInstance().isValidBech32(address) ? 84 : 49;
} else {
}
else {
changeType = 44;
}
......@@ -1209,11 +1211,14 @@ public class SendActivity extends SamouraiActivity {
if (account == WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()) {
change_index = idxBIP84PostMixInternal;
} else if (changeType == 84) {
}
else if (changeType == 84) {
change_index = idxBIP84Internal;
} else if (changeType == 49) {
}
else if (changeType == 49) {
change_index = idxBIP49Internal;
} else {
}
else {
change_index = idxBIP44Internal;
}
......@@ -1855,16 +1860,32 @@ public class SendActivity extends SamouraiActivity {
if (_change > 0L) {
if (SPEND_TYPE == SPEND_SIMPLE) {
if (account == WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()) {
String change_address = BIP84Util.getInstance(SendActivity.this).getAddressAt(WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix(), AddressFactory.CHANGE_CHAIN, AddressFactory.getInstance(SendActivity.this).getHighestPostChangeIdx()).getBech32AsString();
receivers.put(change_address, BigInteger.valueOf(_change));
} else if (changeType == 84) {
String change_address = BIP84Util.getInstance(SendActivity.this).getAddressAt(AddressFactory.CHANGE_CHAIN, BIP84Util.getInstance(SendActivity.this).getWallet().getAccount(0).getChange().getAddrIdx()).getBech32AsString();
if(changeType == 44) {
HD_Address hd_addr = BIP84Util.getInstance(SendActivity.this).getWallet().getAccountAt(WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()).getChain(AddressFactory.CHANGE_CHAIN).getAddressAt(change_index);
String change_address = hd_addr.getAddressString();
receivers.put(change_address, BigInteger.valueOf(_change));
}
else if(changeType == 49) {
HD_Address hd_addr = BIP84Util.getInstance(SendActivity.this).getWallet().getAccountAt(WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()).getChain(AddressFactory.CHANGE_CHAIN).getAddressAt(change_index);
SegwitAddress segwitAddress = new SegwitAddress(hd_addr.getECKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
String change_address = segwitAddress.getAddressAsString();
receivers.put(change_address, BigInteger.valueOf(_change));
}
else {
String change_address = BIP84Util.getInstance(SendActivity.this).getAddressAt(WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix(), AddressFactory.CHANGE_CHAIN, change_index).getBech32AsString();
receivers.put(change_address, BigInteger.valueOf(_change));
}
}
else if (changeType == 84) {
String change_address = BIP84Util.getInstance(SendActivity.this).getAddressAt(AddressFactory.CHANGE_CHAIN, change_index).getBech32AsString();
receivers.put(change_address, BigInteger.valueOf(_change));
} else if (changeType == 49) {
String change_address = BIP49Util.getInstance(SendActivity.this).getAddressAt(AddressFactory.CHANGE_CHAIN, BIP49Util.getInstance(SendActivity.this).getWallet().getAccount(0).getChange().getAddrIdx()).getAddressAsString();
}
else if (changeType == 49) {
String change_address = BIP49Util.getInstance(SendActivity.this).getAddressAt(AddressFactory.CHANGE_CHAIN, change_index).getAddressAsString();
receivers.put(change_address, BigInteger.valueOf(_change));
} else {
String change_address = HD_WalletFactory.getInstance(SendActivity.this).get().getAccount(0).getChange().getAddressAt(HD_WalletFactory.getInstance(SendActivity.this).get().getAccount(0).getChange().getAddrIdx()).getAddressString();
}
else {
String change_address = HD_WalletFactory.getInstance(SendActivity.this).get().getAccount(0).getChange().getAddressAt(change_index).getAddressString();
receivers.put(change_address, BigInteger.valueOf(_change));
}
......@@ -2035,13 +2056,16 @@ public class SendActivity extends SamouraiActivity {
if (account == WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix()) {
String change_address = BIP84Util.getInstance(SendActivity.this).getAddressAt(WhirlpoolMeta.getInstance(SendActivity.this).getWhirlpoolPostmix(), AddressFactory.CHANGE_CHAIN, AddressFactory.getInstance(SendActivity.this).getHighestPostChangeIdx()).getBech32AsString();
_receivers.put(change_address, BigInteger.valueOf(_change));
} else if (changeType == 84) {
}
else if (changeType == 84) {
String change_address = BIP84Util.getInstance(SendActivity.this).getAddressAt(AddressFactory.CHANGE_CHAIN, BIP84Util.getInstance(SendActivity.this).getWallet().getAccount(0).getChange().getAddrIdx()).getBech32AsString();
_receivers.put(change_address, BigInteger.valueOf(_change));
} else if (changeType == 49) {
}
else if (changeType == 49) {
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 {
}
else {
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));
}
......
......@@ -691,10 +691,33 @@ public class SendFactory {
}
if(account == WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()) {
int idx = AddressFactory.getInstance(context).getHighestPostChangeIdx();
String change_address = BIP84Util.getInstance(context).getAddressAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix(), AddressFactory.CHANGE_CHAIN, idx).getBech32AsString();
AddressFactory.getInstance(context).setHighestPostChangeIdx(idx + 1);
return change_address;
if((type == 44 || type == 49) && PrefsUtil.getInstance(context).getValue(PrefsUtil.USE_LIKE_TYPED_CHANGE, true) == true) {
debug("SendFactory", "change index:" + idx);
if(type == 49) {
HD_Address hd_addr = BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).getChain(AddressFactory.CHANGE_CHAIN).getAddressAt(idx);
SegwitAddress segwitAddress = new SegwitAddress(hd_addr.getECKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
String change_address = segwitAddress.getAddressAsString();
AddressFactory.getInstance(context).setHighestPostChangeIdx(idx + 1);
return change_address;
}
else {
HD_Address hd_addr = BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).getChain(AddressFactory.CHANGE_CHAIN).getAddressAt(idx);
String change_address = hd_addr.getAddressString();
AddressFactory.getInstance(context).setHighestPostChangeIdx(idx + 1);
return change_address;
}
}
else {
String change_address = BIP84Util.getInstance(context).getAddressAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix(), AddressFactory.CHANGE_CHAIN, idx).getBech32AsString();
AddressFactory.getInstance(context).setHighestPostChangeIdx(idx + 1);
return change_address;
}
}
else if(type == 84) {
String change_address = BIP84Util.getInstance(context).getAddressAt(AddressFactory.CHANGE_CHAIN, BIP84Util.getInstance(context).getWallet().getAccount(account).getChange().getAddrIdx()).getBech32AsString();
......@@ -737,17 +760,31 @@ public class SendFactory {
ecKey = addr.getECKey();
}
else if(Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
debug("SendFactory", "address type:" + "bip49");
HD_Address addr = BIP49Util.getInstance(context).getWallet().getAccount(0).getChain(Integer.parseInt(s[1])).getAddressAt(Integer.parseInt(s[2]));
ecKey = addr.getECKey();
if(account == WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()) {
debug("SendFactory", "address type:" + "post-mix p2sh");
HD_Address addr = BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).getChain(Integer.parseInt(s[1])).getAddressAt(Integer.parseInt(s[2]));
ecKey = addr.getECKey();
}
else {
debug("SendFactory", "address type:" + "bip49");
HD_Address addr = BIP49Util.getInstance(context).getWallet().getAccount(0).getChain(Integer.parseInt(s[1])).getAddressAt(Integer.parseInt(s[2]));
ecKey = addr.getECKey();
}
}
else {
debug("SendFactory", "address type:" + "bip44");
int account_no = APIFactory.getInstance(context).getUnspentAccounts().get(address);
HD_Address hd_address = AddressFactory.getInstance(context).get(account_no, Integer.parseInt(s[1]), Integer.parseInt(s[2]));
String strPrivKey = hd_address.getPrivateKeyString();
DumpedPrivateKey pk = new DumpedPrivateKey(SamouraiWallet.getInstance().getCurrentNetworkParams(), strPrivKey);
ecKey = pk.getKey();
if(account == WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()) {
debug("SendFactory", "address type:" + "post-mix p2pkh");
HD_Address hd_addr = BIP84Util.getInstance(context).getWallet().getAccountAt(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).getChain(Integer.parseInt(s[1])).getAddressAt(Integer.parseInt(s[2]));
ecKey = hd_addr.getECKey();
}
else {
debug("SendFactory", "address type:" + "bip44");
int account_no = APIFactory.getInstance(context).getUnspentAccounts().get(address);
HD_Address hd_address = AddressFactory.getInstance(context).get(account_no, Integer.parseInt(s[1]), Integer.parseInt(s[2]));
String strPrivKey = hd_address.getPrivateKeyString();
DumpedPrivateKey pk = new DumpedPrivateKey(SamouraiWallet.getInstance().getCurrentNetworkParams(), strPrivKey);
ecKey = pk.getKey();
}
}
}
else {
......
......@@ -131,6 +131,18 @@ class SettingsDetailsFragment(private val key: String?) : PreferenceFragmentComp
true
}
val zpubPostXPref = findPreference("zpub_post_x") as Preference?
zpubPostXPref!!.onPreferenceClickListener = Preference.OnPreferenceClickListener {
getXPUB(44, WhirlpoolMeta.getInstance(requireContext()).whirlpoolPostmix)
true
}
val zpubPostYPref = findPreference("zpub_post_y") as Preference?
zpubPostYPref!!.onPreferenceClickListener = Preference.OnPreferenceClickListener {
getXPUB(49, WhirlpoolMeta.getInstance(requireContext()).whirlpoolPostmix)
true
}
val zpubBadBankPref = findPreference("zpub_badbank") as Preference?
zpubBadBankPref!!.onPreferenceClickListener = Preference.OnPreferenceClickListener {
getXPUB(84, WhirlpoolMeta.getInstance(requireContext()).whirlpoolBadBank)
......@@ -474,17 +486,31 @@ class SettingsDetailsFragment(private val key: String?) : PreferenceFragmentComp
private fun getXPUB(purpose: Int, account: Int) {
var xpub = ""
when (purpose) {
49 -> xpub = BIP49Util.getInstance(requireContext()).wallet.getAccount(account).ypubstr()
84 -> xpub = BIP84Util.getInstance(requireContext()).wallet.getAccountAt(account).zpubstr()
else -> try {
xpub = HD_WalletFactory.getInstance(requireContext()).get().getAccount(account).xpubstr()
} catch (ioe: IOException) {
ioe.printStackTrace()
Toast.makeText(requireContext(), "HD wallet error", Toast.LENGTH_SHORT).show()
} catch (mle: MnemonicLengthException) {
mle.printStackTrace()
Toast.makeText(requireContext(), "HD wallet error", Toast.LENGTH_SHORT).show()
if((purpose == 44 || purpose == 49) && account == WhirlpoolMeta.getInstance(context).whirlpoolPostmix) {
var vpub = BIP84Util.getInstance(requireContext()).wallet.getAccountAt(WhirlpoolMeta.getInstance(context).whirlpoolPostmix).zpubstr()
if(purpose == 49) {
xpub = FormatsUtil.xlatXPUB(vpub, true);
}
else {
xpub = FormatsUtil.xlatXPUB(vpub, false);
}
}
else {
when (purpose) {
49 -> xpub = BIP49Util.getInstance(requireContext()).wallet.getAccount(account).ypubstr()
84 -> xpub = BIP84Util.getInstance(requireContext()).wallet.getAccountAt(account).zpubstr()
else -> try {
xpub = HD_WalletFactory.getInstance(requireContext()).get().getAccount(account).xpubstr()
} catch (ioe: IOException) {
ioe.printStackTrace()
Toast.makeText(requireContext(), "HD wallet error", Toast.LENGTH_SHORT).show()
} catch (mle: MnemonicLengthException) {
mle.printStackTrace()
Toast.makeText(requireContext(), "HD wallet error", Toast.LENGTH_SHORT).show()
}
}
}
......@@ -497,7 +523,15 @@ class SettingsDetailsFragment(private val key: String?) : PreferenceFragmentComp
when (account) {
WhirlpoolAccount.POSTMIX.accountIndex -> {
dialogTitle = "Whirlpool Post-mix ZPUB"
if(purpose == 49){
dialogTitle = "Whirlpool Post-mix YPUB"
}
else if(purpose == 44){
dialogTitle = "Whirlpool Post-mix XPUB"
}
else{
dialogTitle = "Whirlpool Post-mix ZPUB"
}
}
WhirlpoolAccount.PREMIX.accountIndex -> {
dialogTitle = "Whirlpool Pre-mix ZPUB"
......
......@@ -4,14 +4,19 @@ import android.content.Context;
import com.samourai.wallet.SamouraiWallet;
import org.bitcoinj.core.AddressFormatException;
import org.bitcoinj.core.Base58;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.utils.BtcFixedFormat;
import org.bitcoinj.utils.BtcFormat;
import org.bitcoinj.utils.MonetaryFormat;
import java.nio.ByteBuffer;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Arrays;
import java.util.Locale;
public class FormatsUtil extends FormatsUtilGeneric {
......@@ -91,4 +96,54 @@ public class FormatsUtil extends FormatsUtilGeneric {
format.setMinimumFractionDigits(fractions);
return format.format(sats / 1e8);
}
public static String xlatXPUB(String xpub, boolean toSegwit) throws AddressFormatException {
byte[] xpubBytes = Base58.decodeChecked(xpub);
ByteBuffer bb = ByteBuffer.wrap(xpubBytes);
int ver = bb.getInt();
if(ver != MAGIC_XPUB && ver != MAGIC_TPUB && ver != MAGIC_YPUB && ver != MAGIC_UPUB && ver != MAGIC_ZPUB && ver != MAGIC_VPUB) {
throw new AddressFormatException("invalid xpub version");
}
int xlatVer = 0;
switch(ver) {
case FormatsUtilGeneric.MAGIC_XPUB:
xlatVer = toSegwit ? MAGIC_ZPUB : MAGIC_YPUB;
break;
case FormatsUtilGeneric.MAGIC_YPUB:
xlatVer = MAGIC_XPUB;
break;
case FormatsUtilGeneric.MAGIC_TPUB:
xlatVer = toSegwit ? MAGIC_VPUB : MAGIC_UPUB;
break;
case FormatsUtilGeneric.MAGIC_UPUB:
xlatVer = MAGIC_TPUB;
break;
case FormatsUtilGeneric.MAGIC_ZPUB:
xlatVer = toSegwit ? MAGIC_YPUB : MAGIC_XPUB;
break;
case FormatsUtilGeneric.MAGIC_VPUB:
xlatVer = toSegwit ? MAGIC_UPUB : MAGIC_TPUB;
break;
}
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(xlatVer);
byte[] bVer = b.array();
System.arraycopy(bVer, 0, xpubBytes, 0, bVer.length);
// append checksum
byte[] checksum = Arrays.copyOfRange(Sha256Hash.hashTwice(xpubBytes), 0, 4);
byte[] xlatXpub = new byte[xpubBytes.length + checksum.length];
System.arraycopy(xpubBytes, 0, xlatXpub, 0, xpubBytes.length);
System.arraycopy(checksum, 0, xlatXpub, xlatXpub.length - 4, checksum.length);
String ret = Base58.encode(xlatXpub);
return ret;
}
}
\ No newline at end of file
......@@ -40,6 +40,10 @@
<string name="options_xpub84_premix2">Show extended public key for BIP84 Segwit account (Bech32) Whirlpool pre-mix.</string>
<string name="options_xpub84_postmix">Show Whirlpool post-mix ZPUB</string>
<string name="options_xpub84_postmix2">Show extended public key for BIP84 Segwit account (Bech32) Whirlpool post-mix.</string>
<string name="options_xpub44_postmix">Show Whirlpool post-mix change XPUB</string>
<string name="options_xpub44_postmix2">Show extended public key for BIP44 Whirlpool post-mix change account.</string>
<string name="options_xpub49_postmix">Show Whirlpool post-mix change YPUB</string>
<string name="options_xpub49_postmix2">Show extended public key for BIP49 Segwit account (P2SH-wrapped) Whirlpool post-mix change account.</string>
<string name="options_xpub84_badbank">Show Whirlpool bad bank ZPUB</string>
<string name="options_xpub84_badbank2">Show extended public key for BIP84 Segwit account (Bech32) Whirlpool bad bank.</string>
<string name="options_wipe">Secure erase wallet</string>
......@@ -738,6 +742,8 @@
<item>Ricochet Segwit</item>
<item>Whirlpool Segwit pre-mix</item>
<item>Whirlpool Segwit post-mix</item>
<item>Whirlpool Segwit post-mix BIP44 change address</item>
<item>Whirlpool Segwit post-mix BIP49 change address</item>
<item>Whirlpool Segwit bad bank</item>
</string-array>
......
......@@ -86,6 +86,24 @@
app:allowDividerAbove="true"
/>
<Preference
android:title="@string/options_xpub44_postmix"
android:summary="@string/options_xpub44_postmix2"
android:key="zpub_post_x"
app:iconSpaceReserved="false"
app:allowDividerBelow="true"
app:allowDividerAbove="true"
/>
<Preference
android:title="@string/options_xpub49_postmix"
android:summary="@string/options_xpub49_postmix2"
android:key="zpub_post_y"
app:iconSpaceReserved="false"
app:allowDividerBelow="true"
app:allowDividerAbove="true"
/>
<Preference
android:title="@string/options_xpub84_badbank"
android:summary="@string/options_xpub84_badbank2"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment