chrisstampar/fx-swift
Native Swift SDK for the f(x) Protocol on iOS/macOS. Complete read/write operations, client-side transaction signing, secure Keychain storage, built-in caching, and zero data collection. Production-ready with 114+ tests.
π― Architecture
iOS App
β
Swift SDK (HTTP Client + Crypto)
β
REST API (FastAPI on Railway)
β
Python SDK (fx-sdk)
β
Ethereum Blockchain⨠Features
- β Complete Read Operations - Query balances, protocol info, Convex/Curve pools, gauges, and more
- β Full Write Operations - 30+ transaction types (mint, redeem, stake, vote, etc.)
- β Client-Side Signing - All transactions signed locally using Web3.swift
- β Secure Key Storage - Private keys stored in iOS Keychain
- β Built-in Caching - Memory and disk caching for read operations
- β Type-Safe - Full Swift type safety with Codable models
- β Async/Await - Modern Swift concurrency support
- β Comprehensive Tests - 93+ unit and integration tests
π¦ Installation
Swift Package Manager
Add the following to your Package.swift:
dependencies: [
.package(url: "https://github.com/chrisstampar/fx-swift.git", from: "1.0.0")
]Or add via Xcode:
- File β Add Packages...
- Enter the repository URL
- Select version or branch
π Quick Start
Basic Setup
import FXProtocol
// Initialize client (uses production API by default)
let client = FXClient()
// Or specify custom API URL
let client = FXClient(baseURL: "https://fx-api-production.up.railway.app/v1")Read Operations (No Auth Required)
// Get all token balances for an address
let balances = try await client.getAllBalances(
address: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
)
// Get specific token balance
let fxusdBalance = try await client.getBalance(
address: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
token: "fxusd"
)
// Get protocol NAV
let nav = try await client.getProtocolNAV()
print("Base NAV: \(nav.baseNav)")
// Get stETH price
let stethPrice = try await client.getStethPrice()
// Get fxUSD total supply
let supply = try await client.getFxusdSupply()Write Operations (Requires Wallet)
// Import wallet (stores private key securely in Keychain)
try client.importWallet(
privateKey: "0x...", // Your private key
address: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
)
// Mint fxUSD
let tx = try await client.mintFToken(
marketAddress: "0x...",
baseIn: "1000000000000000000", // 1 ETH in wei
walletAddress: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
)
print("Transaction hash: \(tx.hash)")
// Track transaction status
let status = try await client.getTransactionStatus(txHash: tx.hash)
print("Status: \(status.status)")Available Write Operations
The SDK supports 30+ write operations:
Token Operations:
mintFToken()- Mint f-token (e.g., fxUSD)mintXToken()- Mint x-token (e.g., xETH)mintBothTokens()- Mint both f and x tokensapprove()- Approve token spendingtransfer()- Transfer tokensredeem()- Redeem tokens
V2 Protocol:
operatePosition()- Operate V2 positionrebalancePosition()- Rebalance V2 positionliquidatePosition()- Liquidate V2 position
Pool Operations:
depositToRebalancePool()- Deposit to rebalance poolwithdrawFromRebalancePool()- Withdraw from rebalance pooldepositToStabilityPool()- Deposit to stability poolwithdrawFromStabilityPool()- Withdraw from stability pool
Savings:
depositToSavings()- Deposit to fxSAVEredeemFromSavings()- Redeem from fxSAVE
Governance:
voteForGauge()- Vote for gaugeclaimGaugeRewards()- Claim gauge rewardslockFXN()- Lock FXN to create veFXN
Treasury:
mintViaTreasury()- Mint via treasurymintViaGateway()- Mint via gatewayredeemViaTreasury()- Redeem via treasury
And more! See the full API in FXProtocol.swift.
π Security & Privacy
- Private Keys: Stored securely in iOS Keychain (encrypted, secure enclave)
- Client-Side Signing: All transactions signed locally on device
- No Key Transmission: Private keys never leave the device
- HTTPS Only: All API calls over HTTPS
- No Data Collection: The SDK does not collect, track, or transmit any user data, analytics, or usage statistics
- No Third-Party Services: No analytics, tracking, or telemetry services are used
- Local-Only Caching: Cache statistics are stored locally and never transmitted
See PRIVACY.md for detailed privacy information.
πΎ Caching
The SDK includes built-in caching for read operations:
// Use cache (default)
let balances = try await client.getAllBalances(
address: "0x...",
useCache: true
)
// Bypass cache
let freshBalances = try await client.getAllBalances(
address: "0x...",
useCache: false
)
// Access cache manager
let cacheStats = await client.cacheManager.getStats()
print("Cache hits: \(cacheStats.hits)")
print("Cache misses: \(cacheStats.misses)")
// Invalidate cache
await client.cacheManager.invalidate(pattern: "balance:*")π§ͺ Testing
Run All Tests
cd swift
swift testRun Integration Tests
Integration tests run against the production API:
swift test --filter IntegrationTestsUse Custom API URL for Tests
Set the TEST_API_URL environment variable:
TEST_API_URL=http://localhost:8000/v1 swift testπ API Reference
Read Operations
Health & Status
getHealth()- Check API healthgetStatus()- Get API status
Balances
getAllBalances(address:)- Get all token balancesgetBalance(address:token:)- Get specific token balancegetFxusdBalance(address:)- Get fxUSD balancegetFxnBalance(address:)- Get FXN balancegetFethBalance(address:)- Get fETH balancegetXethBalance(address:)- Get xETH balancegetVefxnBalance(address:)- Get veFXN balancegetTokenBalance(address:tokenAddress:)- Get ERC-20 token balance
Protocol Info
getProtocolNAV()- Get protocol NAVgetTokenNAV(token:)- Get token NAVgetStethPrice()- Get stETH pricegetFxusdSupply()- Get fxUSD total supplygetPoolInfo(poolAddress:)- Get pool informationgetMarketInfo(marketAddress:)- Get market informationgetTreasuryInfo()- Get treasury information
Convex
getAllConvexPools()- Get all Convex poolsgetConvexPoolInfo(poolAddress:)- Get Convex pool infogetConvexVaultInfo(vaultAddress:)- Get Convex vault infogetConvexVaultBalance(vaultAddress:address:)- Get vault balancegetConvexVaultRewards(vaultAddress:address:)- Get vault rewardsgetUserConvexVaults(address:)- Get user's Convex vaults
Curve
getAllCurvePools()- Get all Curve poolsgetCurvePoolInfo(poolAddress:)- Get Curve pool infogetCurveGaugeBalance(gaugeAddress:address:)- Get gauge balancegetCurveGaugeRewards(gaugeAddress:address:)- Get gauge rewards
Gauges
getGaugeWeight(gaugeAddress:)- Get gauge weightgetGaugeRelativeWeight(gaugeAddress:)- Get relative weightgetGaugeRewards(gaugeAddress:address:)- Get gauge rewardsgetAllGaugeRewards(address:)- Get all gauge rewards
veFXN
getVeFxnInfo(address:)- Get veFXN information
Write Operations
All write operations follow this pattern:
- Import wallet (if not already imported)
- Call the operation method
- SDK handles: prepare β sign β broadcast
- Returns transaction hash
See the "Available Write Operations" section above for the full list.
ποΈ Project Structure
swift/
βββ Sources/
β βββ FXProtocol/ # Main SDK code
β βββ FXProtocol.swift # Main client
β βββ APIClient.swift # HTTP client
β βββ TransactionSigner.swift # Transaction signing
β βββ KeychainManager.swift # Secure storage
β βββ CacheManager.swift # Caching layer
β βββ Models.swift # Data models
β βββ Extensions.swift # Utilities
βββ Tests/
β βββ FXProtocolTests/ # Test suite
β βββ IntegrationTests.swift # Live API tests
β βββ ... # Unit tests
βββ Package.swift # Swift Package Manager config
βββ README.md # This fileπ Status
- β Phase 1: Core Infrastructure - Complete
- β Phase 2: Read Operations - Complete
- β Phase 3: Write Operations - Complete
- β Phase 4: Advanced Features - Caching complete, wallet management complete
- β Phase 5: Testing & Documentation - 93+ tests passing
π License
MIT
π Links
- π Complete Documentation: DOCUMENTATION.md - Exhaustive API reference, examples, and guides
- π Privacy Policy: PRIVACY.md - Privacy and data collection information
- π§ͺ Test Commands: TEST_COMMANDS.md - Testing guide and commands
- π Changelog: CHANGELOG.md - Version history and changes
- π API Documentation: https://fx-api-production.up.railway.app/docs
- π API Health: https://fx-api-production.up.railway.app/v1/health
π€ Contributing
Contributions welcome! Please ensure all tests pass before submitting PRs.
β οΈ Important Notes
- Private Keys: Never commit private keys to version control
- Testnet: For testing, use testnet addresses and small amounts
- Rate Limiting: The API has rate limits (100 req/min, 5000 req/hour)
- Caching: Cache is automatically invalidated after write operations
Package Metadata
Repository: chrisstampar/fx-swift
Stars: 0
Forks: 0
Open issues: 0
Default branch: main
Primary language: swift
License: MIT
Topics: blockchain, crypto, defi, ethereum, fx-protocol, ios, macos, swift, swift-package-manager, web3
README: README.md