A native iOS app for browsing the DoubleZero ledger's serviceability program on Solana. View all on-chain account types, drill into details, navigate between linked accounts, and search across the entire ledger.
- Browse 9 account types: Exchanges, Contributors, Locations, Devices, Links, Users, Multicast Groups, Tenants, Access Passes
- Detailed views: See all on-chain data for each account with formatted displays
- Telemetry graphs: View packet loss, round-trip time, and jitter charts on Link detail pages
- Cross-account navigation: Tap linked pubkeys to jump to related accounts
- Full-text search: Search across all account types by code, name, IP, or pubkey
- Multi-environment: Switch between Devnet, Testnet, Mainnet-Beta, or custom RPC URL
- User composite codes: Users display as
exchange.code:device.code:tunnel_id(e.g.,fra:allnodes-fra1:507)
- macOS 14+ (Sonoma or later)
- Xcode 16+
- iOS 17+ deployment target
- No external dependencies required
-
Clone the repository:
git clone https://github.com/nikw9944/gm00.git cd gm00 -
Run the setup script:
chmod +x scripts/setup.sh ./scripts/setup.sh
-
Open the Xcode project:
open gm00/gm00.xcodeproj
-
Select an iOS Simulator target and press Cmd+R to build and run.
# Build for simulator
xcodebuild -scheme gm00 -destination 'platform=iOS Simulator,name=iPhone 16' build
# Run tests
xcodebuild -scheme gm00 -destination 'platform=iOS Simulator,name=iPhone 16' testThe app communicates directly with Solana's JSON-RPC API using URLSession. Account data is deserialized from Borsh binary format using a custom Swift decoder. No Rust FFI, no SPM packages.
- Models: Swift structs matching Rust account layouts exactly, with
BorshDecodableconformance - Views: SwiftUI views with
NavigationStackfor deep linking - ViewModels:
@Observable/ObservableObjectview models handling async data loading - Services:
SolanaRPCClient(JSON-RPC),BorshDecoder,Base58,AccountResolver
gm00/
├── gm00/gm00/
│ ├── App/ # App entry point, root navigation
│ ├── Models/ # Account type structs, enums
│ ├── Services/ # RPC client, Borsh decoder, Base58
│ ├── ViewModels/ # View models for each screen
│ ├── Views/ # SwiftUI views
│ │ ├── Detail/ # Per-account-type detail views
│ │ └── Components/# Reusable UI components
│ └── Utilities/ # Network types, extensions
├── gm00/gm00Tests/ # Unit tests
├── docs/ # Work plan, account type reference
└── scripts/ # Development scripts
| Cluster | Program ID |
|---|---|
| Devnet | GYhQDKuESrasNZGyhMJhGYFtbzNijYhcrN9poSqCQVah |
| Testnet | DZtnuQ839pSaDMFG5q1ad2V95G82S5EC4RrB3Ndw2Heb |
| Mainnet | ser2VaTMAcYTaauMrTSfSrxBaUDq7BLNs2xfUugTAGv |
The app uses getProgramAccounts with memcmp filters on the first-byte discriminator to fetch accounts by type. Individual accounts are fetched with getAccountInfo. Batch fetches use getMultipleAccounts.
See docs/account-types.md for the complete reference of all account type structures, fields, and enum values.
If the DoubleZero program adds a new account type:
- Add the discriminator constant to
AccountType.swift - Create a new model file in
Models/matching the Rust struct layout - Add the type to
AccountTypeInfo.browsableTypes - Create a detail view in
Views/Detail/ - Add a case to
AccountResolverandAccountRowView - Add deserialization tests
- Add the source files to the Xcode project
- Launch on Simulator → Home screen shows all 9 account types
- Tap "Exchanges" → List loads, sorted by code
- Tap an exchange → Detail shows all fields
- Tap device1_pk link → Navigates to Device detail
- Tap back → Returns to Exchange detail
- Tap "Users" → List loads with composite codes (e.g.,
fra:allnodes-fra1:507) - Search "ATL" → Results show matching accounts
- Open Settings → Switch to testnet → Data refreshes
- Enter custom RPC URL → Validates and connects
The app defaults to Devnet. Use the gear icon to:
- Select Devnet, Testnet, or Mainnet-Beta
- Enter a custom RPC URL and Program ID
- Test the connection before saving
This project includes Claude Code configuration for AI-assisted development:
- See
CLAUDE.mdfor top-level instructions - See subdirectory
CLAUDE.mdfiles for layer-specific conventions - Use
/build,/test,/add-account-type,/run-on-simulatorskills
[Add license information here]