A Swift package for iOS that enables seamless fiat-to-crypto onboarding with phone authentication, Apple Pay, and embedded wallets.
- 📱 Phone Authentication - SMS-based login with Privy SDK
- 🔐 Embedded Wallets - Automatic Solana wallet creation
- 💳 Apple Pay → Crypto - Coinbase Commerce integration for USDC onramp
- ⛓️ Multi-Chain Ready - Designed to support multiple blockchains
- 🎨 Customizable UI - Optional SwiftUI components with theming
- 🔌 Protocol-Based - Easily swap payment processors
Add ZeroSettleKit to your project:
dependencies: [
.package(url: "https://github.com/your-org/ZeroSettleKit.git", from: "0.1.0")
]Or in Xcode:
- File → Add Packages...
- Enter the repository URL
- Select version and add to your target
import ZeroSettleKit
// Create a Coinbase payment processor
let coinbaseProcessor = CoinbasePaymentProcessor(
apiKeyId: "your-coinbase-api-key-id",
apiKeySecret: "your-coinbase-api-secret",
environment: .production
)
// Configure ZeroSettle
let config = ZeroSettleConfig(
privyAppId: "your-privy-app-id",
privyClientId: "your-privy-client-id",
supportedChains: [.solana, .base],
paymentProcessor: coinbaseProcessor,
defaultNetwork: .base,
partnerAppId: 2 // Replace with your partner app ID
)
// Initialize the manager
let zeroSettle = ZeroSettleManager(config: config)
zeroSettle.delegate = self@main
struct MyApp: App {
@StateObject private var zeroSettle: ZeroSettleManager
init() {
let config = ZeroSettleConfig(...)
_zeroSettle = StateObject(wrappedValue: ZeroSettleManager(config: config))
}
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(zeroSettle)
.environmentObject(zeroSettle.authManager)
.task {
await zeroSettle.initialize()
}
}
}
}// Send OTP
try await zeroSettle.sendOTPCode(to: "+14155552671")
// Verify OTP and login
try await zeroSettle.loginWithOTP(code: "123456", phoneNumber: "+14155552671")
// User now has an embedded Solana wallet!
print("Wallet: \(zeroSettle.walletAddress)")// Initiate funding session
let session = try await zeroSettle.initiateFunding(
amount: Decimal(3.00),
currency: "USD"
)
// Load session.paymentURL in a WKWebView
// User completes Apple Pay checkout
// Coinbase sends USDC to user's walletlet payoutTable = try await zeroSettle.fetchLatestPayoutTable()
for tier in payoutTable.tiers {
print("\(tier.guessesUsed) guesses → \(tier.multiplier)x")
}partnerAppId defaults to 2 (WordPlay) but you can configure it via ZeroSettleConfig to target your own app. If your deployment requires an Authorization header, provide a closure through partnerAuthTokenProvider to return a bearer token at request time.
ZeroSettleKit
├── Core/
│ ├── ZeroSettleManager.swift # Main facade
│ ├── ZeroSettleConfig.swift # Configuration
│ └── ZeroSettleDelegate.swift # Event callbacks
│
├── Authentication/
│ └── AuthenticationManager.swift # Privy integration
│
├── Funding/
│ ├── PaymentProcessor.swift # Protocol
│ └── Coinbase/
│ ├── CoinbasePaymentProcessor.swift
│ ├── CoinbaseJWTGenerator.swift
│ └── CoinbaseOnrampEventHandler.swift
│
├── Models/
│ └── BlockchainModels.swift # Shared models
│
└── UI/ (coming soon)
└── Components/
ZeroSettleKit uses protocols to support multiple payment processors:
public protocol PaymentProcessor {
var supportedMethods: [PaymentMethod] { get }
func initiateFunding(
amount: Decimal,
currency: String,
destination: String,
network: BlockchainNetwork
) async throws -> FundingSession
}- ✅ Coinbase Commerce (Apple Pay, Credit/Debit Cards)
- 🔜 Stripe (Coming soon)
- 🔜 MoonPay (Coming soon)
- 🔜 Custom (Implement your own!)
Implement ZeroSettleDelegate to receive events:
extension MyViewController: ZeroSettleDelegate {
func didAuthenticate(userId: String, wallet: WalletInfo) {
print("✅ User \(userId) authenticated with wallet \(wallet.address)")
}
func didCompleteFunding(amount: Decimal, currency: String, transactionHash: String?) {
print("💰 Added \(amount) \(currency)")
}
func didFailFunding(error: Error) {
print("❌ Funding failed: \(error)")
}
}ZeroSettleKit is designed to support multiple blockchains:
public enum BlockchainNetwork: String, Codable {
case ethereum
case base
case arbitrum
case optimism
case polygon
case solana
}Currently, Privy SDK supports Solana embedded wallets. EVM chain support coming soon!
let theme = ZeroSettleTheme(
primaryColor: "#00FF00",
secondaryColor: "#FFFFFF",
backgroundColors: ["#000000", "#1A1A1A"],
buttonCornerRadius: 12
)
let config = ZeroSettleConfig(
...
theme: theme
)let config = ZeroSettleConfig(
...
defaultFundingAmounts: [100, 500, 1000, 2000] // Cents: $1, $5, $10, $20
)- iOS 15.0+
- Swift 5.9+
- Xcode 15.0+
- Privy iOS SDK (2.5.1+)
- Sign up at privy.io
- Create a new app
- Copy your App ID and Client ID
- Sign up at Coinbase Developer Platform
- Create API credentials
- Copy your API Key ID and Secret
Use environment variables or a secure configuration:
// ❌ DON'T do this
let apiKey = "your-secret-key"
// ✅ DO this
let apiKey = ProcessInfo.processInfo.environment["COINBASE_API_KEY"] ?? ""See the Example/ directory for a complete implementation.
- Core authentication (Privy)
- Coinbase payment processor
- Protocol-based architecture
- SwiftUI UI components
- Stripe payment processor
- EVM chain support
- Transaction monitoring
- Balance tracking
- DocC documentation
- Unit tests
- Example app
MIT License - See LICENSE file for details
Contributions welcome! Please read CONTRIBUTING.md first.
Built with ❤️ by ZeroSettle