Skip to main content
ZSDepositView is a prebuilt, full-featured SwiftUI view that handles the entire USDC deposit flow. It provides a polished UI for amount selection, payment method switching, transaction status, and error handling—so you don’t have to build this from scratch.

Basic Usage

The simplest integration requires just a wallet address:
import ZeroSettleKit

.sheet(isPresented: $showDeposit) {
    ZSDepositView(walletAddress: "your_wallet_address")
}

With Callback

Get notified when a deposit completes:
import ZeroSettleKit

.sheet(isPresented: $showDeposit) {
    ZSDepositView(
        walletAddress: userWalletAddress,
        onDeposit: { depositedAmountCents in
            // Update your user's balance
            currentUser.balance += depositedAmountCents
            print("Deposited $\(Double(depositedAmountCents) / 100.0)")
        }
    )
}

Parameters

ParameterTypeRequiredDescription
walletAddressStringYesDestination wallet address for USDC deposits. Can be Solana (for Phantom) or Ethereum/Base address (for Apple Pay, MetaMask, Coinbase Wallet)
onDeposit((Int) -> Void)?NoCallback invoked when deposit succeeds. Receives the deposited amount in cents (e.g., 300 = $3.00)

Supported Payment Methods

The view automatically shows all available payment methods:
MethodDescriptionNetwork
Apple PayInstant deposits via Coinbase PayBase
PhantomTransfer USDC from Phantom walletSolana
MetaMaskTransfer USDC from MetaMask walletEthereum
Coinbase WalletTransfer USDC on Base networkBase
Users can easily switch between methods in the UI. The view automatically detects which wallets are installed and available.

Amount Selection

Users can choose from preset amounts or enter a custom amount:
  • Preset amounts: 1,1, 2, 3,3, 5, $10
  • Custom amount: Any amount via text input
All amounts are handled internally and returned to your callback in cents (e.g., 500 = $5.00).

Complete Example

Here’s a full working example in a SwiftUI view:
import SwiftUI
import ZeroSettleKit

struct WalletView: View {
    @State private var showDeposit = false
    @State private var currentBalance: Int = 0 // Balance in cents
    
    let userWalletAddress = "YOUR_WALLET_ADDRESS"
    
    var body: some View {
        VStack(spacing: 20) {
            Text("Balance: $\(balanceFormatted)")
                .font(.largeTitle)
                .bold()
            
            Button("Deposit USDC") {
                showDeposit = true
            }
            .buttonStyle(.borderedProminent)
        }
        .sheet(isPresented: $showDeposit) {
            ZSDepositView(
                walletAddress: userWalletAddress,
                onDeposit: { depositedAmountCents in
                    // Update balance
                    currentBalance += depositedAmountCents
                    
                    // Save to backend
                    saveBalanceToBackend(currentBalance)
                    
                    // Track analytics
                    Analytics.track("deposit_completed", [
                        "amount_cents": depositedAmountCents
                    ])
                    
                    // Dismiss sheet
                    showDeposit = false
                }
            )
        }
    }
    
    var balanceFormatted: String {
        String(format: "%.2f", Double(currentBalance) / 100.0)
    }
    
    func saveBalanceToBackend(_ balanceCents: Int) {
        // Your API call here
    }
}

Wallet Address Formats

The walletAddress parameter accepts both Solana and Ethereum-compatible addresses:

Solana Address (for Phantom)

ZSDepositView(
    walletAddress: "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU"
)

Ethereum/Base Address (for Apple Pay, MetaMask, Coinbase)

ZSDepositView(
    walletAddress: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
)
You can use the same wallet address for all payment methods, or let users choose by omitting the parameter. The view handles routing automatically.

What the View Handles

The ZSDepositView automatically takes care of: Payment Method Selection - Buttons to switch between Apple Pay, Phantom, MetaMask, and Coinbase Wallet Wallet Detection - Automatically detects installed wallets and shows installation prompts if needed Amount Input - Preset buttons (1,1, 2, 3,3, 5, $10) and custom amount text field Transaction Processing - Handles wallet connections, transaction signing, and network submission Loading States - Shows progress indicators during transaction processing Transaction Status - Real-time updates showing “Pending”, “Confirming”, “Confirmed” Error Handling - User-friendly error messages with retry options Dismissal - Automatic or manual dismissal after success/error

Working with Amounts

All amounts in ZeroSettle are represented in cents to avoid floating-point precision issues:
// Amounts in cents
let oneDollar = 100
let fiveDollars = 500
let tenCents = 10

// Converting to display
let displayAmount = String(format: "$%.2f", Double(amountCents) / 100.0)

// Example callback
onDeposit: { cents in
    print("User deposited \(cents) cents")
    print("That's $\(Double(cents) / 100.0)")
    
    // Update balance (also in cents)
    userBalance += cents
}

Common Patterns

Update UI After Deposit

.sheet(isPresented: $showDeposit) {
    ZSDepositView(
        walletAddress: walletAddress,
        onDeposit: { cents in
            currentBalance += cents
            showDeposit = false // Dismiss
            showSuccessAlert = true // Show confirmation
        }
    )
}

Save to Backend

.sheet(isPresented: $showDeposit) {
    ZSDepositView(
        walletAddress: walletAddress,
        onDeposit: { cents in
            Task {
                try await backend.updateBalance(cents)
                await fetchUserBalance()
            }
        }
    )
}

Track Analytics

.sheet(isPresented: $showDeposit) {
    ZSDepositView(
        walletAddress: walletAddress,
        onDeposit: { cents in
            Analytics.logEvent("usdc_deposit", parameters: [
                "amount_usd": Double(cents) / 100.0,
                "amount_cents": cents,
                "wallet_address": walletAddress
            ])
        }
    )
}

Testing

When testing deposits, use small amounts:
// Good for testing
ZSDepositView(walletAddress: testWalletAddress)
// User selects $1 or $2 for testing

// Track test deposits separately
onDeposit: { cents in
    #if DEBUG
    print("TEST DEPOSIT: \(cents) cents")
    #endif
    currentBalance += cents
}
Always test on testnet or with small amounts before deploying to production. USDC transactions are real money.

Best Practices

Always store monetary amounts as integers (cents) to avoid floating-point precision errors. Convert to dollars only for display.
Don’t rely solely on the callback. Save deposit records to your backend with transaction details for reconciliation and support.
Set showDeposit = false in your callback to automatically dismiss the view after a successful deposit.
Make sure to test with Apple Pay, Phantom, MetaMask, and Coinbase Wallet to ensure all flows work correctly.
Solana addresses for Phantom, Ethereum/Base addresses (starting with 0x) for Apple Pay, MetaMask, and Coinbase Wallet.
Need more control? Use the ZeroSettle Deposit API to build fully custom UIs with direct access to payment rails.