diff --git a/lib/src/main/java/com/circle/modularwallets/core/accounts/Account.kt b/lib/src/main/java/com/circle/modularwallets/core/accounts/Account.kt index 7fe292c..87d1e3e 100644 --- a/lib/src/main/java/com/circle/modularwallets/core/accounts/Account.kt +++ b/lib/src/main/java/com/circle/modularwallets/core/accounts/Account.kt @@ -35,16 +35,16 @@ abstract class Account { abstract fun getAddress(): String /** - * Signs the given hex data. + * Signs a given hash * * @param context The context in which the signing operation is performed. - * @param hex The hex data to sign. + * @param messageHash The hash to sign. * @return The signed data of type T. */ - abstract suspend fun sign(context: Context, hex: String): T + abstract suspend fun sign(context: Context, messageHash: String): T /** - * Signs the given message. + * Signs a given message. * * @param context The context in which the signing operation is performed. * @param message The message to sign. @@ -53,7 +53,7 @@ abstract class Account { abstract suspend fun signMessage(context: Context, message: String): T /** - * Signs the given typed data. + * Signs a given typed data. * * @param context The context in which the signing operation is performed. * @param typedData The typed data to sign. diff --git a/lib/src/main/java/com/circle/modularwallets/core/accounts/CircleSmartAccount.kt b/lib/src/main/java/com/circle/modularwallets/core/accounts/CircleSmartAccount.kt index b690ddb..4a7e7e7 100644 --- a/lib/src/main/java/com/circle/modularwallets/core/accounts/CircleSmartAccount.kt +++ b/lib/src/main/java/com/circle/modularwallets/core/accounts/CircleSmartAccount.kt @@ -32,10 +32,8 @@ import com.circle.modularwallets.core.clients.Client import com.circle.modularwallets.core.constants.CIRCLE_SMART_ACCOUNT_VERSION import com.circle.modularwallets.core.constants.CIRCLE_SMART_ACCOUNT_VERSION_V1 import com.circle.modularwallets.core.constants.CIRCLE_WEIGHTED_WEB_AUTHN_MULTISIG_PLUGIN -import com.circle.modularwallets.core.constants.EIP712_PREFIX import com.circle.modularwallets.core.constants.FACTORY import com.circle.modularwallets.core.constants.PUBLIC_KEY_OWN_WEIGHT -import com.circle.modularwallets.core.constants.REPLAY_SAFE_HASH_V1 import com.circle.modularwallets.core.constants.SALT import com.circle.modularwallets.core.constants.STUB_SIGNATURE import com.circle.modularwallets.core.constants.THRESHOLD_WEIGHT @@ -52,13 +50,9 @@ import com.circle.modularwallets.core.utils.NonceManagerSource import com.circle.modularwallets.core.utils.abi.encodeAbiParameters import com.circle.modularwallets.core.utils.abi.encodeCallData import com.circle.modularwallets.core.utils.abi.encodePacked -import com.circle.modularwallets.core.utils.data.concat import com.circle.modularwallets.core.utils.data.pad import com.circle.modularwallets.core.utils.data.slice -import com.circle.modularwallets.core.utils.encoding.bytesToHex import com.circle.modularwallets.core.utils.encoding.stringToHex -import com.circle.modularwallets.core.utils.encoding.toBytes -import com.circle.modularwallets.core.utils.encoding.toSha3Bytes import com.circle.modularwallets.core.utils.signature.hashMessage import com.circle.modularwallets.core.utils.signature.hashTypedData import com.circle.modularwallets.core.utils.signature.parseP256Signature @@ -74,7 +68,6 @@ import org.web3j.abi.datatypes.DynamicBytes import org.web3j.abi.datatypes.DynamicStruct import org.web3j.abi.datatypes.StaticStruct import org.web3j.abi.datatypes.Type -import org.web3j.abi.datatypes.Utf8String import org.web3j.abi.datatypes.generated.Bytes32 import org.web3j.abi.datatypes.generated.Uint256 import org.web3j.abi.datatypes.generated.Uint8 @@ -276,18 +269,17 @@ class CircleSmartAccount( } /** - * Signs the given hex data. + * Signs a hash via the Smart Account's owner. * * @param context The context used to launch framework UI flows ; use an activity context to make sure the UI will be launched within the same task stack. - * @param hex The hex data to sign. + * @param messageHash The hash to sign. * @return The signed data. */ @ExcludeFromGeneratedCCReport @Throws(Exception::class) - override suspend fun sign(context: Context, hex: String): String { - val digest = toSha3Bytes(hex) - val hash = UtilApiImpl.getReplaySafeMessageHash(client.transport, getAddress(), bytesToHex(digest)) - val signResult = owner.sign(context, hash) + override suspend fun sign(context: Context, messageHash: String): String { + val replaySafeMessageHash = UtilApiImpl.getReplaySafeMessageHash(client.transport, getAddress(), messageHash) + val signResult = owner.sign(context, replaySafeMessageHash) val signature = encodePackedForSignature( signResult, owner.getAddress(), @@ -297,7 +289,7 @@ class CircleSmartAccount( } /** - * Signs the given message. + * Signs a [EIP-191 Personal Sign message](https://eips.ethereum.org/EIPS/eip-191). * * @param context The context used to launch framework UI flows ; use an activity context to make sure the UI will be launched within the same task stack. * @param message The message to sign. @@ -306,9 +298,9 @@ class CircleSmartAccount( @ExcludeFromGeneratedCCReport @Throws(Exception::class) override suspend fun signMessage(context: Context, message: String): String { - val digest = toSha3Bytes(hashMessage(message.toByteArray())) - val hash = UtilApiImpl.getReplaySafeMessageHash(client.transport, getAddress(), bytesToHex(digest)) - val signResult = owner.sign(context, hash) + val hashedMessage = hashMessage(message.toByteArray()) + val replaySafeMessageHash = UtilApiImpl.getReplaySafeMessageHash(client.transport, getAddress(), hashedMessage) + val signResult = owner.sign(context, replaySafeMessageHash) val signature = encodePackedForSignature( signResult, owner.getAddress(), @@ -327,9 +319,9 @@ class CircleSmartAccount( @ExcludeFromGeneratedCCReport @Throws(Exception::class) override suspend fun signTypedData(context: Context, typedData: String): String { - val digest = toSha3Bytes(hashTypedData(typedData)) - val hash = UtilApiImpl.getReplaySafeMessageHash(client.transport, getAddress(), bytesToHex(digest)) - val signResult = owner.sign(context, hash) + val hashedTypedData = hashTypedData(typedData) + val replaySafeMessageHash = UtilApiImpl.getReplaySafeMessageHash(client.transport, getAddress(), hashedTypedData) + val signResult = owner.sign(context, replaySafeMessageHash) val signature = encodePackedForSignature( signResult, owner.getAddress(), @@ -339,7 +331,7 @@ class CircleSmartAccount( } /** - * Signs the given user operation. + * Signs a given user operation. * * @param context The context used to launch framework UI flows ; use an activity context to make sure the UI will be launched within the same task stack. * @param chainId The chain ID for the user operation. Default is the chain ID of the client. diff --git a/lib/src/main/java/com/circle/modularwallets/core/accounts/SmartAccount.kt b/lib/src/main/java/com/circle/modularwallets/core/accounts/SmartAccount.kt index 34ba2b6..d421cae 100644 --- a/lib/src/main/java/com/circle/modularwallets/core/accounts/SmartAccount.kt +++ b/lib/src/main/java/com/circle/modularwallets/core/accounts/SmartAccount.kt @@ -79,16 +79,16 @@ abstract class SmartAccount(val client: Client, val entryPoint: EntryPoint) { abstract fun getStubSignature(userOp: T): String /** - * Signs the given hex data. + * Signs a hash via the Smart Account's owner. * * @param context The context in which the signing operation is performed. - * @param hex The hex data to sign. + * @param messageHash The hash to sign. * @return The signed data. */ - abstract suspend fun sign(context: Context, hex: String): String + abstract suspend fun sign(context: Context, messageHash: String): String /** - * Signs the given message. + * Signs a given message. * * @param context The context in which the signing operation is performed. * @param message The message to sign. @@ -97,7 +97,7 @@ abstract class SmartAccount(val client: Client, val entryPoint: EntryPoint) { abstract suspend fun signMessage(context: Context, message: String): String /** - * Signs the given typed data. + * Signs a given typed data. * * @param context The context in which the signing operation is performed. * @param typedData The typed data to sign. @@ -106,7 +106,7 @@ abstract class SmartAccount(val client: Client, val entryPoint: EntryPoint) { abstract suspend fun signTypedData(context: Context, typedData: String): String /** - * Signs the given user operation. + * Signs a given user operation. * * @param context The context in which the signing operation is performed. * @param chainId The chain ID for the user operation. Default is the chain ID of the client. diff --git a/lib/src/main/java/com/circle/modularwallets/core/accounts/WebAuthnAccount.kt b/lib/src/main/java/com/circle/modularwallets/core/accounts/WebAuthnAccount.kt index ee80b1d..84c1db8 100644 --- a/lib/src/main/java/com/circle/modularwallets/core/accounts/WebAuthnAccount.kt +++ b/lib/src/main/java/com/circle/modularwallets/core/accounts/WebAuthnAccount.kt @@ -60,17 +60,17 @@ open class WebAuthnAccount internal constructor(internal val credential: WebAuth } /** - * Signs the given hex data. + * Signs a given hash * * @param context The context used to launch framework UI flows ; use an activity context to make sure the UI will be launched within the same task stack. - * @param hex The hex data to sign. + * @param messageHash The hash to sign. * @return The result of the signing operation. * @throws BaseError if the credential request fails. */ @ExcludeFromGeneratedCCReport @Throws(Exception::class) - override suspend fun sign(context: Context, hex: String): SignResult { - val optionsAndJson = getRequestOptions(credential.rpId, credential.id, hex) + override suspend fun sign(context: Context, messageHash: String): SignResult { + val optionsAndJson = getRequestOptions(credential.rpId, credential.id, messageHash) val authRespJson = getSavedCredentials(context, optionsAndJson.second) val authResp = fromJson(authRespJson, AuthenticationCredential::class.java) ?: throw BaseError("credential request failed. Get null from json\n${authRespJson}") @@ -85,7 +85,7 @@ open class WebAuthnAccount internal constructor(internal val credential: WebAuth } /** - * Signs the given message. + * Signs a given message. * * @param context The context used to launch framework UI flows ; use an activity context to make sure the UI will be launched within the same task stack. * @param message The message to sign. @@ -100,7 +100,7 @@ open class WebAuthnAccount internal constructor(internal val credential: WebAuth } /** - * Signs the given typed data. + * Signs a given typed data. * * @param context The context used to launch framework UI flows ; use an activity context to make sure the UI will be launched within the same task stack. * @param typedData The typed data to sign. diff --git a/lib/src/main/java/com/circle/modularwallets/core/apis/util/UtilApi.kt b/lib/src/main/java/com/circle/modularwallets/core/apis/util/UtilApi.kt index 8aeac7a..e2e7fe9 100644 --- a/lib/src/main/java/com/circle/modularwallets/core/apis/util/UtilApi.kt +++ b/lib/src/main/java/com/circle/modularwallets/core/apis/util/UtilApi.kt @@ -18,7 +18,6 @@ package com.circle.modularwallets.core.apis.util -import com.circle.modularwallets.core.constants.CIRCLE_WEIGHTED_WEB_AUTHN_MULTISIG_PLUGIN import com.circle.modularwallets.core.transports.Transport import java.math.BigInteger @@ -52,7 +51,7 @@ internal interface UtilApi { suspend fun isValidSignature( transport: Transport, - message: String, + digest: String, signature: String, from: String, to: String diff --git a/lib/src/main/java/com/circle/modularwallets/core/apis/util/UtilApiImpl.kt b/lib/src/main/java/com/circle/modularwallets/core/apis/util/UtilApiImpl.kt index bad7789..659479a 100644 --- a/lib/src/main/java/com/circle/modularwallets/core/apis/util/UtilApiImpl.kt +++ b/lib/src/main/java/com/circle/modularwallets/core/apis/util/UtilApiImpl.kt @@ -27,7 +27,6 @@ import com.circle.modularwallets.core.transports.Transport import com.circle.modularwallets.core.utils.Logger import com.circle.modularwallets.core.utils.encoding.bytesToHex import com.circle.modularwallets.core.utils.encoding.hexToBigInteger -import com.circle.modularwallets.core.utils.encoding.toSha3Bytes import com.circle.modularwallets.core.utils.rpc.performJsonRpcRequest import org.web3j.abi.FunctionEncoder import org.web3j.abi.FunctionReturnDecoder @@ -117,15 +116,17 @@ internal object UtilApiImpl : UtilApi { @ExcludeFromGeneratedCCReport override suspend fun isValidSignature( transport: Transport, - message: String, + digest: String, signature: String, from: String, to: String ): Boolean { - val digest = toSha3Bytes(message) val function = Function( "isValidSignature", - listOf>(Bytes32(digest), DynamicBytes(Numeric.hexStringToByteArray(signature))), + listOf>( + Bytes32(Numeric.hexStringToByteArray(digest)), + DynamicBytes(Numeric.hexStringToByteArray(signature)) + ), listOf>( object : TypeReference() {}) ) @@ -133,8 +134,7 @@ internal object UtilApiImpl : UtilApi { Logger.d( msg = """ isValidSignature > call - Message: $message - Digest: ${bytesToHex(digest)} + Digest: $digest Signature: $signature From: $from To: $to @@ -142,6 +142,10 @@ internal object UtilApiImpl : UtilApi { ) val resp = call(transport, from, to, data) val decoded = FunctionReturnDecoder.decode(resp, function.outputParameters) + if (decoded.isEmpty()) { + Logger.w(msg = "Empty response from isValidSignature call") + return false + } return EIP1271_VALID_SIGNATURE.contentEquals(decoded[0].value as ByteArray) }