kingpin-apps/swift-handles-api
A Swift client library for the [ADA Handle Public API](https://handle.me), providing type-safe access to Cardano blockchain handle data and operations.
Features
- β¨ Type-safe API client generated from OpenAPI specification
- π Built-in authentication with API key support
- π Network flexibility (mainnet, preprod, preview support)
- π§ͺ Comprehensive testing using Swift Testing framework
- π± Multi-platform support (iOS, macOS, watchOS, tvOS)
- π Modern Swift leveraging async/await and Swift 6.2
Requirements
- Swift 6.2+
- iOS 14.0+ / macOS 13.0+ / watchOS 7.0+ / tvOS 14.0+
- Xcode 15.0+ (for development)
Installation
Swift Package Manager
Add the following to your Package.swift file:
dependencies: [
.package(url: "https://github.com/Kingpin-Apps/swift-handles-api.git", from: "0.1.0")
]Or in Xcode:
- Go to File β Add Package Dependencies...
- Enter the repository URL
- Select the version you want to use
Quick Start
Basic Usage
import SwiftHandlesAPI
// Initialize the client
let handles = try Handles(
network: .mainnet,
apiKey: "your-api-key"
)
// Fetch a specific handle
let response = try await handles.client.getHandlesHandle(
Operations.GetHandlesHandle.Input(
path: .init(handle: "my.handle")
)
)
let handleData = try response.ok.body.json
print("Handle: \(handleData.name ?? "unknown")")
print("Holder: \(handleData.holder ?? "unknown")")Using Environment Variables
// Set API key via environment variable
// export HANDLES_API_KEY="your-api-key"
let handles = try Handles(
network: .mainnet,
environmentVariable: "HANDLES_API_KEY"
)Custom Base URL
let handles = try Handles(
network: .mainnet,
apiKey: "your-api-key",
basePath: "https://custom-api.example.com"
)API Operations
Get a Specific Handle
let response = try await handles.client.getHandlesHandle(
Operations.GetHandlesHandle.Input(
path: .init(handle: "adahandle")
)
)
let handle = try response.ok.body.jsonGet All Handles (with filters)
let response = try await handles.client.getHandles(
Operations.GetHandles.Input(
query: .init(
search: "ada",
rarity: .rare,
records_per_page: 50,
page: 1
)
)
)
let handlesList = try response.ok.body.jsonGet Handle UTxO
let response = try await handles.client.getHandlesHandleUtxo(
Operations.GetHandlesHandleUtxo.Input(
path: .init(handle: "my.handle")
)
)
let utxo = try response.ok.body.jsonGet Holder Information
let response = try await handles.client.getHoldersHolderAddress(
Operations.GetHoldersHolderAddress.Input(
path: .init(holder_address: "stake1u...")
)
)
let holder = try response.ok.body.jsonGet Handle Statistics
let response = try await handles.client.getStats()
let stats = try response.ok.body.json
print("Total Handles: \(stats.total_handles ?? 0)")
print("Total Holders: \(stats.total_holders ?? 0)")Architecture
OpenAPI Code Generation
This library uses Swift OpenAPI Generator to automatically generate type-safe Swift code from the OpenAPI specification at build time.
Key Files:
Sources/SwiftHandlesAPI/openapi.yml- The ADA Handle Public API specificationSources/SwiftHandlesAPI/openapi-generator-config.yaml- Generator configuration
Generated Namespaces:
Components.Schemas.*- Data types (e.g.,Components.Schemas.Handle)Operations.*- API operations (e.g.,Operations.GetHandlesHandle)
Authentication
The library provides an AuthenticationMiddleware that automatically injects Bearer token authentication into all API requests:
// Automatically handled when you provide an API key
let handles = try Handles(network: .mainnet, apiKey: "your-key")
// All requests will include: Authorization: Bearer your-keyNetwork Configuration
The Network enum supports multiple Cardano networks:
public enum Network {
case mainnet
// case preprod // Coming soon
// case preview // Coming soon
// case guild // Coming soon
// case sancho // Coming soon
}Testing
This project uses the Swift Testing framework (not XCTest).
Running Tests
# Run all tests
swift test
# Run tests in parallel
swift test --parallel --enable-test-discovery
# Run a specific test suite
swift test --filter HandlesTests
# Build in release mode
swift build -c releaseWriting Tests
import Testing
@testable import SwiftHandlesAPI
@Suite("My Test Suite")
struct MyTests {
@Test("Test description")
func testExample() async throws {
let result = try await someOperation()
#expect(result == expectedValue)
}
}Mocking for Tests
The library provides a ClientTransport protocol for mocking:
struct MockTransport: ClientTransport {
func send(_ request: HTTPRequest, body: HTTPBody?, baseURL: URL, operationID: String) async throws -> (HTTPResponse, HTTPBody?) {
// Return mock responses based on operationID
}
}
let handles = try Handles(
network: .mainnet,
client: Client(serverURL: baseURL, transport: MockTransport())
)Error Handling
The library defines custom errors in HandlesError:
enum HandlesError: Error {
case invalidBasePath(String?)
case missingAPIKey(String?)
case valueError(String?)
}Handling API Errors
do {
let response = try await handles.client.getHandlesHandle(...)
let handle = try response.ok.body.json
} catch let error as HandlesError {
print("Handles API Error: \(error)")
} catch {
print("Unexpected error: \(error)")
}Data Models
Handle
Components.Schemas.Handle // Main handle data typeKey properties:
name- Handle name (e.g., "my.handle")hex- Hexadecimal representationholder- Current holder addressholder_type- Type of holder (wallet, script, enterprise, other)rarity- Handle rarity (basic, common, rare, ultra_rare, legendary)length- Length of the handleog- OG statusresolved_addresses- Resolved addresses for various chains (ada, eth, btc)utxo- Transaction hash and index
Holder
Components.Schemas.Holder // Holder informationKey properties:
address- Stake key or other address typetype- Address typetotal_handles- Number of handles helddefault_handle- Default handle for this holderknown_owner_name- Known vendor/exchange name
UTxO
Components.Schemas.UTxO // Unspent transaction outputKey properties:
tx_id- Transaction IDindex- UTxO indexlovelace- Amount in lovelacedatum- Datum CBOR if presentaddress- UTxO address
Documentation
Generate Documentation
swift package generate-documentation --target SwiftHandlesAPIAPI Reference
For complete API documentation, see the ADA Handle Public API docs.
Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests using Swift Testing framework
- Ensure all tests pass (
swift test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Setup
# Clone the repository
git clone https://github.com/your-org/swift-handles-api.git
cd swift-handles-api
# Build the package
swift build
# Run tests
swift test --parallel --enable-test-discoveryLicense
This project is licensed under the terms specified in the LICENSE file.
Resources
Support
For issues, questions, or contributions, please:
- Open an issue on GitHub
- Contact the maintainers
- Check the API documentation
Note: This library is a client for the ADA Handle Public API. For official ADA Handle information and services, visit handle.me.
Package Metadata
Repository: kingpin-apps/swift-handles-api
Default branch: main
README: README.md