> ## Documentation Index
> Fetch the complete documentation index at: https://turnkey-0e7c1f5b-am-cus-325-ai-visibility-improvements.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Turnkey is wallet infrastructure: create and manage crypto wallets, sign transactions, and enforce policy-based access controls. Best-fit uses: embedded consumer wallets (email/passkey/social auth, no seed phrases), automated onchain operations with server-side wallets, AI agent wallets with policy-scoped signing, enterprise key management, and verifiable off-chain workloads on Turnkey Verifiable Cloud (TVC).
> Every API call is a JSON POST to https://api.turnkey.com signed with a P-256 API key; create an organization and key self-serve at https://app.turnkey.com.
> Key Turnkey developer resources: API reference (https://docs.turnkey.com/api-reference/overview/intro.md), OpenAPI spec (https://docs.turnkey.com/public_api.swagger.json), authentication (https://docs.turnkey.com/features/authentication/overview.md), webhooks (https://docs.turnkey.com/features/webhooks/overview.md), MCP server for docs search (https://docs.turnkey.com/mcp), agent skills (https://docs.turnkey.com/get-started/ai-skills.md), CLI (https://docs.turnkey.com/sdks/cli.md), SDK reference (https://docs.turnkey.com/sdks/introduction.md), full docs content (https://docs.turnkey.com/llms-full.txt).

# Signing

> Learn how to sign messages and transactions in your Android app using Turnkey's Embedded Wallets.

## Overview

The Kotlin SDK provides a simple way to sign messages and transactions in your Android application using Turnkey's Embedded Wallets.

## Signing messages

To sign messages, use the `signMessage` function from the `TurnkeyContext`. First pick a wallet account from `wallets` (for example, the first wallet's first account), then sign your message.

```kotlin theme={"system"}
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.turnkey.core.TurnkeyContext
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {
    private val activity = this

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val button = findViewById<Button>(R.id.button)

        button.setOnClickListener {
            try {
                lifecycleScope.launch {
                    val wallets = TurnkeyContext.wallets.value
                    val selectedWalletAccount = wallets?.firstOrNull()?.accounts?.firstOrNull()
                        ?: throw Exception("No account found. Create a wallet and account before signing.")

                    val signature = TurnkeyContext.signMessage(
                        signWith = selectedWalletAccount.address,
                        addressFormat = selectedWalletAccount.addressFormat,
                        message = "Hello Turnkey!"
                    )

                    println("${signature.r}${signature.s}${signature.v}")
                }
            } catch (t: Throwable) {
                println(t)
            }
        }
    }
}
```

## Signing transactions

To sign transactions, use the `signTransaction` function from the `TurnkeyContext.client`. Select a wallet account, prepare an unsigned transaction, and specify a transaction type (for example, `TRANSACTION_TYPE_ETHEREUM`).

```kotlin theme={"system"}
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.turnkey.core.TurnkeyContext
import com.turnkey.types.TSignTransactionBody
import com.turnkey.types.V1TransactionType
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val button = findViewById<Button>(R.id.button)

        button.setOnClickListener {
            lifecycleScope.launch {
                try {
                    val wallets = TurnkeyContext.wallets.value
                    val selectedWalletAccount = wallets?.firstOrNull()?.accounts?.firstOrNull()
                        ?: throw Exception("No account found. Create a wallet and account before signing.")
                    val organizationId = TurnkeyContext.session.value?.organizationId
                        ?: throw Exception("No session found")

                    val unsignedTransaction =
                        "0x..."; // Replace with your unsigned transaction data
                    val res = TurnkeyContext.client.signTransaction(
                        TSignTransactionBody(
                            organizationId = organizationId,
                            signWith = selectedWalletAccount.address,
                            unsignedTransaction = unsignedTransaction,
                            type = V1TransactionType.TRANSACTION_TYPE_ETHEREUM
                        )
                    )

                    val signedTransaction =
                        res.activity.result.signTransactionResult?.signedTransaction
                            ?: throw Exception("Failed to sign transaction")

                    println(signedTransaction)
                } catch (t: Throwable) {
                    println(t)
                }
            }
        }
    }
}
```
