> For the complete documentation index, see [llms.txt](https://hinkal-team.gitbook.io/hinkal/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hinkal-team.gitbook.io/hinkal/hinkal-mobile-sdk/android/guides/transfers.md).

# Transfers

A private transfer sends tokens from your private balance to another Hinkal user's private balance (`private → private`). There is no public trace of sender, recipient, or amount. It runs server-side through a Hinkal relayer.

### Basic Transfer

```kotlin
val wei = Mobile.amountToWei(chainId, tokenAddress, "0.5")
val txHash = hinkal.transfer(
    chainId,
    "[\"$tokenAddress\"]",
    "[\"$wei\"]",
    recipientPrivateAddress,
    tokenAddress,   // feeToken
    "",             // feeStructureJSON
)
```

### Parameters

| Parameter          | Type     | Description                             |
| ------------------ | -------- | --------------------------------------- |
| `chainID`          | `Long`   | Target chain id.                        |
| `tokenAddrsJSON`   | `String` | JSON array of token addresses.          |
| `amountsWeiJSON`   | `String` | JSON array of amounts in wei.           |
| `recipient`        | `String` | The recipient's Hinkal private address. |
| `feeToken`         | `String` | Token the relayer fee is paid in.       |
| `feeStructureJSON` | `String` | Fee quote, or empty for defaults.       |

### Recipient addresses

The recipient is a Hinkal private address. The recipient shares theirs via `getRecipientInfo`, and you can validate a value with `Mobile.isValidPrivateAddress(...)`:

```kotlin
if (!Mobile.isValidPrivateAddress(recipientPrivateAddress)) {
    // prompt the user to re-enter the address
    return
}
```

### Error Handling

```kotlin
try {
    val txHash = hinkal.transfer(chainId, "[\"$tokenAddress\"]", "[\"$wei\"]",
                                 recipientPrivateAddress, tokenAddress, "")
} catch (e: Exception) {
    Log.e("Hinkal", "Transfer failed: ${e.message}")
}
```

### Best Practices

#### 1. Validate the recipient

```kotlin
if (!Mobile.isValidPrivateAddress(recipient)) return
```

#### 2. Confirm the balance covers amount + fee

The fee is charged on top of the amount; ensure the private balance covers `amount + fee` (quote with the fee helpers on `Client`).
