From 6fa03052fcc92064d0ce93567f10871593a2f84a Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 22 Jun 2026 18:58:22 +0000 Subject: [PATCH 1/5] docs: rewrite root README (Flipcash branding + full overview) Replace the minimal stub with a stakeholder-ready README: Flipcash branding, product overview (USDF reserve + USDF-backed launchpad currencies, device-to- device Kik Code cash bills), an architecture layer diagram linking the docs/architecture suite, tech stack, project structure, getting-started (JDK 21, SDK 37, real local.properties keys), testing, docs links, and contributing/community/license sections. Draft for stakeholder sign-off. Open questions flagged in the PR: confirm public branding, and supply the Flipcash store/landing URL for a download CTA. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01JRVfsXp4HDrDMy7Pbmw9fD --- README.md | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 151 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b88d3d37b..0bae3cb86 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,164 @@ -Code Android App +Flipcash Android App -# Code Android App +# Flipcash for Android [![Release](https://img.shields.io/github/v/release/code-payments/code-android-app.svg)](https://github.com/code-payments/code-android-app/releases/latest) [![GitHub License](https://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat)](https://github.com/code-payments/code-android-app/blob/main/LICENSE.md) -[Code](https://getcode.com) is a mobile wallet app leveraging self-custodial blockchain technology to deliver an instant, global, and private payments experience. +**Flipcash** is a self-custodial mobile wallet for instant, global, private payments, +built on the open [Code Protocol](https://getcode.com) and the Solana blockchain. Its +base reserve currency is **USDF** (a USD stablecoin); on top of it, users create, buy, +sell, and share **launchpad currencies** — custom on-chain tokens backed by USDF +reserves (think memecoins backed by USDC). The signature interaction is a +**device-to-device cash bill**: one phone shows an animated circular **Kik Code**, a +second phone scans it, and a peer-to-peer handshake settles the payment. -Download Code for Android [here](https://play.google.com/store/apps/details?id=com.getcode). +> This repository is the **Android** client. Keys never leave the device — every +> transaction is signed locally with Ed25519 keys derived from a BIP39 mnemonic. + +## Table of contents + +- [Features](#features) +- [How it works](#how-it-works) +- [Architecture](#architecture) +- [Tech stack](#tech-stack) +- [Project structure](#project-structure) +- [Getting started](#getting-started) +- [Testing](#testing) +- [Documentation](#documentation) +- [Contributing](#contributing) +- [Community & support](#community--support) +- [License](#license) + +## Features + +- **Self-custodial wallet** — on-device keys, no custodian; USDF + launchpad currencies. +- **Device-to-device cash bills** — scan a Kik Code to send/receive in person. +- **Launchpad currencies** — create a USDF-backed token; buy/sell it against USDF via an on-chain bonding curve. +- **Contact & username sends**, remote send via shareable link, and in-app messaging. +- **Funding & withdrawal** — Coinbase on-ramp, in-app purchase, and on-chain USDC withdrawals. +- **Verified pricing** — every payment carries a cryptographically signed exchange-rate proof. + +## How it works + +- **USDF is the reserve currency.** Launchpad currencies are priced in and redeemable + for USDF; USDF is locked in each currency's liquidity pool as backing. +- **Two gRPC backends.** The Flipcash service (accounts, profiles, chat, activity) and + the Open Code Protocol / OCP service (transactions, intents, swaps, exchange rates). +- **Intents over Solana.** Money movement is expressed as signed *intents* submitted + over a bidirectional `SubmitIntent` stream; the client builds and signs the Solana + transactions locally, so the backend can verify rates and limits without ever holding + the keys. + +## Architecture + +A multi-module Gradle project (**100+ modules**) with a strictly layered, acyclic +dependency graph. UI is Jetpack Compose (dark-mode only); dependencies are wired with +Hilt and surfaced to Compose through `CompositionLocal`. + +```mermaid +graph TD + App["apps/flipcash/app — entry point, navigation host, DI wiring"] + Features["apps/flipcash/features/* — 26 self-contained screens"] + Shared["apps/flipcash/shared/* — coordinators / controllers / services"] + Services["services/* — gRPC wrappers (API → Service → Repository → Controller)"] + Defs["definitions/* — protobuf sources + generated models"] + UI["ui/* — Compose components, theme, navigation, scanner"] + Libs["libs/* — crypto, network, logging, currency (leaf utilities)"] + + App --> Features --> Shared --> Services --> Defs --> Libs + Features --> UI --> Libs + Services --> Libs +``` + +The full architecture is documented in **[`docs/architecture/`](docs/architecture/README.md)** — +18 topic docs covering modules & boundaries, state & DI, navigation, networking, +persistence, payments, the design system, testing, and more. + +## Tech stack + +| Area | Choice | +|------|--------| +| Language / UI | Kotlin, Jetpack **Compose** (Material 3) | +| Navigation | Jetpack **Navigation 3** + a custom `CodeNavigator` | +| DI | **Hilt** + `CompositionLocal` | +| Async | Kotlin **Coroutines + Flow** (MVI via `BaseViewModel`) | +| Networking | **gRPC + Protobuf**; Retrofit/OkHttp for REST | +| Persistence | **Room** (per-user database) + DataStore | +| Crypto | **Ed25519**, BIP39 mnemonic/key derivation, **Solana** | +| Build | Gradle convention plugins, KSP, **Java 21** | + +## Project structure + +``` +apps/flipcash/ Main app + feature (26) and shared modules +services/ gRPC clients: flipcash, opencode (+ Compose wrappers) +definitions/ Protobuf sources and generated models +libs/ Reusable utilities (crypto, network, logging, currency, …) +ui/ Compose design system, navigation, scanner, biometrics +vendor/ Third-party SDKs (Kik scanner, OpenCV, TipKit) +build-logic/ Convention plugins for consistent module setup +docs/ Architecture documentation +``` + +Each service module has its own README: [`services/flipcash`](services/flipcash/README.md), +[`services/opencode`](services/opencode/README.md). + +## Getting started + +**Prerequisites** + +- **JDK 21** (Amazon Corretto) +- Android SDK (compileSdk **37**, minSdk **29**) +- `google-services.json` placed at `apps/flipcash/app/src/` +- API keys in `local.properties` — `MIXPANEL_API_KEY`, `BUGSNAG_API_KEY`, + `COINBASE_ONRAMP_API_KEY`, `GOOGLE_CLOUD_PROJECT_NUMBER` (a missing key won't fail + the build, but disables the dependent feature) + +**Build & run** + +```bash +# Debug APK +./gradlew :apps:flipcash:app:assembleDebug + +# Release bundle (AAB) +./gradlew :apps:flipcash:app:bundleRelease + +# Unit tests (all modules) +./gradlew test +``` + +See **[docs/architecture/10-build-and-run.md](docs/architecture/10-build-and-run.md)** +for the full setup, build variants, and CI details. + +## Testing + +Fast JVM unit tests (Robolectric where Android APIs are needed), with `:libs:test-utils` +providing coroutine test helpers and Turbine for flow assertions. CI runs the unit +suite via Fastlane (`bundle exec fastlane android flipcash_tests`). See +**[docs/architecture/12-testing.md](docs/architecture/12-testing.md)**. + +## Documentation + +- **[Architecture suite](docs/architecture/README.md)** — the canonical guide (start here). +- **[Build & run](docs/architecture/10-build-and-run.md)** · **[Adding a feature](docs/architecture/11-adding-a-feature.md)** · **[Testing](docs/architecture/12-testing.md)** +- **[Glossary](docs/architecture/glossary.md)** — domain & architecture terms. +- **[`CLAUDE.md`](CLAUDE.md)** — repository orientation for contributors and AI agents. ## Contributing -Anyone is welcome to make code contributions through a PR. +Contributions are welcome via pull request. + +- **Conventional commits** (`feat:`, `fix:`, `chore:`, optional scope e.g. `feat(oc):`). +- Default branch: **`code/cash`**; open PRs against it. +- CI runs on every PR (tests via Fastlane); please run `./gradlew test` locally first. -The best way to share general feedback is on [Discord](https://discord.gg/T8Tpj8DBFp). +## Community & support -This will evolve as we continue to build out the platform and open up more ways to contribute. +- **Discord:** +- **X / Twitter:** +- **Website:** -## Getting Help +## License -If you have any additional questions or need help integrating Code into your website or application, please reach out to us on [Discord](https://discord.gg/T8Tpj8DBFp) or [Twitter](https://twitter.com/getcode). +Released under the **MIT License** — see [LICENSE.md](LICENSE.md). From 1928eaa33fad43dacb9a25109f797ca3a4db3ec0 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 22 Jun 2026 19:01:21 +0000 Subject: [PATCH 2/5] docs: update README community links to Flipcash (website + X), drop Discord Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01JRVfsXp4HDrDMy7Pbmw9fD --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0bae3cb86..32e84e135 100644 --- a/README.md +++ b/README.md @@ -155,9 +155,9 @@ Contributions are welcome via pull request. ## Community & support -- **Discord:** -- **X / Twitter:** -- **Website:** +- **Website:** +- **X / Twitter:** +- **Support:** support@flipcash.com ## License From 693b22e7fb93eec8b3b6db322417ba709e13c1f8 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 22 Jun 2026 19:08:42 +0000 Subject: [PATCH 3/5] docs: replace README header with a Flipcash SVG banner Adds a self-contained vector banner (dark background, Flipcash logomark + wordmark) at docs/assets/flipcash-header.svg and points the README header at it, replacing the legacy Code asset URL. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01JRVfsXp4HDrDMy7Pbmw9fD --- README.md | 2 +- docs/assets/flipcash-header.svg | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 docs/assets/flipcash-header.svg diff --git a/README.md b/README.md index 32e84e135..0358a314f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Flipcash Android App +Flipcash # Flipcash for Android diff --git a/docs/assets/flipcash-header.svg b/docs/assets/flipcash-header.svg new file mode 100644 index 000000000..65e319cef --- /dev/null +++ b/docs/assets/flipcash-header.svg @@ -0,0 +1,12 @@ + + + + + + + + + Flipcash + + From b6caa7c85f703db6c08faea7c7005d3c96e9a862 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 22 Jun 2026 19:16:33 +0000 Subject: [PATCH 4/5] docs: point README header at docs/assets/flipcash-header.png Switch the header image to a committed PNG (to be added) and drop the placeholder SVG. Header renders once docs/assets/flipcash-header.png lands. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01JRVfsXp4HDrDMy7Pbmw9fD --- README.md | 2 +- docs/assets/flipcash-header.svg | 12 ------------ 2 files changed, 1 insertion(+), 13 deletions(-) delete mode 100644 docs/assets/flipcash-header.svg diff --git a/README.md b/README.md index 0358a314f..4b93b6663 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Flipcash +Flipcash # Flipcash for Android diff --git a/docs/assets/flipcash-header.svg b/docs/assets/flipcash-header.svg deleted file mode 100644 index 65e319cef..000000000 --- a/docs/assets/flipcash-header.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - Flipcash - - From 9d1d429d3a87cda520836692d1beee74e38acf68 Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Mon, 22 Jun 2026 15:18:15 -0400 Subject: [PATCH 5/5] Add header image --- docs/assets/flipcash-header.png | Bin 0 -> 10244 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/assets/flipcash-header.png diff --git a/docs/assets/flipcash-header.png b/docs/assets/flipcash-header.png new file mode 100644 index 0000000000000000000000000000000000000000..45f8124eac2b2d25416a190ed1222d391d0d33ec GIT binary patch literal 10244 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