> ## 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.

# Api reference

# API Reference

Complete API reference for the Privacy Boost iOS SDK.

## Generated Documentation

Full API documentation can be generated using `cargo doc`:

```bash theme={null}
# From rust-sdk directory
make docs-rust

# iOS-specific docs
cargo doc --no-deps -p privacy-boost-ios
```

***

## PrivacyBoost

Main SDK class for iOS.

### Constructor

```swift theme={null}
init(config: PrivacyBoostConfig) throws
```

Creates a new SDK instance.

**Parameters:**

* `config` - SDK configuration

**Throws:** `SDKError.internalError` if initialization fails

### Properties

```swift theme={null}
var isConnected: Bool { get }
var isAuthenticated: Bool { get }
```

### Connection & Authentication Methods

#### authenticate

```swift theme={null}
func authenticate(wallet: WalletDelegate, keySource: KeySource? = nil, tokenProvider: TokenProvider? = nil) async throws -> AuthResult
```

Connect a wallet, derive privacy keys, and authenticate with the Privacy Boost backend in a single call.

**Parameters:**

* `wallet` - Implementation of `WalletDelegate` protocol
* `keySource` - Optional key derivation source. If `nil` and no persistence is configured, defaults to `.walletDerived`. If `nil` with persistence configured and no existing vault, an error is thrown.
* `tokenProvider` - Optional custom token provider. If `nil`, the SDK sends the login payload directly to the Privacy Boost backend. Supply a `TokenProvider` to route authentication through your own server.

**Returns:** `AuthResult` - either `.authenticated(LoginResult)` or `.credentialRequired(CredentialChallenge)`

**Throws:**

* `SDKError.walletError` if signing fails
* `SDKError.invalidConfig` if configuration is invalid or keySource is required but missing
* `SDKError.networkError` if backend unreachable

#### submitCredential

```swift theme={null}
func submitCredential(_ credential: String, tokenProvider: TokenProvider? = nil) async throws -> LoginResult
```

Submit a credential when `authenticate()` returns `.credentialRequired`.

**Parameters:**

* `credential` - The credential string
* `tokenProvider` - Optional custom token provider for routing authentication through your own server

**Returns:** `LoginResult` with privacy address and MPK

#### logout

```swift theme={null}
func logout()
```

End session completely, clear all state.

#### clearSession

```swift theme={null}
func clearSession()
```

Clear JWT only, keep keys for quick re-auth.

### State Accessors

```swift theme={null}
func getPrivacyAddress() -> String?
func getMpk() -> String?
func getWalletAddress() -> String?
```

### Balance Methods

#### getBalance

```swift theme={null}
func getBalance(tokenAddress: String) async throws -> TokenBalance
```

Get balance for a specific token.

**Parameters:**

* `tokenAddress` - ERC-20 token contract address

**Returns:** `TokenBalance` with shielded and wallet amounts

#### getAllBalances

```swift theme={null}
func getAllBalances() async throws -> [TokenBalance]
```

Get all token balances.

### Vault Operations

#### deposit

```swift theme={null}
func shield(tokenAddress: String, amount: String) async throws -> ShieldResult
```

Deposit tokens into the shielded pool.

**Parameters:**

* `tokenAddress` - Token contract address
* `amount` - Amount in wei (as string)

**Returns:** `ShieldResult` with transaction hash

#### withdraw

```swift theme={null}
func unshield(tokenAddress: String, amount: String, recipient: String) async throws -> UnshieldResult
```

Withdraw tokens from the shielded pool.

**Parameters:**

* `tokenAddress` - Token contract address
* `amount` - Amount in wei (as string)
* `recipient` - Recipient Ethereum address

**Returns:** `UnshieldResult` with transaction hash

#### send

```swift theme={null}
func send(tokenAddress: String, amount: String, recipientPrivacyAddress: String) async throws -> TransferResult
```

Send a private transfer.

**Parameters:**

* `tokenAddress` - Token contract address
* `amount` - Amount in wei (as string)
* `recipientPrivacyAddress` - Recipient's 194-char privacy address

**Returns:** `TransferResult` with transaction hash

#### prepareShield

```swift theme={null}
func prepareShield(tokenAddress: String, amount: String, recipient: String?) async throws -> PreparedShield
```

Build a deposit payload **without submitting it** — for callers that relay the
transaction themselves (a gasless relayer, an EIP-7702 session key, or a plain
raw transaction). Returns the calldata to relay plus the note commitment;
nothing is sent on-chain and no wallet is used. After relaying, pass the mined
receipt to the top-level `finalizeShield(...)` to recover the on-chain request
id.

**Parameters:**

* `tokenAddress` - Token contract address (zero address = native ETH)
* `amount` - Amount in wei (as string)
* `recipient` - (Optional) recipient privacy address. Pass `nil` to shield to yourself.

**Returns:** `PreparedShield` with the calls to relay and the note commitment

### Transaction History

```swift theme={null}
func getTransactionHistory(
    txType: String?,
    tokenAddress: String?,
    limit: UInt32?
) async throws -> [Transaction]
```

Get transaction history.

**Parameters:**

* `txType` - Filter by type: "deposit", "withdraw", "transfer"
* `tokenAddress` - Filter by token
* `limit` - Maximum results

### Session Persistence

#### exportSession

```swift theme={null}
func exportSession() -> ExportedSession?
```

Export session data for persistence.

**Returns:** `ExportedSession` or `nil` if not authenticated

#### importSession

```swift theme={null}
func importSession(_ session: ExportedSession) throws -> Bool
```

Import a previously exported session.

**Returns:** `true` if session is valid and imported

### Address Lookup

#### resolveIdentity

```swift theme={null}
func resolveIdentity(identifier: String) async throws -> IdentityResult
```

Look up a user's privacy address by MPK or Ethereum address.

**Parameters:**

* `identifier` - MPK or Ethereum address

**Returns:** `IdentityResult` with privacy address and public keys

### Utilities

```swift theme={null}
func isValidPrivacyAddress(_ address: String) -> Bool
func isValidAddress(_ address: String) -> Bool
func parseAmount(_ amount: String, decimals: UInt8) throws -> String
func formatAmount(_ wei: String, decimals: UInt8) throws -> String
```

***

## Module Functions

```swift theme={null}
func sdkVersion() -> String
func generateMnemonic() throws -> String
```

* `sdkVersion()` — Returns the SDK version string
* `generateMnemonic()` — Generates a random 12-word BIP-39 mnemonic

### Stateless shield helpers

Top-level functions for building a deposit payload without a signed-in session —
for a backend that holds only a recipient's privacy address. No wallet, no
private keys.

```swift theme={null}
func buildShieldPayload(
    tokenAddress: String,
    amount: String,
    recipient: String,
    tokenId: UInt16,
    shieldContractAddress: String,
    wethContractAddress: String?,
    teePublicKey: String,
    minShieldAmount: String?,
    emitApprove: Bool
) throws -> PreparedShield

func finalizeShield(
    receipt: TransactionReceipt,
    shieldContract: String,
    commitment: String
) throws -> ShieldResult
```

`buildShieldPayload` builds a recipient-targeted deposit payload from public
material only. Resolve `tokenId`, `shieldContractAddress`, and `teePublicKey`
from the token catalog / config. An ephemeral sender keypair is generated and
discarded internally, and the note is spendable only by `recipient`.
`wethContractAddress` is required only when shielding native ETH;
`minShieldAmount` (per-token minimum in wei) rejects below-minimum deposits;
`emitApprove` emits the ERC-20 approve call (pass `true` by default).

`finalizeShield` recovers the on-chain shield request id from the mined receipt
of a relayed deposit. Stateless — the caller obtained the receipt from its own
relay/RPC. Throws if the deposit reverted or the `DepositRequested` log is
absent.

***

## Types

### PrivacyBoostConfig

```swift theme={null}
struct PrivacyBoostConfig {
    let serverUrl: String
    let wethContractAddress: String
    let appId: String
    let chainId: UInt64?
    let shieldContractAddress: String?
    let teePublicKey: String?
}
```

| Field                   | Type    | Description                                                     |
| ----------------------- | ------- | --------------------------------------------------------------- |
| `serverUrl`             | String  | Privacy Boost server URL                                        |
| `wethContractAddress`   | String  | WETH contract address                                           |
| `appId`                 | String  | Application ID (required)                                       |
| `chainId`               | UInt64? | EIP-155 chain ID (optional, auto-discovered from server)        |
| `shieldContractAddress` | String? | Shield contract address (optional, auto-discovered from server) |
| `teePublicKey`          | String? | TEE public key for encryption (optional)                        |

### KeySource

```swift theme={null}
enum KeySource {
    case walletDerived
    case mnemonic(phrase: String)
    case rawSeed(hexSeed: String)
}
```

Specifies how privacy keys are derived. Passed as an optional parameter to `authenticate()`.

* **walletDerived** - Derive keys from a deterministic wallet signature (default when no persistence configured)
* **mnemonic** - Derive keys from a BIP-39 mnemonic phrase
* **rawSeed** - Derive keys from raw hex entropy (for testing)

### AuthResult

```swift theme={null}
enum AuthResult {
    case authenticated(LoginResult)
    case credentialRequired(CredentialChallenge)
}
```

### LoginResult

```swift theme={null}
struct LoginResult {
    let privacyAddress: String
    let mpk: String
}
```

### TokenBalance

```swift theme={null}
struct TokenBalance {
    let tokenAddress: String
    let shieldedBalance: String
    let walletBalance: String
    let symbol: String?
    let decimals: UInt8
}
```

### ShieldResult

Returned by `shield` and `finalizeShield`.

```swift theme={null}
struct ShieldResult {
    let txHash: String
    let commitment: String
    let warning: String?
    let requestId: String       // on-chain shield request id
    let wrapTxHash: String?     // present when native ETH was wrapped
}
```

### UnshieldResult

```swift theme={null}
struct UnshieldResult {
    let txHash: String
    let fee: String
}
```

### TransferResult

```swift theme={null}
struct TransferResult {
    let requestId: String
    let txHash: String
    let fee: String
    let giftRecord: GiftRecord? // populated by gift funding; persist to refund
    let claimLink: String?      // pbgift:v1:... — populated by gift funding
}
```

For an ordinary `send()`, `giftRecord` and `claimLink` are `nil`; they are
populated by the [gift funding methods](#gift-methods).

### Call

A single on-chain call to relay. `value` and `data` are 0x-hex.

```swift theme={null}
struct Call {
    let to: String
    let value: String
    let data: String
}
```

### PreparedShield

Returned by `prepareShield` and `buildShieldPayload`.

```swift theme={null}
struct ShieldFinalizeMeta {
    let shieldContract: String
    let tokenId: UInt16
}

struct PreparedShield {
    let approve: Call?   // ERC-20 approve(pool, amount); nil when managed out of band
    let wrap: Call?      // WETH deposit() wrap; present only when shielding native ETH
    let shield: Call     // the requestDeposit(...) call
    let commitment: String
    let finalize: ShieldFinalizeMeta
}
```

### TransactionReceipt

The mined-receipt record passed to `finalizeShield`.

```swift theme={null}
struct TransactionLog {
    let address: String
    let topics: [String]
    let data: String
}

struct TransactionReceipt {
    let txHash: String
    let status: Bool
    let logs: [TransactionLog]
}
```

### Transaction

```swift theme={null}
struct Transaction {
    let txHash: String
    let txType: String
    let tokenAddress: String
    let amount: String
    let direction: String
    let senderPubKey: String
    let receiverPubKeys: [String]
    let createdAt: UInt64
}
```

### IdentityResult

```swift theme={null}
struct IdentityResult {
    let mpk: String
    let ethereumAddress: String
    let viewingPublicKeyX: String
    let viewingPublicKeyY: String
    let privacyAddress: String
}
```

### ExportedSession

```swift theme={null}
struct ExportedSession {
    let version: UInt32
    let data: String
}
```

`data` is an opaque serialized core session. Store and pass it back unchanged;
do not parse or persist individual key fields.

***

## WalletDelegate Protocol

```swift theme={null}
protocol WalletDelegate: AnyObject {
    func getAddress() async throws -> String
    func getChainId() async throws -> UInt64
    func signMessage(message: String) async throws -> String
    func signTypedData(typedDataJson: String) async throws -> String
    func sendTransaction(toAddress: String, value: String, data: String) async throws -> String
    func waitForTransactionReceipt(txHash: String) async throws -> TransactionReceipt
}

struct TransactionLog {
    let address: String
    let topics: [String]
    let data: String
}

struct TransactionReceipt {
    let txHash: String
    let status: Bool
    let logs: [TransactionLog]
}
```

***

## TokenProvider Protocol

```swift theme={null}
protocol TokenProvider: AnyObject {
    func getToken(loginPayloadJson: String) async throws -> TokenResponse
}
```

Implement this protocol to route authentication through your own server. The SDK serializes the login payload as a JSON string and passes it to `getToken()`. Your implementation should forward this payload to your backend, which adds its own credentials and calls the Privacy Boost API.

### TokenResponse

```swift theme={null}
struct TokenResponse {
    let token: String      // JWT access token
    let expiresIn: UInt64  // Token lifetime in seconds
}
```

### Example

```swift theme={null}
class MyTokenProvider: TokenProvider {
    func getToken(loginPayloadJson: String) async throws -> TokenResponse {
        var request = URLRequest(url: URL(string: "https://your-server.com/api/privacy-auth")!)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = loginPayloadJson.data(using: .utf8)

        let (data, _) = try await URLSession.shared.data(for: request)
        let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
        return TokenResponse(
            token: json["token"] as! String,
            expiresIn: json["expiresIn"] as! UInt64
        )
    }
}

let result = try await sdk.authenticate(
    wallet: walletDelegate,
    tokenProvider: MyTokenProvider()
)
```

***

## SDKError

```swift theme={null}
enum SDKError: Error {
    case notConnected
    case notAuthenticated
    case authenticationFailed(message: String)
    case invalidConfig
    case configError(message: String)
    case networkError(message: String)
    case walletError(message: String)
    case signatureRejected
    case insufficientBalance(message: String)
    case invalidAddress
    case invalidAmount
    case invalidInput(message: String)
    case serializationError(message: String)
    case authServerError(code: String, message: String)
    case shieldError(code: String, message: String)
    case transferError(code: String, message: String)
    case noteError(code: String, message: String)
    case merkleError(code: String, message: String)
    case apiError(code: String, message: String, retryable: Bool)
    case rateLimited(retryAfterMs: UInt64)
    case forbidden(message: String)
    case resourceNotFound(message: String)
    case waitTimeout(requestId: String, waited: String)
    case transactionFailed(requestId: String, message: String)
    case internalError(message: String)
    case transactionReverted(message: String)
    case cryptoError(message: String)
    case stateError(message: String)
    case operationError(message: String)
}
```

***

## Gift Methods

Claimable transfers (gifts). See the
[Claimable Transfers guide](./guides/claimable-transfers) and the
[concept page](/sdk/concepts/claimable-transfers).

<Info>
  **Preview feature — pending external audit, and enabled per deployment.** These
  methods may not be present in the checked-in generated Swift bindings.
</Info>

Each fund/claim/refund method returns a `TransferResult` whose `giftRecord` and
`claimLink` fields are populated for gift operations.

#### giftFundToWallet

```swift theme={null}
func giftFundToWallet(
    tokenAddress: String,
    amount: String,
    recipientWallet: String,
    refundAfterBlock: UInt64,
    currentBlock: UInt64
) async throws -> TransferResult
```

Fund a gift bound to an Ethereum wallet address that may not be registered with
Privacy Boost.

**Parameters:**

* `tokenAddress` - Token contract address
* `amount` - Amount in wei (as string)
* `recipientWallet` - Recipient's Ethereum address the gift binds to
* `refundAfterBlock` - Block height after which an unclaimed gift may be reclaimed
* `currentBlock` - Current chain head; pre-validates the refund delay

**Returns:** `TransferResult` with `claimLink` and `giftRecord` populated

#### giftFund

```swift theme={null}
func giftFund(
    tokenAddress: String,
    amount: String,
    recipientPrivacyAddress: String,
    recipientWallet: String,
    refundAfterBlock: UInt64,
    currentBlock: UInt64
) async throws -> TransferResult
```

Fund a gift when the recipient is already a Privacy Boost user, sealing the
ciphertext to their viewing key. The argument label is `recipientPrivacyAddress`.

**Parameters:**

* `recipientPrivacyAddress` - Recipient's 194-char privacy address (the ciphertext's ECDH target)
* Other parameters as in `giftFundToWallet`

**Returns:** `TransferResult` with `claimLink` and `giftRecord` populated

#### giftClaim

```swift theme={null}
func giftClaim(index: UInt32, acknowledgeUnknownSender: Bool) async throws -> TransferResult
```

Claim a pending gift by its position in `getPendingGifts()`.

**Parameters:**

* `index` - Position in the pending-gifts list
* `acknowledgeUnknownSender` - Must be `true`; acknowledges accepting funds from an unknown sender

#### giftClaimByCGift

```swift theme={null}
func giftClaimByCGift(cGift: String, acknowledgeUnknownSender: Bool) async throws -> TransferResult
```

Claim a pending gift by its stable commitment `cGift` (preferred when the list
may shift as gifts settle).

#### giftClaimFromLink

```swift theme={null}
func giftClaimFromLink(link: String, acknowledgeUnknownSender: Bool) async throws -> TransferResult
```

Claim a gift directly from a `pbgift:v1:...` claim link, without a server lookup
first.

#### giftRefundByRecord

```swift theme={null}
func giftRefundByRecord(index: UInt32) async throws -> TransferResult
```

Refund an unclaimed gift after its deadline, using a local gift record. `index`
is the positional index into `getGiftRecords()`.

#### giftRefund

```swift theme={null}
func giftRefund(
    recipientWallet: String,
    blind: String,
    refundAfterBlock: UInt64,
    tokenId: UInt16,
    amount: String,
    fundingTreeNumber: UInt64,
    giftLeafIndex: UInt64
) async throws -> TransferResult
```

Refund an unclaimed gift by supplying every field manually — the fallback when
the local gift record is unavailable.

#### getPendingGifts

```swift theme={null}
func getPendingGifts() async throws -> [PendingGift]
```

List the pending gifts addressed to the authenticated wallet.

#### getGiftRecords

```swift theme={null}
func getGiftRecords() -> [GiftRecord]
```

Return the local records the SDK persisted for gifts you funded. These make a
gift refundable and travel inside an exported session. Synchronous.

#### decodeGiftLink

```swift theme={null}
func decodeGiftLink(link: String) throws -> GiftLinkPreview
```

Decode a claim link into a preview offline, with no network call. Synchronous and
throwing.

<Info>
  A third funding mode, `giftFundSecretBearer`, binds a gift to a secret instead
  of a wallet. It is **experimental, disabled by default, and a bearer
  instrument** (whoever holds the link can claim). See the
  [concept page](/sdk/concepts/claimable-transfers) before considering it.
</Info>

### GiftRecord

```swift theme={null}
struct GiftRecord {
    let recipientWallet: String
    let blind: String
    let refundAfterBlock: UInt64
    let tokenId: UInt16
    let amount: String
    let cGift: String
    let giftNpk: String
    let requestId: String
    let fundingTreeNumber: UInt64?
    let giftLeafIndex: UInt64?
    let status: String?
}
```

### PendingGift

```swift theme={null}
struct PendingGift {
    let index: UInt32
    let treeNumber: UInt64
    let leafIndex: UInt64
    let cGift: String
    let tokenId: UInt16
    let amount: String
    let refundAfterBlock: UInt64
    let recipientWallet: String
}
```

### GiftLinkPreview

```swift theme={null}
struct GiftLinkPreview {
    let server: String
    let chainId: UInt64
    let cGift: String
    let recipientWallet: String
    let tokenId: UInt16
    let amount: String
    let refundAfterBlock: UInt64
}
```

The gift fields on `TransferResult` are documented under
[TransferResult](#transferresult).

***

## Portal

Portal deposit addresses. See the
[Portal Deposits guide](./guides/portal-deposits) and the
[concept page](/sdk/concepts/portal-deposits).

<Info>
  **Preview feature — pending external audit, and enabled per deployment.** iOS
  exposes the portal lifecycle as methods on `PrivacyBoost`. Low-level portal
  functions are limited to custodial escape hatches.
</Info>

The supported path is `createPortal`, which derives the portal EOA from the
account seed and keeps the key inside core.

#### createPortal

```swift theme={null}
func createPortal(index: UInt32?) async throws -> Portal
```

Derive portal `E`, gaslessly delegate and register it via the server relays, then
publish the discovery entry. Pass `nil` to use the next free derivation index.

#### listPortals

```swift theme={null}
func listPortals() async throws -> [PortalInfo]
```

List the authenticated account's portals with status and derivation index.

#### listPortalDeposits

```swift theme={null}
func listPortalDeposits(portal: String) async throws -> [PortalDeposit]
```

List deposits observed at `portal`.

#### getPortalStatus

```swift theme={null}
func getPortalStatus(portal: String) async throws -> PortalStatus
```

Return registry/on-chain status for one portal.

#### sweepPortal

```swift theme={null}
func sweepPortal(portal: String, tokenId: UInt16) async throws -> String
```

Send `requestPortalDeposit` from the connected wallet and return the transaction
hash.

#### reclaimPortalDeposit

```swift theme={null}
func reclaimPortalDeposit(depositId: String) async throws -> String
```

Send `cancelPortalDeposit` from the connected wallet and return the transaction
hash.

#### withdrawPortal

```swift theme={null}
func withdrawPortal(
    index: UInt32,
    token: String,
    to: String,
    amount: String,
    nonce: UInt64,
    gasLimit: UInt64,
    maxFeePerGas: String,
    maxPriorityFeePerGas: String
) throws -> String
```

Build a signed EIP-1559 transaction that withdraws raw funds resting at the
seed-derived portal `E`. Broadcast the returned raw transaction yourself.

### Low-level escape hatches

These top-level functions are for custodial integrations that manage their own
portal EOA key. The seed-derived `createPortal` flow does not expose a private
key.

#### generatePortalEoa

```swift theme={null}
func generatePortalEoa() -> PortalEoa
```

Generate a fresh portal EOA `E` and its secret private key.

#### encodePortalWithdraw

```swift theme={null}
func encodePortalWithdraw(token: String, to: String, amount: String) throws -> String
```

Encode raw withdraw calldata for a custodial integration that already controls
its own portal EOA.

#### publishPortalRegistry

```swift theme={null}
func publishPortalRegistry(portal: String) async throws
```

Publish the discovery registry entry (`E → blind`) — the supported submit path so
the indexer can credit deposits to the right account.

#### portalDelegateAddress

```swift theme={null}
func portalDelegateAddress() -> String?
```

Return the portal delegate address advertised by the server's `/info`, or `nil`
if the server does not support portals.

### PortalEoa

```swift theme={null}
struct Portal {
    let address: String
    let index: UInt32
    let bindH: String
}

struct PortalInfo {
    let address: String
    let index: UInt32?
    let status: PortalStatus
}

struct PortalStatus {
    let registered: Bool
    let delegated: Bool
    let published: Bool
}

enum PortalDepositState {
    case pendingSweep
    case credited
    case cancellable
    case cancelled
    case unknown
}

struct PortalDeposit {
    let portalDepositId: String
    let portal: String
    let tokenId: UInt16
    let grossAmount: String
    let netAmount: String
    let state: PortalDepositState
    let requestBlock: UInt64
    let cancellableAtBlock: UInt64
}

struct PortalEoa {
    let privateKey: String  // SECRET — custody it; never persisted by the SDK
    let address: String     // the portal deposit address E
}
```

***

## See Also

* [Getting Started](./getting-started) - Quick start guide
* [Wallet Integration](./guides/wallet-integration) - Wallet delegate implementation
