diff --git a/app/build.gradle b/app/build.gradle
index 19e47f47..482876ef 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -69,6 +69,7 @@ dependencies {
implementation 'androidx.camera:camera-camera2:1.0.0-beta03'
implementation 'androidx.camera:camera-lifecycle:1.0.0-beta03'
implementation 'androidx.camera:camera-view:1.0.0-alpha10'
+ implementation 'androidx.browser:browser:1.2.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'com.squareup.okhttp3:okhttp:4.4.1'
diff --git a/app/src/main/java/io/lbry/browser/ui/wallet/WalletFragment.java b/app/src/main/java/io/lbry/browser/ui/wallet/WalletFragment.java
index 38245035..c22a4109 100644
--- a/app/src/main/java/io/lbry/browser/ui/wallet/WalletFragment.java
+++ b/app/src/main/java/io/lbry/browser/ui/wallet/WalletFragment.java
@@ -6,8 +6,10 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Color;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.util.Base64;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -19,6 +21,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
+import androidx.browser.customtabs.CustomTabsIntent;
import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.DividerItemDecoration;
@@ -30,12 +33,20 @@ import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.android.material.textfield.TextInputEditText;
+import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.List;
import java.util.Locale;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
import io.lbry.browser.MainActivity;
import io.lbry.browser.R;
import io.lbry.browser.adapter.TransactionListAdapter;
@@ -57,6 +68,10 @@ import io.lbry.browser.utils.Lbryio;
public class WalletFragment extends BaseFragment implements SdkStatusListener, WalletBalanceListener {
+ private static final String MOONPAY_KEY = "c2tfbGl2ZV9ueVJqVXNDbE5pcnVSdnlCMkJLWW5JcFA5VnA3dWU=";
+ private static final String MOONPAY_URL_FORMAT =
+ "https://buy.moonpay.io?apiKey=pk_live_xNFffrN5NWKy6fu0ggbV8VQIwRieRzy&colorCode=%%232F9176¤cyCode=LBC&showWalletAddressForm=true&walletAddress=%s&externalCustomerId=%s";
+
private View layoutAccountRecommended;
private View layoutSdkInitializing;
private View linkSkipAccount;
@@ -75,6 +90,7 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
private View inlineBalanceContainer;
private TextView textWalletInlineBalance;
private MaterialButton buttonSignUp;
+ private MaterialButton buttonBuyLBC;
private RecyclerView recentTransactionsList;
private View linkViewAll;
private TextView textConvertCredits;
@@ -125,6 +141,7 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
recentTransactionsList = root.findViewById(R.id.wallet_recent_transactions_list);
linkViewAll = root.findViewById(R.id.wallet_link_view_all);
textNoRecentTransactions = root.findViewById(R.id.wallet_no_recent_transactions);
+ buttonBuyLBC = root.findViewById(R.id.wallet_buy_lbc_button);
textConvertCredits = root.findViewById(R.id.wallet_hint_convert_credits);
textConvertCreditsBittrex = root.findViewById(R.id.wallet_hint_convert_credits_bittrex);
textEarnMoreTips = root.findViewById(R.id.wallet_hint_earn_more_tips);
@@ -313,6 +330,13 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
}
});
+ buttonBuyLBC.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ launchMoonpayFlow();
+ }
+ });
+
inputSendAddress.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean hasFocus) {
@@ -481,6 +505,48 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
return sp.getBoolean(MainActivity.PREFERENCE_KEY_INTERNAL_SKIP_WALLET_ACCOUNT, false);
}
+ public void launchMoonpayFlow() {
+ Context context = getContext();
+ String receiveAddress = null;
+ if (context != null) {
+ try {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
+ receiveAddress = sp.getString(MainActivity.PREFERENCE_KEY_INTERNAL_WALLET_RECEIVE_ADDRESS, null);
+ if (Helper.isNullOrEmpty(receiveAddress)) {
+ showError(getString(R.string.receive_address_not_set));
+ return;
+ }
+
+ long userId = Lbryio.currentUser != null ? Lbryio.currentUser.getId() : 0;
+ String url = String.format(MOONPAY_URL_FORMAT, receiveAddress,
+ URLEncoder.encode(String.format("android-%d", userId), StandardCharsets.UTF_8.name()));
+ String email = Lbryio.getSignedInEmail();
+ if (!Helper.isNullOrEmpty(email)) {
+ url = String.format("%s&email=%s", url, URLEncoder.encode(email, StandardCharsets.UTF_8.name()));
+ }
+ // Sign the URL
+ String query = url.substring(url.indexOf("?"));
+ Mac hmacSHA256 = Mac.getInstance("HmacSHA256");
+
+ SecretKeySpec secretKey = new SecretKeySpec(
+ new String(Base64.decode(MOONPAY_KEY, Base64.NO_WRAP), StandardCharsets.UTF_8.name()).getBytes(), "HmacSHA256");
+ hmacSHA256.init(secretKey);
+ String signature = new String(
+ Base64.encode(hmacSHA256.doFinal(query.getBytes(StandardCharsets.UTF_8.name())), Base64.NO_WRAP),
+ StandardCharsets.UTF_8.name());
+ url = String.format("%s&signature=%s", url, URLEncoder.encode(signature, StandardCharsets.UTF_8.name()));
+
+ CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder().setToolbarColor(
+ ContextCompat.getColor(context, R.color.lbryGreen)
+ );
+ CustomTabsIntent intent = builder.build();
+ intent.launchUrl(context, Uri.parse(url));
+ } catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException ex) {
+ showError(getString(R.string.hash_not_supported));
+ }
+ }
+ }
+
public void onResume() {
super.onResume();
Context context = getContext();
diff --git a/app/src/main/res/layout/card_wallet_balance.xml b/app/src/main/res/layout/card_wallet_balance.xml
index 8e07d85f..550f8849 100644
--- a/app/src/main/res/layout/card_wallet_balance.xml
+++ b/app/src/main/res/layout/card_wallet_balance.xml
@@ -69,11 +69,22 @@
android:textFontWeight="300" />
+
+
Are you sure you want to unlock all your tips?
Please enter an amount more than 0.0001 credits.
+ Buy LBC
+ Your device does not support the minimum requirements for securing your purchase request.
+ You do not have a wallet address set. Please generate a new address and try again.
+
- You sent %1$s credit
- You sent %1$s credits