Skip to content

Commit

Permalink
get the tests cleaned up
Browse files Browse the repository at this point in the history
  • Loading branch information
nplasterer committed Oct 18, 2024
1 parent ff9c5cf commit 1e7f8d7
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.web3j.crypto.Credentials
import org.web3j.protocol.Web3j
import org.web3j.protocol.http.HttpService

@RunWith(AndroidJUnit4::class)
class SmartContractWalletTest {
Expand All @@ -21,12 +18,7 @@ class SmartContractWalletTest {
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
)
val context = InstrumentationRegistry.getInstrumentation().targetContext
val web3j = Web3j.build(HttpService("http://10.0.2.2:8545"))
Thread.sleep(1000L)

val credentials =
Credentials.create("ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
val davonSCW = FakeSCWWallet.generate(web3j, credentials)
val davonSCW = FakeSCWWallet.generate()
val options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
enableV3 = true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package org.xmtp.android.library

import android.util.Log
import com.google.protobuf.kotlin.toByteString
import kotlinx.coroutines.runBlocking
import org.web3j.abi.FunctionEncoder
import org.web3j.abi.datatypes.DynamicBytes
import org.web3j.abi.datatypes.Uint
import org.web3j.crypto.Credentials
import org.web3j.crypto.Hash
import org.web3j.crypto.Sign
import org.web3j.protocol.Web3j
import org.web3j.protocol.http.HttpService
import org.web3j.tx.gas.DefaultGasProvider
import org.web3j.utils.Numeric
import org.xmtp.android.library.artifact.CoinbaseSmartWallet
Expand All @@ -20,13 +18,10 @@ import org.xmtp.android.library.messages.PrivateKey
import org.xmtp.android.library.messages.PrivateKeyBuilder
import org.xmtp.android.library.messages.Signature
import org.xmtp.android.library.messages.Topic
import org.xmtp.android.library.messages.consentProofText
import org.xmtp.android.library.messages.ethHash
import org.xmtp.android.library.messages.toPublicKeyBundle
import org.xmtp.android.library.messages.walletAddress
import org.xmtp.proto.message.contents.SignatureOuterClass
import java.math.BigInteger
import java.security.SecureRandom
import java.util.Date

class FakeWallet : SigningKey {
Expand Down Expand Up @@ -59,19 +54,12 @@ class FakeWallet : SigningKey {
get() = privateKey.walletAddress
}

class FakeSCWWallet(
private val web3j: Web3j,
private val credentials: Credentials,
) : SigningKey {
class FakeSCWWallet : SigningKey {
private var web3j: Web3j = Web3j.build(HttpService("http://10.0.2.2:8545"))
private val credentials: Credentials =
Credentials.create("ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
var walletAddress: String = ""

init {
runBlocking {
createSmartContractWallet()
}
}

// Override address to return the created smart contract wallet address
override val address: String
get() = walletAddress

Expand All @@ -81,58 +69,37 @@ class FakeSCWWallet(
override var chainId: Long = 31337L

companion object {
fun generate(
web3j: Web3j,
credentials: Credentials,
): FakeSCWWallet {
return FakeSCWWallet(web3j, credentials).apply {
runBlocking { createSmartContractWallet() }
fun generate(): FakeSCWWallet {
return FakeSCWWallet().apply {
createSmartContractWallet()
}
}
}

override suspend fun sign(data: ByteArray): Signature {
override suspend fun signSmartContract(message: String): ByteArray {
val smartWallet = CoinbaseSmartWallet.load(
walletAddress,
web3j,
credentials,
DefaultGasProvider()
)

val replaySafeHash = smartWallet.replaySafeHash(data).send()
Log.d("LOPI1", replaySafeHash.toHex())
val digest = Signature.newBuilder().build().ethHash(message)
val replaySafeHash = smartWallet.replaySafeHash(digest).send()

val signature = Sign.signMessage(replaySafeHash, credentials.ecKeyPair, false)
val signatureBytes = signature.r + signature.s + signature.v
Log.d("LOPI2", signatureBytes.toHex())

val tokens = listOf(
Uint(BigInteger.ZERO),
DynamicBytes(signatureBytes)
)
val encoded = FunctionEncoder.encodeConstructor(tokens)
val encodedBytes = Numeric.hexStringToByteArray(encoded)
Log.d("LOPI3", encoded)

return SignatureOuterClass.Signature.newBuilder().also {
it.ecdsaCompact = it.ecdsaCompact.toBuilder().also { builder ->
builder.bytes = encodedBytes.toByteString()
}.build()
}.build()
}

override suspend fun sign(message: String): Signature {
val digest = Signature.newBuilder().build().ethHash(message)
return sign(digest)
}

private fun ByteArray.sha256(): ByteArray {
val digest = java.security.MessageDigest.getInstance("SHA-256")
return digest.digest(this)
return encodedBytes
}

private fun createSmartContractWallet() {
val smartWalletContract = CoinbaseSmartWallet.deploy(
val smartWalletContract = CoinbaseSmartWallet.deploy(
web3j,
credentials,
DefaultGasProvider()
Expand All @@ -154,7 +121,7 @@ class FakeSCWWallet(

val transactionReceipt = factory.createAccount(owners, nonce, BigInteger.ZERO).send()
val smartWalletAddress = factory.getAddress(owners, nonce).send()
Log.d("LOPI5", smartWalletAddress)

if (transactionReceipt.isStatusOK) {
walletAddress = smartWalletAddress
} else {
Expand All @@ -163,7 +130,6 @@ class FakeSCWWallet(
}
}


data class Fixtures(
val clientOptions: ClientOptions? = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, isSecure = false)
Expand Down
22 changes: 10 additions & 12 deletions library/src/main/java/org/xmtp/android/library/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ class Client() {
this.hasV2Client = false
val clientOptions = options ?: ClientOptions(enableV3 = true)
val accountAddress =
if (contractChainId != null) "eip155:${contractChainId}:${address.lowercase()}" else address.lowercase()
if (contractChainId != null) "eip155:$contractChainId:${address.lowercase()}" else address.lowercase()
return try {
initializeV3Client(accountAddress, clientOptions)
} catch (e: Exception) {
Expand Down Expand Up @@ -448,17 +448,15 @@ class Client() {
}
v3Client.signatureRequest()?.let { signatureRequest ->
if (account != null) {
account.sign(signatureRequest.signatureText())?.let {
if (account.isSmartContractWallet) {
Log.d("LOPI", it.ecdsaCompact.bytes.toByteArray().toHex())
Log.d("LOPI4", account.address)
signatureRequest.addScwSignature(
it.ecdsaCompact.bytes.toByteArray(),
account.address.lowercase(),
account.chainId.toULong(),
account.blockNumber?.toULong()
)
} else {
if (account.isSmartContractWallet) {
signatureRequest.addScwSignature(
account.signSmartContract(signatureRequest.signatureText()),
account.address.lowercase(),
account.chainId.toULong(),
account.blockNumber?.toULong()
)
} else {
account.sign(signatureRequest.signatureText())?.let {
signatureRequest.addEcdsaSignature(it.rawData)
}
}
Expand Down
12 changes: 10 additions & 2 deletions library/src/main/java/org/xmtp/android/library/SigningKey.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,17 @@ interface SigningKey {
get() = null
set(_) {}

suspend fun sign(data: ByteArray): SignatureOuterClass.Signature?
suspend fun sign(data: ByteArray): SignatureOuterClass.Signature? {
throw NotImplementedError("sign(ByteArray) is not implemented.")
}

suspend fun sign(message: String): SignatureOuterClass.Signature? {
throw NotImplementedError("sign(String) is not implemented.")
}

suspend fun sign(message: String): SignatureOuterClass.Signature?
suspend fun signSmartContract(message: String): ByteArray {
throw NotImplementedError("signSmartContract(String) is not implemented.")
}
}

/**
Expand Down

0 comments on commit 1e7f8d7

Please sign in to comment.