mirror of
https://github.com/status-im/keycard-connect.git
synced 2025-02-27 18:10:28 +00:00
add sign interface
This commit is contained in:
parent
aad3a2bf9a
commit
503743d527
@ -10,13 +10,14 @@
|
||||
android:required="true" />
|
||||
|
||||
<application
|
||||
android:hardwareAccelerated="true"
|
||||
android:allowBackup="true"
|
||||
android:hardwareAccelerated="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.SignMessageActivity"></activity>
|
||||
<activity android:name=".ui.PUKActivity" />
|
||||
<activity android:name=".ui.ChangePINActivity" />
|
||||
<activity android:name=".ui.InitActivity" />
|
||||
|
@ -11,6 +11,9 @@ const val INIT_ACTIVITY_PIN = "initPIN"
|
||||
const val INIT_ACTIVITY_PUK = "initPUK"
|
||||
const val INIT_ACTIVITY_PAIRING = "initPairing"
|
||||
|
||||
const val SIGN_TEXT_MESSAGE = "signMessage"
|
||||
|
||||
const val REQ_INTERACTIVE_SCRIPT = 0x01
|
||||
const val REQ_WALLETCONNECT = 0x02
|
||||
|
||||
const val CACHE_VALIDITY = 15 * 60 * 1000
|
@ -17,6 +17,7 @@ import kotlin.reflect.KClass
|
||||
import androidx.core.app.ComponentActivity.ExtraData
|
||||
import androidx.core.content.ContextCompat.getSystemService
|
||||
import com.google.zxing.client.android.Intents
|
||||
import im.status.keycard.connect.data.REQ_WALLETCONNECT
|
||||
|
||||
class MainActivity : AppCompatActivity(), ScriptListener {
|
||||
private lateinit var viewSwitcher: ViewSwitcher
|
||||
@ -49,6 +50,7 @@ class MainActivity : AppCompatActivity(), ScriptListener {
|
||||
|
||||
when (requestCode) {
|
||||
REQ_INTERACTIVE_SCRIPT -> Registry.scriptExecutor.onUserInteractionReturned(resultCode, data)
|
||||
REQ_WALLETCONNECT -> Registry.walletConnect.onUserInteractionReturned(resultCode, data)
|
||||
IntentIntegrator.REQUEST_CODE -> qrCodeScanned(resultCode, data)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
package im.status.keycard.connect.ui
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import im.status.keycard.connect.R
|
||||
import im.status.keycard.connect.data.SIGN_TEXT_MESSAGE
|
||||
|
||||
class SignMessageActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_sign_message)
|
||||
val signText = findViewById<TextView>(R.id.signText)
|
||||
signText.text = intent.getStringExtra(SIGN_TEXT_MESSAGE)
|
||||
}
|
||||
|
||||
fun sign(@Suppress("UNUSED_PARAMETER") view: View) {
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
|
||||
fun reject(@Suppress("UNUSED_PARAMETER") view: View) {
|
||||
setResult(Activity.RESULT_CANCELED)
|
||||
finish()
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package im.status.keycard.connect.walletconnect
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import im.status.keycard.applet.BIP32KeyPair
|
||||
@ -8,6 +10,9 @@ import im.status.keycard.connect.Registry
|
||||
import im.status.keycard.connect.card.ExportKeyCommand
|
||||
import im.status.keycard.connect.card.SignCommand
|
||||
import im.status.keycard.connect.card.scriptWithAuthentication
|
||||
import im.status.keycard.connect.data.REQ_WALLETCONNECT
|
||||
import im.status.keycard.connect.data.SIGN_TEXT_MESSAGE
|
||||
import im.status.keycard.connect.ui.SignMessageActivity
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.OkHttpClient
|
||||
@ -30,6 +35,7 @@ class WalletConnect : ExportKeyCommand.Listener, SignCommand.Listener {
|
||||
private val sessionStore = FileWCSessionStore(File(Registry.mainActivity.filesDir, "wcSessions.json").apply { createNewFile() }, moshi)
|
||||
private var session: WCSession? = null
|
||||
private var requestId: Long = 0
|
||||
private var action: (data: Intent?) -> Unit = this::nop
|
||||
|
||||
private val sessionCB = object : Session.Callback {
|
||||
override fun onStatus(status: Session.Status) {
|
||||
@ -69,6 +75,10 @@ class WalletConnect : ExportKeyCommand.Listener, SignCommand.Listener {
|
||||
session?.rejectRequest(call.id, 1L, "Not implemented yet")
|
||||
}
|
||||
|
||||
"eth_signTransaction" -> {
|
||||
session?.rejectRequest(call.id, 1L, "Not implemented yet")
|
||||
}
|
||||
|
||||
"eth_sendRawTransaction" -> {
|
||||
session?.rejectRequest(call.id, 1L, "Not implemented yet")
|
||||
}
|
||||
@ -79,12 +89,34 @@ class WalletConnect : ExportKeyCommand.Listener, SignCommand.Listener {
|
||||
}
|
||||
|
||||
private fun signText(id: Long, message: String) {
|
||||
requestId = id
|
||||
val msg = Hex.decode(if (message.startsWith("0x", true)) message.drop(2) else message)
|
||||
val text = String(msg)
|
||||
|
||||
requestId = id
|
||||
action = {
|
||||
val keccak256 = Keccak.Digest256()
|
||||
val hash = keccak256.digest(byteArrayOf(0x19) + "Ethereum Signed Message:\n${msg.size}".toByteArray() + msg)
|
||||
Registry.scriptExecutor.runScript(scriptWithAuthentication().plus(SignCommand(Registry.walletConnect, hash)))
|
||||
}
|
||||
|
||||
val intent = Intent(Registry.mainActivity, SignMessageActivity::class.java).apply {
|
||||
putExtra(SIGN_TEXT_MESSAGE, text)
|
||||
}
|
||||
|
||||
Registry.mainActivity.startActivityForResult(intent, REQ_WALLETCONNECT)
|
||||
}
|
||||
}
|
||||
|
||||
private fun nop(@Suppress("UNUSED_PARAMETER") data: Intent?) { }
|
||||
|
||||
fun onUserInteractionReturned(resultCode: Int, data: Intent?) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
action.invoke(data)
|
||||
} else {
|
||||
session?.rejectRequest(requestId, -1, "Rejected by user")
|
||||
}
|
||||
|
||||
action = this::nop
|
||||
}
|
||||
|
||||
fun connect(uri: String) {
|
||||
@ -114,7 +146,6 @@ class WalletConnect : ExportKeyCommand.Listener, SignCommand.Listener {
|
||||
override fun onResponse(signature: RecoverableSignature) {
|
||||
scope.launch {
|
||||
session?.approveRequest(requestId, "0x${toHexString(signature.r)}${toHexString(signature.s)}${toHexString(byteArrayOf(signature.recId.toByte()))}")
|
||||
//session?.rejectRequest(requestId, -1, "Rejected by user")
|
||||
}
|
||||
}
|
||||
}
|
51
app/src/main/res/layout/activity_sign_message.xml
Normal file
51
app/src/main/res/layout/activity_sign_message.xml
Normal file
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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.SignMessageActivity">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/signTextLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="52dp"
|
||||
android:text="@string/sign_text_label"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.498"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/signButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="80dp"
|
||||
android:layout_marginEnd="68dp"
|
||||
android:onClick="sign"
|
||||
android:text="@string/sign_button"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/signText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/rejectButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="64dp"
|
||||
android:layout_marginTop="80dp"
|
||||
android:onClick="reject"
|
||||
android:text="@string/reject_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/signText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/signText"
|
||||
android:layout_width="306dp"
|
||||
android:layout_height="389dp"
|
||||
android:layout_marginTop="52dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.495"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/signTextLabel" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -10,7 +10,10 @@
|
||||
<string name="title_activity_change_pin">ChangePINActivity</string>
|
||||
<string name="change_pin_prompt">New PIN</string>
|
||||
<string name="change_pin">Change PIN</string>
|
||||
<string name="puk_prompt" >Insert your PUK</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>
|
||||
<string name="connect_wallet">Connect to WalletConnect</string>
|
||||
<string name="sign_button">Sign</string>
|
||||
<string name="reject_button">Reject</string>
|
||||
<string name="sign_text_label">Sign a message</string>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user