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.
Multi-Chain
The iOS SDK currently does not expose a native chain-context API — PrivacyBoost is initialized against a single chain via its config. Multi-chain support exists in the underlying Rust core and is exposed today on the TypeScript, React Native, and Web/WASM SDKs.
For an architectural overview of how multi-chain identity works, see Multi-Chain Concepts. The same identity keys and privacy address apply across chains regardless of which SDK creates them.
Single-Chain Setup
Pick a chain at SDK init time:
let config = PrivacyBoostConfig(
serverUrl: "https://op.example.com",
chainId: 10, // Optimism
shieldContractAddress: nil, // discovered from server
wethContractAddress: "0x4200000000000000000000000000000000000006",
teePublicKey: nil,
appId: "my-app",
persistenceStorage: nil,
persistenceUnlock: nil
)
let sdk = try PrivacyBoost(config: config)
Switching chains is a config swap — tear down the current SDK and instantiate a new one with the new server URL and chainId.
Multiple SDK Instances (Workaround)
If you need to operate on more than one chain in a single app session, you can instantiate one PrivacyBoost per chain. Each instance keeps its own JWT and chain state, but you must authenticate each one separately.
let optimism = try PrivacyBoost(config: PrivacyBoostConfig(
serverUrl: "https://op.example.com",
chainId: 10,
shieldContractAddress: nil,
wethContractAddress: "0x4200000000000000000000000000000000000006",
teePublicKey: nil,
appId: "my-app",
persistenceStorage: nil,
persistenceUnlock: nil
))
let ethereum = try PrivacyBoost(config: PrivacyBoostConfig(
serverUrl: "https://eth.example.com",
chainId: 1,
shieldContractAddress: nil,
wethContractAddress: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
teePublicKey: nil,
appId: "my-app",
persistenceStorage: nil,
persistenceUnlock: nil
))
// Authenticate each instance independently with the same wallet.
_ = try await optimism.authenticate(
wallet: walletDelegate,
keySource: .walletDerived,
tokenProvider: nil
)
_ = try await ethereum.authenticate(
wallet: walletDelegate,
keySource: .walletDerived,
tokenProvider: nil
)
Caveats
- Persistence collisions. Both instances will try to read/write the same Keychain entries if you pass
persistenceStorage/persistenceUnlock. Either leave persistence off (nil) on the secondary instances, or use distinct appIds — but distinct app IDs mean distinct identities, which defeats the multi-chain story.
- Re-derivation per chain. Each instance derives keys via the wallet signature and re-issues a JWT, so the user signs once per chain.
- No cross-instance state. Pending transactions, balances, and history are siloed per instance — your app code must aggregate.
- No proper resource sharing. The multi-chain
ChainContext API on TS/RN/Web shares one identity and only multiplexes the chain JWT; with multiple iOS SDK instances you pay the full proving / state init cost on each one.
This pattern is suitable for showing balances or running occasional cross-chain operations. For production multi-chain UX, prefer the chain-context API on the platforms that expose it, or wait for native iOS support.
Operating per Chain
Once authenticated, the API surface is identical across instances:
let amount = try optimism.parseAmount("1.0", decimals: 18)
let opShield = try await optimism.shield(
tokenAddress: "0x4200000000000000000000000000000000000006",
amount: amount
)
let ethShield = try await ethereum.shield(
tokenAddress: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
amount: try ethereum.parseAmount("0.5", decimals: 18)
)
Parallel Operations
Use Swift Concurrency to fan out:
async let opTask = optimism.shield(tokenAddress: "0x...", amount: opAmount)
async let ethTask = ethereum.shield(tokenAddress: "0x...", amount: ethAmount)
let (opResult, ethResult) = try await (opTask, ethTask)
Aggregating Balances
struct ChainEntry {
let sdk: PrivacyBoost
let token: String
}
func totalShielded(across chains: [ChainEntry]) async throws -> String {
try await withThrowingTaskGroup(of: String.self) { group in
for chain in chains {
group.addTask {
let bal = try await chain.sdk.getBalance(tokenAddress: chain.token)
return bal.shieldedBalance
}
}
var sum: UInt64 = 0
for try await wei in group {
sum &+= UInt64(wei) ?? 0
}
return String(sum)
}
}
For amounts that exceed UInt64, use BigInt from a library such as BigInt.
Roadmap
A native ChainContextHandle for iOS — mirroring the React Native and TypeScript surfaces — is planned. When available, it will replace the multi-instance workaround with a single SDK instance that multiplexes JWTs and shares identity keys.
Next Steps