Documentation Index
Fetch the complete documentation index at: https://docs.privacyboost.io/llms.txt
Use this file to discover all available pages before exploring further.
Private Transfers
This guide covers sending tokens privately between privacy addresses.
Basic Transfer
do {
let result = try await sdk.send(
tokenAddress: "0x...token-address",
amount: "1000000000000000000", // 1 token
recipientPrivacyAddress: "0x04..." // 194-char privacy address
)
print("Transaction hash: \(result.txHash)")
} catch {
print("Transfer failed: \(error)")
}
Transfer Parameters
| Parameter | Type | Required | Description |
|---|
tokenAddress | String | Yes | Token contract address |
amount | String | Yes | Amount in wei (smallest unit) |
recipientPrivacyAddress | String | Yes | Recipient’s 194-character privacy address |
Transfer Result
struct TransferResult {
let txHash: String // Transaction hash
let fee: String // Fee paid (in wei)
}
Privacy Address Validation
Always validate privacy addresses before sending:
let recipientAddress = "0x04..."
guard sdk.isValidPrivacyAddress(recipientAddress) else {
print("Invalid privacy address")
return
}
let result = try await sdk.send(
tokenAddress: "0x...",
amount: "1000000000000000000",
recipientPrivacyAddress: recipientAddress
)
Looking Up Privacy Addresses
If you have a user’s MPK or Ethereum address, you can look up their privacy address:
do {
let identity = try await sdk.resolveIdentity(identifier: "0x...ethereum-address")
print("Privacy address: \(identity.privacyAddress)")
// Now send to their privacy address
let result = try await sdk.send(
tokenAddress: "0x...",
amount: "1000000000000000000",
recipientPrivacyAddress: identity.privacyAddress
)
} catch {
print("Address lookup failed: \(error)")
}
Checking Balance Before Transfer
func safeTransfer(
tokenAddress: String,
amount: String,
recipient: String
) async throws -> TransferResult {
let balance = try await sdk.getBalance(tokenAddress: tokenAddress)
guard let shielded = UInt64(balance.shieldedBalance),
let requested = UInt64(amount),
requested <= shielded else {
throw SDKError.insufficientBalance
}
return try await sdk.send(
tokenAddress: tokenAddress,
amount: amount,
recipientPrivacyAddress: recipient
)
}
Transfer Privacy
Private transfers provide:
- Sender Privacy: Your wallet address is not linked to the transaction
- Recipient Privacy: The recipient’s wallet address is not revealed
- Amount Privacy: The transfer amount is encrypted
- Relationship Privacy: No public link between sender and recipient
Only the sender and recipient can see the transfer details.
Error Handling
do {
let result = try await sdk.send(
tokenAddress: tokenAddress,
amount: amount,
recipientPrivacyAddress: recipient
)
} catch SDKError.insufficientBalance {
print("Not enough shielded balance")
} catch SDKError.invalidAddress {
print("Invalid privacy address")
} catch SDKError.invalidAmount {
print("Invalid amount")
} catch SDKError.walletError(let message) {
print("Wallet error: \(message)")
} catch SDKError.networkError(let message) {
print("Network error: \(message)")
} catch SDKError.transferError(let code, let message) {
print("Transfer error [\(code)]: \(message)")
} catch {
print("Transfer error: \(error)")
}
Best Practices
func validateTransfer(
tokenAddress: String,
amount: String,
recipient: String
) throws {
guard sdk.isValidAddress(tokenAddress) else {
throw SDKError.invalidAddress
}
guard sdk.isValidPrivacyAddress(recipient) else {
throw SDKError.invalidAddress
}
guard let value = UInt64(amount), value > 0 else {
throw SDKError.invalidAmount
}
}
2. Confirm Large Transfers
func transferWithConfirmation(
tokenAddress: String,
amount: String,
recipient: String,
onConfirm: (String) async -> Bool
) async throws -> TransferResult {
let formatted = try sdk.formatAmount(amount, decimals: 18)
guard await onConfirm("Send \(formatted) tokens to \(recipient.prefix(10))...?") else {
throw SDKError.signatureRejected
}
return try await sdk.send(
tokenAddress: tokenAddress,
amount: amount,
recipientPrivacyAddress: recipient
)
}
3. Handle Network Delays
func transferWithRetry(
tokenAddress: String,
amount: String,
recipient: String,
maxRetries: Int = 3
) async throws -> TransferResult {
for attempt in 1...maxRetries {
do {
return try await sdk.send(
tokenAddress: tokenAddress,
amount: amount,
recipientPrivacyAddress: recipient
)
} catch SDKError.networkError(_) where attempt < maxRetries {
try await Task.sleep(nanoseconds: UInt64(2_000_000_000 * attempt))
continue
}
}
throw SDKError.networkError("Max retries exceeded")
}
Next Steps