Complete reference of the public iOS SDK surface (iosSdk/Sources/InterstellarSdk/). All members live on InterstellarSdk: ObservableObject unless noted otherwise.
Android parity
Since the iOS SDK was published as a standalone package, its API is name-identical to the Android SDK — the same function names (getterRootAccount, getterCampaigns, extrinsicClientTransfer, …), only the signatures differ (Swift vs Kotlin). You can port an app from one platform to the other without renaming anything; see the differences table at the bottom.
Conventions
@Published state is mutated on the main thread only (the SDK hops internally) — bind it directly in SwiftUI.
Methods prefixed with prepare… arm a pinpad/VCA flow; getter… read state; extrinsic… submit on-chain actions.
Errors are not thrown in most paths: failures are logged ([InterstellarSdk]) and surfaced as nil/false. create, prepareCoinTransfer and prepareRecoveryVcaVouch are the notable throws exceptions.
import InterstellarSdk also re-exports the raw Rust API (the uniffi bindings + the renderer C FFI) — see Exports.
SdkCoinBalance(coinIdx: Int32, rawBalance: Int64, usdBalance: Double, address: String?) — Identifiable by coinIdx. SdkCoinBalance.supportedCoins holds the coin table: DOT (10 decimals, $3.79), SOL (9, $177.9), BTC (8, $113796), ETH (18, $4192). SdkCoinBalance.usdPrice(for:) returns the price of a coin index.
CoinBalanceBuilder(coinIdx:decimals:usdPrice:) — the coin table entry; convertToUsd(rawBalance:) converts atomic units to USD.
CoinType (enum CoinType: Int, CaseIterable, Identifiable) — .dot = 0, .sol = 1, .btc = 2, .eth = 3. The order is wire-compatible with the Rust core and with Android's CoinType — do not reorder. Each case exposes intIndex (Int32) and name.
CurrencyMath (enum, static helpers) — priceUsd(_:), divisor(for:), coinToUsd(_:coinAmount:), coinToAtomic(_:amount:), amountToUsd(_:amount:), atomicToBase(_:divisor:), totalBalanceInUsd(_:), computeTotalUsd(_:). The price table is hardcoded (demo-grade values).
WalletBalances (struct) — dot/sol/btc/eth in base units (Decimal), the iOS mirror of Android's WalletBalances.
MobileKeychainSigner — the P-256 (secp256r1) ECDSA device key stored in the iOS Keychain (tag interstellar_mobile_proxy_v1); publicKeySec1Compressed is the 33-byte SEC1-compressed public key. It is the counterpart of the (internal) Android Keystore signer.
Test-only: retarget the worker cli mid-session (Rust update_worker_cli_endpoint).
The init? is public but the factory is the way in
InterstellarSdk.init?(wsURL:nodeURL:ipfsAddr:) is public (it returns nil when the Keychain is unavailable), but create is the supported entry point: it is the only one that performs the registration, the server-reset check and the first balance pull.
Supported end-to-end flow — all steps are [network]:
// 1. Prepare the transaction (note: TxAmount is in ATOMIC units on iOS). let_=await sdk.extrinsicClientInitializeTransaction( recipient:"9WzDX…", txAmount:.fixed(amountInAtomicUnits:500_000_000),// 0.5 SOL coinTypeIdx:1) // 2. Ask the SDK what to do next. iflet pending =await sdk.getterClientGetPendingTx(){ switch pending { case.autoSent(let txHash): // No VCA required for this policy — already broadcast. break case.requiresVca: // Arm the pinpad in one call: tryawait sdk.prepareCoinTransfer(coinTypeIdx:1)// → navigateToPinpad = true } }
High-level: runs the pending-tx dance for you. Throws if there is no pending tx. If the flow was .autoSent, returns the broadcasted tx hash directly; otherwise arms the pinpad (navigateToPinpad = true) and returns nil.
Low-level: submit pad digits. You normally do not call this — CircuitSurfaceView (inside TxPinpadScreen) does it via processPinpadInputs.
processPinpadInputs
func processPinpadInputs(inputs: Data) -> String?
The single entry the pad uses for all flows (transfer, recovery vouch, airdrop, demo). Returns the new broadcasted hash only when a coin transfer was accepted; otherwise nil. Clears the pinpad state afterwards.
getterLatestBroadcastedTxHash
func getterLatestBroadcastedTxHash() -> String?
Latest broadcasted tx hash for this account (receipt display).
clearPinpad
func clearPinpad()
Reset pinpad state (navigateToPinpad=false, package/campaign cleared).
Reading the transfer result
processPinpadInputs returns nilon success for non-transfer flows (recovery vouch, airdrop, demo). The only reliable failure signal for a coin transfer is showTxFailed == true (set when the returned hash did not change). Mirror of Android's contract.
[network] Register an NFC card as recovery method (increments nfcCount on success).
recoveryAddVcaToken
func recoveryAddVcaToken() async -> Data
[network] Generate a VCA token file (Data, file recovery-token.interstellar.enc) — your app handles saving/sharing it (on Android the SDK shares via InterstellarFileSharer). Increments vcaCount.
[network] Vouch with an NFC card. Sets recoveryVouchSubmitted = true on success.
recoveryClaim
func recoveryClaim() async
[network] Claim the recovered account after the ~10-block delay; clears cached accounts/root and zeroes balances until refresh.
Vouch → Claim flow
Recovering a lost account: the helping device (with its own or the imported token/NFC) vouches — recoveryVouchVca or recoveryVouchNfc — then the same device waits for the ~10-block delay (watch recoveryVouchSubmitted == true) and finally calls recoveryClaim().
[network] Server-signs a MoonPay query string so your app can build a trusted MoonPay URL.
Demo transaction (visual cryptography sandbox) — not part of the public API
The SDK code still carries a createDemoTx / demoTxCheckInputs pair: it garbles a display
circuits package for a free-form message so the VCA renderer can be exercised without a real
transaction. These are internal sandbox helpers, not public API — they are not documented
as a contract, they may change or disappear, and they are not covered by the parity promise
with Android. Do not build on them; use the real flows (prepareCoinTransfer,
prepareAirdropRegistration, prepareAirdropClaim, prepareRecoveryVcaVouch) instead.
import InterstellarSdk also gives you the uniffi bindings and the renderer C API (the package re-exports the two FFI modules). Handy for advanced use — e.g. calling the renderer directly:
importInterstellarSdk// gives you the uniffi globals + the renderer C functions var msgWidth:UInt32=0 var msgHeight:UInt32=0 var padWidth:UInt32=0 var padHeight:UInt32=0 _=get_dimensions(ctxPtr,&msgWidth,&msgHeight,&padWidth,&padHeight)
The Android SDK exposes the same Rust surface through its RustWrapper adapter.
A few more symbols ship in the package; they are internal and are not part of the contract —
do not use them (and do not expect them to exist in a future release):
Symbol
What it is
the _getter… / _extrinsic… methods
the internal wrappers over the uniffi bindings (the public API of the same name calls them).
the rust… functions of Rust.swift
the raw uniffi wrappers — the same reason they exist.
InterstellarSdk.init?(wsURL:nodeURL:ipfsAddr:)
the failable initializer; create is the supported entry point.
SdkVcaFlowType
the internal "which flow is armed" state (it is public, but it is a detail of the SDK's state machine).
The public Rust surface is re-exported by the package (see above) — but the supported entry
point is the InterstellarSdk API documented on this page.