class SignerTest { init { System.loadLibrary("TrustWalletCore") } @Test fun testSignTransaction() { val privKey = "0x29692ef13269197f78b7b070a7bf6ae787f08b9bbee4503416b0f8d95836b286" val signWeb3 = signUsingWeb3j(web3J, privKey) val signTrustCore = signUsingWalletCore(privKey, web3J) println(signWeb3.toString()) println(signTrustCore.toString()) assertEquals( signTrustCore.v.toHex(), signWeb3.v.toHex(), ) } private val web3J = Transaction1559.createTransaction( /* chainId = */ 1, /* nonce = */ BigInteger("46"), /* gasLimit = */ BigInteger("25430"), /* to = */ "0xa358b8d0d382ee175c63e9a56f5b1806b8dfecc3", /* value = */ BigInteger("100000000000000"), /* data = */ "a1903eab0000000000000000000000000000000000000000000000000000000000000000", /* maxPriorityFeePerGas = */ BigInteger("90000000"), /* maxFeePerGas = */ BigInteger("31110000000") ) private fun signUsingWeb3j( transaction: Transaction1559, privateKey: String ): Sign.SignatureData { val credentials = Credentials.create(privateKey) val rawTransaction = RawTransaction.createTransaction( 1L, transaction.nonce, transaction.gasLimit, transaction.to, transaction.value, transaction.data, transaction.maxPriorityFeePerGas, transaction.maxFeePerGas ) val web3SignedMessage = TransactionEncoder.signMessage( rawTransaction, credentials ).toHexString() val signed = TransactionDecoder.decode( web3SignedMessage.prefixedValue ) as SignedRawTransaction return signed.signatureData } private fun signUsingWalletCore( privateKey: String, rawTransaction: Transaction1559 ): Ethereum.SigningOutput { val pk = PrivateKey(privateKey.fromHexToBytes()) val transferTransaction = Ethereum.Transaction .newBuilder() .apply { this.transfer = Ethereum.Transaction.Transfer .newBuilder() .apply { this.amount = rawTransaction.value.toByteString() if (rawTransaction.data != null) { this.data = rawTransaction.data.toHexByteString() } } .build() } .build() val signingInput = Ethereum.SigningInput.newBuilder().apply { this.privateKey = ByteString.copyFrom(pk.data()) this.chainId = BigInteger.ONE.toByteString() this.nonce = rawTransaction.nonce.toByteString() this.gasLimit = rawTransaction.gasLimit.toByteString() this.toAddress = rawTransaction.to this.txMode = Ethereum.TransactionMode.Enveloped this.maxInclusionFeePerGas = rawTransaction.maxPriorityFeePerGas.toByteString() this.maxFeePerGas = rawTransaction.maxFeePerGas.toByteString() this.transaction = transferTransaction }.build() val signResult = AnySigner.sign(signingInput, CoinType.ETHEREUM, Ethereum.SigningOutput.parser()) return signResult } private fun BigInteger.toByteString(): ByteString? { val bigIntHex = Numeric.toHexStringWithPrefix(this) return ByteString.copyFrom(Numeric.hexStringToByteArray(bigIntHex)) } private fun String.toHexByteString(): ByteString = ByteString.copyFrom(Numeric.hexStringToByteArray(this)) private fun ByteString.toHex(): String = Numeric.toHexString(this.toByteArray()) private fun ByteArray.toHex(): String = Numeric.toHexString(this) }