mirror of
https://github.com/status-im/keycard-connect.git
synced 2025-01-10 02:55:58 +00:00
start walletconnect integration
This commit is contained in:
parent
97f7b9256a
commit
4fd3dc530e
@ -9,7 +9,7 @@ android {
|
||||
buildToolsVersion "29.0.2"
|
||||
defaultConfig {
|
||||
applicationId "im.status.keycard.connect"
|
||||
minSdkVersion 23
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
@ -48,7 +48,12 @@ dependencies {
|
||||
implementation 'androidx.security:security-crypto:1.0.0-alpha02'
|
||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.64'
|
||||
implementation 'com.github.status-im.status-keycard-java:android:3.0.1'
|
||||
implementation "com.github.walletconnect:kotlin-walletconnect-lib:0.9.3"
|
||||
implementation 'com.github.walletconnect:kotlin-walletconnect-lib:0.9.3'
|
||||
implementation 'com.journeyapps:zxing-android-embedded:4.0.0'
|
||||
implementation 'com.google.zxing:core:3.4.0'
|
||||
implementation 'com.squareup.moshi:moshi:1.9.1'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.2.1'
|
||||
implementation 'com.squareup.moshi:moshi-kotlin:1.9.1'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
|
@ -10,13 +10,14 @@
|
||||
android:required="true" />
|
||||
|
||||
<application
|
||||
android:hardwareAccelerated="true"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".ui.PUKActivity"></activity>
|
||||
<activity android:name=".ui.PUKActivity" />
|
||||
<activity android:name=".ui.ChangePINActivity" />
|
||||
<activity android:name=".ui.InitActivity" />
|
||||
<activity android:name=".ui.PairingActivity" />
|
||||
|
@ -7,7 +7,9 @@ import im.status.keycard.android.NFCCardManager
|
||||
import im.status.keycard.connect.card.*
|
||||
import im.status.keycard.connect.data.PINCache
|
||||
import im.status.keycard.connect.data.PairingManager
|
||||
import im.status.keycard.connect.walletconnect.SessionManager
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
object Registry {
|
||||
lateinit var pinCache: PINCache
|
||||
private set
|
||||
@ -15,7 +17,9 @@ object Registry {
|
||||
lateinit var pairingManager: PairingManager
|
||||
private set
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
lateinit var mainActivity: Activity
|
||||
private set
|
||||
|
||||
lateinit var scriptExecutor: CardScriptExecutor
|
||||
private set
|
||||
|
||||
@ -25,15 +29,21 @@ object Registry {
|
||||
lateinit var nfcAdapter: NfcAdapter
|
||||
private set
|
||||
|
||||
lateinit var walletConnect: SessionManager
|
||||
|
||||
fun init(activity: Activity, listener: ScriptListener) {
|
||||
this.mainActivity = activity
|
||||
|
||||
pairingManager = PairingManager(activity)
|
||||
pinCache = PINCache()
|
||||
|
||||
nfcAdapter = NfcAdapter.getDefaultAdapter(activity)
|
||||
scriptExecutor = CardScriptExecutor(activity, listener)
|
||||
scriptExecutor = CardScriptExecutor(listener)
|
||||
|
||||
cardManager = NFCCardManager()
|
||||
cardManager.setCardListener(scriptExecutor)
|
||||
cardManager.start()
|
||||
|
||||
walletConnect = SessionManager()
|
||||
}
|
||||
}
|
@ -3,11 +3,12 @@ package im.status.keycard.connect.card
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import im.status.keycard.applet.KeycardCommandSet
|
||||
import im.status.keycard.connect.Registry
|
||||
import im.status.keycard.io.CardChannel
|
||||
import im.status.keycard.io.CardListener
|
||||
|
||||
class CardScriptExecutor(private val activity: Activity, private val listener: ScriptListener) : CardListener {
|
||||
class ScriptContext(val activity: Activity, val cmdSet: KeycardCommandSet)
|
||||
class CardScriptExecutor(private val listener: ScriptListener) : CardListener {
|
||||
data class ScriptContext(val activity: Activity, val cmdSet: KeycardCommandSet)
|
||||
|
||||
enum class State {
|
||||
READY, UX_ONGOING, RUNNING
|
||||
@ -20,7 +21,7 @@ class CardScriptExecutor(private val activity: Activity, private val listener: S
|
||||
private var waitingCmd: CardCommand? = null
|
||||
|
||||
override fun onConnected(channel: CardChannel) {
|
||||
val executionContext = ScriptContext(activity, KeycardCommandSet(channel))
|
||||
val executionContext = ScriptContext(Registry.mainActivity, KeycardCommandSet(channel))
|
||||
|
||||
if (state == State.READY) {
|
||||
startScript()
|
||||
|
@ -10,7 +10,7 @@ import androidx.security.crypto.EncryptedSharedPreferences
|
||||
import androidx.security.crypto.MasterKeys
|
||||
|
||||
class PairingManager(context: Context) {
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
private val sharedPreferences: SharedPreferences
|
||||
|
||||
private fun id(instanceUID: ByteArray) : String {
|
||||
return Base64.encodeToString(instanceUID, NO_PADDING or NO_WRAP)
|
||||
|
@ -8,11 +8,15 @@ import android.content.Intent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.ViewSwitcher
|
||||
import com.google.zxing.integration.android.IntentIntegrator
|
||||
import im.status.keycard.connect.R
|
||||
import im.status.keycard.connect.Registry
|
||||
import im.status.keycard.connect.card.*
|
||||
import im.status.keycard.connect.data.REQ_INTERACTIVE_SCRIPT
|
||||
import kotlin.reflect.KClass
|
||||
import androidx.core.app.ComponentActivity.ExtraData
|
||||
import androidx.core.content.ContextCompat.getSystemService
|
||||
import com.google.zxing.client.android.Intents
|
||||
|
||||
class MainActivity : AppCompatActivity(), ScriptListener {
|
||||
private lateinit var viewSwitcher: ViewSwitcher
|
||||
@ -43,8 +47,9 @@ class MainActivity : AppCompatActivity(), ScriptListener {
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
if (requestCode == REQ_INTERACTIVE_SCRIPT) {
|
||||
Registry.scriptExecutor.onUserInteractionReturned(resultCode, data)
|
||||
when (requestCode) {
|
||||
REQ_INTERACTIVE_SCRIPT -> Registry.scriptExecutor.onUserInteractionReturned(resultCode, data)
|
||||
IntentIntegrator.REQUEST_CODE -> qrCodeScanned(resultCode, data)
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,6 +69,13 @@ class MainActivity : AppCompatActivity(), ScriptListener {
|
||||
Registry.scriptExecutor.cancelScript()
|
||||
}
|
||||
|
||||
fun connectWallet(@Suppress("UNUSED_PARAMETER") view: View) {
|
||||
val integrator = IntentIntegrator(this)
|
||||
integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
|
||||
integrator.setOrientationLocked(false)
|
||||
integrator.initiateScan()
|
||||
}
|
||||
|
||||
fun changePIN(@Suppress("UNUSED_PARAMETER") view: View) {
|
||||
startCommand(ChangePINActivity::class)
|
||||
}
|
||||
@ -72,4 +84,14 @@ class MainActivity : AppCompatActivity(), ScriptListener {
|
||||
val intent = Intent(this, activity.java)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
private fun qrCodeScanned(resultCode: Int, data: Intent?) {
|
||||
if (resultCode != Activity.RESULT_OK || data == null) return
|
||||
|
||||
val uri: String? = data.getStringExtra(Intents.Scan.RESULT)
|
||||
|
||||
if (uri != null && uri.startsWith("wc:")) {
|
||||
Registry.walletConnect.connect(uri)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
package im.status.keycard.connect.walletconnect
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import im.status.keycard.connect.Registry
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.OkHttpClient
|
||||
import org.walletconnect.Session
|
||||
import org.walletconnect.Session.Config.Companion.fromWCUri
|
||||
import org.walletconnect.impls.*
|
||||
import java.io.File
|
||||
|
||||
class SessionManager {
|
||||
private val scope = MainScope()
|
||||
private val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
private val okHttpClient = OkHttpClient()
|
||||
private val sessionStore = FileWCSessionStore(File(Registry.mainActivity.filesDir, "wcSessions.json").apply { createNewFile() }, moshi)
|
||||
private var session: WCSession? = null
|
||||
|
||||
object SessionCB : Session.Callback {
|
||||
override fun onStatus(status: Session.Status) {
|
||||
println(status)
|
||||
}
|
||||
|
||||
override fun onMethodCall(call: Session.MethodCall) {
|
||||
println(call)
|
||||
}
|
||||
}
|
||||
|
||||
fun connect(uri: String) {
|
||||
scope.launch {
|
||||
session = WCSession(
|
||||
fromWCUri(uri),
|
||||
MoshiPayloadAdapter(moshi),
|
||||
sessionStore,
|
||||
OkHttpTransport.Builder(okHttpClient, moshi),
|
||||
Session.PeerMeta(name = "Keycard Connect")
|
||||
)
|
||||
|
||||
session?.addCallback(SessionCB)
|
||||
}
|
||||
}
|
||||
}
|
@ -9,13 +9,26 @@
|
||||
tools:context=".ui.MainActivity">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:id="@+id/changePINButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="48dp"
|
||||
android:onClick="changePIN"
|
||||
android:text="@string/change_pin"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.049"
|
||||
app:layout_constraintHorizontal_bias="0.532"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/walletConnectButton" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/walletConnectButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:onClick="connectWallet"
|
||||
android:text="@string/connect_wallet"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.553"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -12,4 +12,5 @@
|
||||
<string name="change_pin">Change PIN</string>
|
||||
<string name="puk_prompt" >Insert your PUK</string>
|
||||
<string name="nfc_prompt">Tap your card</string>
|
||||
<string name="connect_wallet" >Connect to WalletConnect</string>
|
||||
</resources>
|
||||
|
@ -8,7 +8,7 @@ buildscript {
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.1'
|
||||
classpath 'com.android.tools.build:gradle:3.5.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
Loading…
x
Reference in New Issue
Block a user