Skip to content

Aurocheg/TONContest

Repository files navigation

TON Wallet iOS Contest

iOS crypto wallet prototype built for the TON Wallet Contest.

Awarded 3rd place with a $3,000 prize.

Overview

TON Wallet iOS Contest is an older contest project focused on the core mobile wallet experience for The Open Network:

  • Wallet onboarding and recovery phrase flows
  • Passcode and biometric lock flows
  • Main wallet balance screen
  • Receive flow with QR-code generation
  • Send and transfer flows
  • Transaction history and transaction details
  • TON deep-link handling through the ton:// URL scheme
  • Wallet settings for currency, contract version, Face ID, and notifications

This repository is intentionally preserved as a contest-era UIKit project. The current cleanup focuses on making it easier to inspect, build, and discuss as a portfolio artifact without rewriting the product or changing the original visual identity.

Contest Result

  • 3rd place
  • $3,000 award
  • Built as an independent contest project

Technical Highlights

  • UIKit-first wallet UI with custom controls, collection views, table views, animations, and QR-code rendering
  • VIPER-like screen structure using ViewController, Presenter, Router, and Configurator files per flow
  • Local framework split for UI components, entities, utilities, QR code generation, and signal primitives
  • TON wallet integration through SwiftyTON, including wallet creation, wallet import, contract versions, balance loading, and transfer message creation
  • Security-sensitive UX surfaces: recovery phrase, passcode setup, biometric lock, wallet unlock, and transaction confirmation
  • Network-aware wallet refresh and currency conversion via CoinGecko
  • Deep-link routing for TON transfer links

Architecture

The project is organized as an Xcode workspace with a main app target and several local framework projects:

  • TONApp - main iOS app, screen assembly, navigation, services, TON wallet orchestration, persistence, and app lifecycle
  • WalletUI - reusable UIKit components, controls, cells, labels, QR rendering helpers, and theme primitives
  • WalletEntity - entities and constants used across wallet screens
  • WalletUtils - UIKit and Foundation helper extensions
  • QrCode - QR-code generation wrapper built on WalletUI and SwiftSignalKit
  • SwiftSignalKit - vendored signal primitives used by QR-code rendering
  • WalletCore and WalletUrl - early local modules kept for project history; they are not currently part of the main workspace

Most app flows follow this structure:

  • ViewController owns UIKit layout, view state, and user events.
  • Presenter owns presentation logic and service calls.
  • Router owns navigation.
  • Configurator wires dependencies.

Important logic lives in:

  • TONApp/TONApp/Service/TON/WalletManager.swift
  • TONApp/TONApp/Service/TON/KeystoreManager.swift
  • TONApp/TONApp/Persistence/DatabaseManager.swift
  • TONApp/TONApp/Service/ExchangeManager.swift
  • TONApp/TONApp/Service/ProcessTransactionsManager.swift

Recent cleanup tightened several high-risk boundaries without changing the app concept:

  • Wallet contract selection is centralized in WalletManager instead of being force-cast in presenters.
  • Main wallet loading and network monitoring use cancellable tasks with weak captures.
  • QR scanning starts and stops AVCaptureSession on a serial camera queue and ignores duplicate QR detections.
  • Exchange-rate networking now has deterministic completion behavior and local error types.
  • Recent transaction persistence uses a property-list-safe representation instead of Swift tuples.
  • Key and wallet file writes are atomic and use iOS file protection options.

Screenshots

Current screenshot placeholders:

Wallet screen Transaction flow

Recommended portfolio follow-up: replace these placeholders with fresh simulator screenshots or a short GIF covering onboarding, wallet balance, receive QR, and transaction details.

Running the Project

Requirements

  • Xcode with iOS Simulator support
  • iOS 14.0 or later deployment target
  • Swift 5 project settings
  • Swift Package Manager

The project was originally created with Xcode 14.x-era settings. It has been inspected with Xcode 26.5, but current build verification is blocked by an upstream binary dependency issue described below.

Setup

  1. Open TONApp.xcworkspace.
  2. Select the TONApp scheme.
  3. Resolve Swift packages.
  4. Build and run on an iPhone simulator.

Command-line build shape:

DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer \
xcodebuild \
  -workspace TONApp.xcworkspace \
  -scheme TONApp \
  -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.5' \
  build

Current Dependency Caveat

The original labraburn/SwiftyTON repository is no longer available on GitHub. The workspace now points to a public fork that still contains the exact commit pinned by the original Package.resolved file:

351296979a68f292c03c0adf952389d0f25f69b0

Package resolution now reaches SwiftyTON, but SwiftyTON itself depends on deleted binary release assets from labraburn/tonlib-xcframework:

  • TON.xcframework.zip
  • OpenSSL.xcframework.zip

To fully restore builds, those binary artifacts need to be restored, mirrored, or replaced with a maintained TON Swift integration. That work is intentionally not done here because it would be a dependency recovery task, not a small portfolio cleanup.

Known Caveats

  • Recovery words and the app passcode are still stored through UserDefaults, matching the contest-era implementation. A production wallet should move these flows to a Keychain-backed model with a migration plan.
  • SwiftyTON is configured with a hardcoded local SDK password from the original implementation. Replacing it safely would require wallet data migration and compatibility testing.
  • SwiftSignalKit, QR rendering helpers, and historical WalletCore sources still contain older Swift patterns. They are preserved as local/vendor code rather than broadly modernized.
  • Automated test coverage is still minimal; the current cleanup focused on static safety, lifecycle, and presentation quality.

What I Would Improve Today

This project was built under contest constraints. If I were rebuilding it today, I would improve:

  • Replace the unavailable TON binary dependency with a maintained, reproducible integration
  • Move dependency setup to a single documented package strategy
  • Tighten architecture boundaries between UI, wallet domain logic, persistence, and networking
  • Move recovery phrase and passcode persistence to Keychain-backed storage with migration support
  • Replace the hardcoded TON SDK local password with a secure, user/device-bound secret strategy
  • Add unit tests for wallet state, transaction grouping, amount validation, and settings behavior
  • Add UI tests for onboarding, unlock, receive, send, and deep-link flows
  • Expand accessibility labels, traits, Dynamic Type behavior, and VoiceOver validation
  • Improve error presentation for wallet creation, import, transfer creation, camera access, and network failures
  • Adopt modern Swift concurrency consistently where it clarifies data flow
  • Add fresh screenshots and a short demo GIF

About

Built by Ivan Nichypar.

Senior iOS Engineer focused on SwiftUI, UIKit, complex UI systems, accessibility, performance, framework-level debugging, and product-quality mobile UX.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors