add disconnect function

This commit is contained in:
Michele Balistreri 2020-10-13 12:01:32 +02:00
parent 46b8387b14
commit 2f643b53f1
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
4 changed files with 45 additions and 15 deletions

View File

@ -13,6 +13,7 @@ import im.status.keycard.connect.data.PairingManager
import im.status.keycard.connect.data.SettingsManager
import im.status.keycard.connect.net.EthereumRPC
import im.status.keycard.connect.net.WalletConnect
import org.walletconnect.Session
@SuppressLint("StaticFieldLeak")
object Registry {
@ -52,7 +53,7 @@ object Registry {
value.add(0, KotlinJsonAdapterFactory())
}
fun init(activity: Activity, listener: ScriptListener) {
fun init(activity: Activity, listener: ScriptListener, sessionListener: Session.Callback) {
//TODO: remove this hack, it is needed now because KEthereum does not add the KotlinJsonAdapterFactory
moshiAddKotlin()
@ -70,6 +71,6 @@ object Registry {
cardManager.start()
ethereumRPC = EthereumRPC(settingsManager.rpcEndpoint)
walletConnect = WalletConnect(settingsManager.bip32Path, settingsManager.chainID)
walletConnect = WalletConnect(sessionListener, settingsManager.bip32Path, settingsManager.chainID)
}
}

View File

@ -44,8 +44,7 @@ import pm.gnosis.eip712.adapters.moshi.MoshiAdapter
import pm.gnosis.eip712.typedDataHash
import java.io.File
class WalletConnect(var bip32Path: String, var chainID: Long) : ExportKeyCommand.Listener, SignCommand.Listener, Session.Callback {
class WalletConnect(var sessionStatusListener : Session.Callback, var bip32Path: String, var chainID: Long) : ExportKeyCommand.Listener, SignCommand.Listener, Session.Callback {
private val scope = MainScope()
private val moshi = Moshi.Builder().build()
private val okHttpClient = OkHttpClient()
@ -56,12 +55,8 @@ class WalletConnect(var bip32Path: String, var chainID: Long) : ExportKeyCommand
private var signAction: (RecoverableSignature) -> Unit = this::nop
override fun onStatus(status: Session.Status) {
when (status) {
is Session.Status.Error -> println("WalletConnect Error")
is Session.Status.Approved -> println("WalletConnect Approved")
is Session.Status.Connected -> println("WalletConnect Connected")
is Session.Status.Disconnected -> println("WalletConnect Disconnected")
is Session.Status.Closed -> session = null
if (status == Session.Status.Closed) {
session = null
}
}
@ -94,7 +89,7 @@ class WalletConnect(var bip32Path: String, var chainID: Long) : ExportKeyCommand
private fun onCustomCall(call: Session.MethodCall.Custom) {
when(call.method) {
"personal_sign" -> runOnValidParam<String>(call, 0) { signText(call.id, it) }
"eth_signTypedData" -> { runOnValidParam<String>(call, 1) { @Suppress("UNCHECKED_CAST") signTypedData(call.id, it) } }
"eth_signTypedData" -> { runOnValidParam<String>(call, 1) { signTypedData(call.id, it) } }
"eth_signTransaction" -> { runOnValidParam<Map<*, *>>(call, 0) { signTransaction(call.id, toTransaction(toSendTransaction(call.id, it)), false)} }
"eth_sendRawTransaction" -> { runOnValidParam<String>(call, 0) { relayTX(call.id, it) } }
else -> session?.rejectRequest(call.id, 1L, "Not implemented")
@ -134,7 +129,7 @@ class WalletConnect(var bip32Path: String, var chainID: Long) : ExportKeyCommand
Registry.scriptExecutor.runScript(scriptWithAuthentication().plus(SignCommand(Registry.walletConnect, hash)))
}
signAction = { session?.approveRequest(requestId, "0x${it.r.toNoPrefixHexString()}${it.s.toNoPrefixHexString()}${encode((it.recId + 27).toByte())}") }
signAction = { session?.approveRequest(requestId, formatDataSignature(it)) }
val intent = Intent(Registry.mainActivity, SignMessageActivity::class.java).apply {
putExtra(SIGN_TEXT_MESSAGE, text)
@ -151,7 +146,7 @@ class WalletConnect(var bip32Path: String, var chainID: Long) : ExportKeyCommand
Registry.scriptExecutor.runScript(scriptWithAuthentication().plus(SignCommand(Registry.walletConnect, hash)))
}
signAction = { session?.approveRequest(requestId, "0x${it.r.toNoPrefixHexString()}${it.s.toNoPrefixHexString()}${encode((it.recId + 27).toByte())}") }
signAction = { session?.approveRequest(requestId, formatDataSignature(it)) }
val intent = Intent(Registry.mainActivity, SignMessageActivity::class.java).apply {
putExtra(SIGN_TEXT_MESSAGE, message)
@ -160,6 +155,8 @@ class WalletConnect(var bip32Path: String, var chainID: Long) : ExportKeyCommand
Registry.mainActivity.startActivityForResult(intent, REQ_WALLETCONNECT)
}
private fun formatDataSignature(sig: RecoverableSignature) : String = "0x${sig.r.toNoPrefixHexString()}${sig.s.toNoPrefixHexString()}${encode((sig.recId + 27).toByte())}"
private fun signTransaction(id: Long, tx: Transaction, send: Boolean) {
requestId = id
@ -227,11 +224,16 @@ class WalletConnect(var bip32Path: String, var chainID: Long) : ExportKeyCommand
Session.PeerMeta(name = "Keycard Connect")
)
session?.addCallback(Registry.walletConnect.sessionStatusListener)
session?.addCallback(Registry.walletConnect)
session?.init()
}
}
fun disconnect() {
session?.kill()
}
override fun onResponse(keyPair: BIP32KeyPair) {
scope.launch(Dispatchers.IO) {
val addr = keyPair.toEthereumAddress().toHexString()

View File

@ -6,6 +6,7 @@ import android.nfc.NfcAdapter
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.Button
import android.widget.ViewSwitcher
import androidx.appcompat.app.AppCompatActivity
import com.google.zxing.client.android.Intents
@ -14,9 +15,10 @@ import im.status.keycard.connect.R
import im.status.keycard.connect.Registry
import im.status.keycard.connect.card.*
import im.status.keycard.connect.data.*
import org.walletconnect.Session
import kotlin.reflect.KClass
class MainActivity : AppCompatActivity(), ScriptListener {
class MainActivity : AppCompatActivity(), ScriptListener, Session.Callback {
private lateinit var viewSwitcher: ViewSwitcher
override fun onCreate(savedInstanceState: Bundle?) {
@ -28,7 +30,7 @@ class MainActivity : AppCompatActivity(), ScriptListener {
inflater.inflate(R.layout.activity_nfc, viewSwitcher)
setContentView(viewSwitcher)
Registry.init(this, this)
Registry.init(this, this, this)
Registry.scriptExecutor.defaultScript = cardCheckupScript()
}
@ -77,6 +79,10 @@ class MainActivity : AppCompatActivity(), ScriptListener {
integrator.initiateScan()
}
fun disconnectWallet(@Suppress("UNUSED_PARAMETER") view: View) {
Registry.walletConnect.disconnect()
}
fun changePIN(@Suppress("UNUSED_PARAMETER") view: View) {
startCommand(ChangePINActivity::class)
}
@ -137,4 +143,24 @@ class MainActivity : AppCompatActivity(), ScriptListener {
Registry.walletConnect.connect(uri)
}
}
override fun onMethodCall(call: Session.MethodCall) {}
override fun onStatus(status: Session.Status) {
when (status) {
is Session.Status.Error, Session.Status.Closed, Session.Status.Disconnected -> walletConnectDisconnected()
is Session.Status.Connected, Session.Status.Approved -> walletConnectConnected()
}
}
private fun walletConnectConnected() {
val button = findViewById<Button>(R.id.walletConnectButton)
button.setOnClickListener(this::disconnectWallet)
button.text = getString(R.string.disconnect_wallet)
}
private fun walletConnectDisconnected() {
val button = findViewById<Button>(R.id.walletConnectButton)
button.setOnClickListener(this::connectWallet)
button.text = getString(R.string.connect_wallet)
}
}

View File

@ -44,4 +44,5 @@
<string name="reinstall_cash_checkbox">Install Cash applet</string>
<string name="reinstall_ndef_checkbox">Install NDEF applet</string>
<string name="reinstall_button">Select cap file and install</string>
<string name="disconnect_wallet">Disconnect</string>
</resources>