-
Notifications
You must be signed in to change notification settings - Fork 87
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
CAIP-222/ReCaps #1272
CAIP-222/ReCaps #1272
Changes from 20 commits
6fde6cb
cfab8af
fddd7f3
ab8ad34
4aca1d5
4e2c5bc
64d19b6
7d6015c
95def21
63220ed
ccf8b71
960558b
7cb8e8e
eeec72b
caad190
cc07a33
cea30b0
ac843be
50ce3c0
343effd
59a3d48
ea45ebb
3702609
ac0494d
bf373a4
9d9a699
bd988cc
d04eece
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,14 @@ | |
import com.squareup.moshi.Json | ||
import com.squareup.moshi.JsonClass | ||
import com.walletconnect.android.cacao.SignatureInterface | ||
import com.walletconnect.android.internal.common.signing.cacao.Cacao.Payload.Companion.ACTION_DELIMITER | ||
import com.walletconnect.android.internal.common.signing.cacao.Cacao.Payload.Companion.ACTION_POSITION | ||
import com.walletconnect.android.internal.common.signing.cacao.Cacao.Payload.Companion.ACTION_TYPE_POSITION | ||
import com.walletconnect.android.internal.common.signing.cacao.Cacao.Payload.Companion.ATT_KEY | ||
import com.walletconnect.android.internal.common.signing.cacao.Cacao.Payload.Companion.RECAPS_PREFIX | ||
import com.walletconnect.android.internal.common.signing.signature.Signature | ||
import org.bouncycastle.util.encoders.Base64 | ||
import org.json.JSONObject | ||
|
||
@JsonClass(generateAdapter = true) | ||
data class Cacao( | ||
|
@@ -57,19 +64,30 @@ | |
@Json(name = "resources") | ||
val resources: List<String>?, | ||
) { | ||
val actionsString get() = getActionsString(Issuer(iss)) | ||
val methods get() = getActions(Issuer(iss)) | ||
|
||
companion object { | ||
const val CURRENT_VERSION = "1" | ||
const val ISO_8601_PATTERN = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" | ||
const val RECAPS_PREFIX = "urn:recap:" | ||
const val ATT_KEY = "att" | ||
const val ACTION_TYPE_POSITION = 0 | ||
const val ACTION_POSITION = 1 | ||
const val ACTION_DELIMITER = "/" | ||
} | ||
} | ||
} | ||
|
||
@JvmSynthetic | ||
internal fun Cacao.Signature.toSignature(): Signature = Signature.fromString(s) | ||
|
||
fun Cacao.Payload.toCAIP122Message(chainName: String = "Ethereum"): String { | ||
fun Cacao.Payload.toCAIP222Message(chainName: String = "Ethereum"): String { | ||
var message = "$domain wants you to sign in with your $chainName account:\n${Issuer(iss).address}\n\n" | ||
if (statement != null) message += "$statement\n" | ||
if (statement != null) message += "$statement" | ||
if (resources?.find { r -> r.startsWith(RECAPS_PREFIX) } != null) message += " I further authorize the stated URI to perform the following actions on my behalf: (1) $actionsString for '${ | ||
Issuer(iss).namespace | ||
}'\n" | ||
message += "\nURI: $aud\nVersion: $version\nChain ID: ${Issuer(iss).chainIdReference}\nNonce: $nonce\nIssued At: $iat" | ||
if (exp != null) message += "\nExpiration Time: $exp" | ||
if (nbf != null) message += "\nNot Before: $nbf" | ||
|
@@ -78,5 +96,29 @@ | |
message += "\nResources:" | ||
resources.forEach { resource -> message += "\n- $resource" } | ||
} | ||
|
||
return message | ||
} | ||
|
||
private fun Cacao.Payload.getActionsString(issuer: Issuer): String { | ||
return decodeReCaps(issuer).entries.joinToString(", ") { "'${it.key}': " + it.value.joinToString(", ") { value -> "'$value'" } } | ||
} | ||
|
||
private fun Cacao.Payload.getActions(issuer: Issuer): List<String> { | ||
return decodeReCaps(issuer).values.flatten() | ||
} | ||
|
||
private fun Cacao.Payload.decodeReCaps(issuer: Issuer): MutableMap<String, MutableList<String>> { | ||
val encodedReCaps = resources?.find { resource -> resource.startsWith(RECAPS_PREFIX) }?.removePrefix(RECAPS_PREFIX) ?: throw Exception() | ||
val reCaps = Base64.decode(encodedReCaps).toString(Charsets.UTF_8) | ||
val requests = (JSONObject(reCaps).get(ATT_KEY) as JSONObject).getJSONArray(issuer.namespace) | ||
val actions: MutableMap<String, MutableList<String>> = mutableMapOf() | ||
|
||
for (i in 0 until requests.length()) { | ||
val actionString = requests.getJSONObject(i).keys().next() as String | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. regarding the Qodana warning, can we just do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup |
||
val actionType = actionString.split(ACTION_DELIMITER)[ACTION_TYPE_POSITION] | ||
val action = actionString.split(ACTION_DELIMITER)[ACTION_POSITION] | ||
actions[actionType]?.add(action) ?: actions.put(actionType, mutableListOf(action)) | ||
} | ||
return actions | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please address lint warnings on this file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we still keep this for backwards compatibility?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's a new method that has changed during development