Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fake Wallet QR Code Scanner #1077

Merged
merged 1 commit into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions android/fakewallet/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ dependencies {
implementation libs.bcprov.jdk18on
implementation libs.kotlinx.coroutines.android
implementation libs.multimult
implementation libs.zxing.android.embedded
implementation project(path: ':walletlib')
kapt libs.androidx.room.compiler
}
8 changes: 8 additions & 0 deletions android/fakewallet/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.INTERNET" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.CAMERA"/>

<application
android:name=".FakeWalletApplication"
Expand All @@ -26,6 +30,10 @@
</intent-filter>
</activity>

<activity android:name=".ui.scanqr.ScanQRActivity"
android:theme="@style/Theme.MaterialComponents.DayNight.NoActionBar"
android:exported="false"/>

<activity
android:name=".MobileWalletAdapterActivity"
android:launchMode="singleTask"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

package com.solana.mobilewalletadapter.fakewallet

import androidx.appcompat.app.AppCompatActivity
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.solana.mobilewalletadapter.fakewallet.databinding.ActivityMainBinding
import com.solana.mobilewalletadapter.fakewallet.ui.scanqr.ScanQRActivity

class MainActivity : AppCompatActivity() {
private lateinit var viewBinding: ActivityMainBinding
Expand All @@ -16,5 +18,9 @@ class MainActivity : AppCompatActivity() {

viewBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(viewBinding.root)

viewBinding.buttonStartRemote.setOnClickListener {
startActivity(Intent(applicationContext, ScanQRActivity::class.java))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2025 Solana Mobile Inc.
*/

package com.solana.mobilewalletadapter.fakewallet.ui.scanqr

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.snackbar.Snackbar
import com.journeyapps.barcodescanner.BarcodeView
import com.solana.mobilewalletadapter.fakewallet.MobileWalletAdapterActivity
import com.solana.mobilewalletadapter.fakewallet.R
import com.solana.mobilewalletadapter.fakewallet.databinding.ActivityScanQrBinding
import com.solana.mobilewalletadapter.walletlib.association.RemoteAssociationUri

class ScanQRActivity : AppCompatActivity() {
private lateinit var viewBinding: ActivityScanQrBinding
private lateinit var barcodeView: BarcodeView

override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)

viewBinding = ActivityScanQrBinding.inflate(layoutInflater)
setContentView(viewBinding.root)

barcodeView = viewBinding.scannerViewFinder
}

override fun onResume() {
super.onResume()
barcodeView.resume()
decodeQRSingle()
}

public override fun onPause() {
super.onPause()
barcodeView.pauseAndWait()
}

private fun decodeQRSingle() {
barcodeView.decodeSingle { barcodeResult ->
println("Barcode Result = ${barcodeResult.text}")
runCatching {
val remoteAssociationUri = RemoteAssociationUri(Uri.parse(barcodeResult.text))
barcodeView.pause()

startActivity(
Intent(applicationContext, MobileWalletAdapterActivity::class.java)
.setData(remoteAssociationUri.uri))
}.getOrElse {
Snackbar.make(viewBinding.root, R.string.str_invalid_barcode, Snackbar.LENGTH_LONG).apply {
setAction(R.string.label_try_again) { dismiss() }
addCallback(object : Snackbar.Callback() {
override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
super.onDismissed(transientBottomBar, event)
decodeQRSingle()
}
})
show()
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<vector
android:width="540dp"
android:height="1200dp"
android:viewportWidth="540"
android:viewportHeight="1200">
<path
android:fillColor="#99000000"
android:pathData="M 0 0 L 0 1200 L 540 1200 L 540 0 L 0 0 z M 118 253.71484 L 422 253.71484 C 448.592 253.71484 470 275.12284 470 301.71484 L 470 605.71484 C 470 632.30684 448.592 653.71484 422 653.71484 L 118 653.71484 C 91.408 653.71484 70 632.30684 70 605.71484 L 70 301.71484 C 70 275.12284 91.408 253.71484 118 253.71484 z" />
</vector>
</item>
<item>
<vector
android:width="372dp"
android:height="372dp"
android:viewportWidth="540"
android:viewportHeight="1200">
<path
android:strokeWidth="12"
android:strokeLineCap="round"
android:strokeColor="@android:color/white"
android:pathData="m 415.19999,255.71459 c 29.2512,0 52.8,23.5488 52.8,52.8 m 0,290.39999 c 0,29.25119 -23.5488,52.8 -52.8,52.8 m -290.39998,0 c -29.2512,0 -52.799999,-23.54881 -52.799999,-52.8 m 0,-290.39999 c 0,-29.2512 23.5488,-52.8 52.799999,-52.8" />
</vector>
</item>
</layer-list>
11 changes: 11 additions & 0 deletions android/fakewallet/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
tools:context=".MainActivity">

<TextView
android:id="@+id/label_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_hello_world"
Expand All @@ -19,4 +20,14 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button_start_remote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_start_remote_connection"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/label_main" />

</androidx.constraintlayout.widget.ConstraintLayout>
39 changes: 39 additions & 0 deletions android/fakewallet/src/main/res/layout/activity_scan_qr.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2025 Solana Mobile Inc.
-->

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.scanqr.ScanQRActivity">

<com.journeyapps.barcodescanner.BarcodeView
android:id="@+id/scanner_view_finder"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/label_scanner_title"
app:layout_constraintBottom_toBottomOf="parent" />

<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/drawable_view_finder_cutout"/>

<TextView
android:id="@+id/label_scanner_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="400dp"
android:gravity="center"
android:textColor="@color/white"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:text="@string/str_scan_mwa_qr_code"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
6 changes: 6 additions & 0 deletions android/fakewallet/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

<!-- Main activity strings -->
<string name="label_hello_world">I\'m a wallet!</string>
<string name="label_start_remote_connection">Start Remote Connection</string>

<!-- Associate fragment strings -->
<string name="label_session_active">Session active, awaiting requests from dApp…</string>
Expand Down Expand Up @@ -62,4 +63,9 @@
work properly when the device battery save mode is active. Please turn off battery
saver or plug in your phone and try again.
</string>

<!-- Scan QR Code fragment strings -->
<string name="str_scan_mwa_qr_code">Scan MWA Connection QR Code</string>
<string name="str_invalid_barcode">Invalid QR Code</string>
<string name="label_try_again">Scan MWA Connection QR Code</string>
</resources>
2 changes: 2 additions & 0 deletions android/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ nvWebsocketClient = "2.14"
robolectric = "4.14.1"
slf4jAndroid = "1.7.36"
web3Core = "0.3.0-beta4"
zxingAndroidEmbedded = "4.3.0"

[libraries]
androidx-activity-ktx = { module = "androidx.activity:activity-ktx", version.ref = "androidxActivityKtx" }
Expand Down Expand Up @@ -80,6 +81,7 @@ nv-websocket-client = { module = "com.neovisionaries:nv-websocket-client", versi
robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" }
slf4j-android = { module = "org.slf4j:slf4j-android", version.ref = "slf4jAndroid" }
web3-solana = { module = "com.solanamobile:web3-solana", version.ref = "web3Core" }
zxing-android-embedded = { module = "com.journeyapps:zxing-android-embedded", version.ref = "zxingAndroidEmbedded" }

[plugins]
android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }
Expand Down
Loading