Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ body:
attributes:
label: App Version
description: Which version of BitSleuth Wallet are you using?
placeholder: e.g., 1.2.1
placeholder: e.g., 1.2.2
validations:
required: true

Expand Down
15 changes: 15 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,21 @@ node scripts/test-biometric.js
| Constants | UPPER_SNAKE_CASE | `MAX_FEE_RATE` |
| Types/Interfaces | PascalCase | `WalletState` |

### Version Update Checklist (MUST FOLLOW)

When asked to bump/update the app version, update **ALL** of the following:

1. `app.json` (`expo.version`) — **drives all in-app version displays** (splash screen, About screen, Settings, Crashlytics) via `constants/app-version.ts`
2. `package.json` (`version`)
3. `android/app/build.gradle` (`versionName`, and bump `versionCode`)
4. `ios/BitSleuthWallet/Info.plist` (`CFBundleShortVersionString`)
5. `CHANGELOG.md` — add the new release entry
6. `README.md` — version badge near the top
7. `app/about.tsx` — add a "What's New in X.Y.Z?" `DropdownSection` at the top with `defaultExpanded={true}` (remove `defaultExpanded` from the previous version's section)
8. `.github/ISSUE_TEMPLATE/bug_report.yml` — App Version placeholder example

**NEVER hardcode the version number in components or services.** Always import `APP_VERSION` from `@/constants/app-version`, which reads it from `app.json` via `expo-constants`.

### Documentation Organization

**All markdown files MUST go in the `docs/` folder**, with these exceptions:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

**A professional-grade, non-custodial Bitcoin wallet for iOS and Android**

[![Version](https://img.shields.io/badge/version-1.2.1-blue.svg)](https://github.com/BitSleuthAI/Wallet)
[![Version](https://img.shields.io/badge/version-1.2.2-blue.svg)](https://github.com/BitSleuthAI/Wallet)
[![Platform](https://img.shields.io/badge/platform-iOS%20%7C%20Android-lightgrey.svg)](https://github.com/BitSleuthAI/Wallet)
[![License](https://img.shields.io/badge/license-AGPL--3.0-blue.svg)](LICENSE)
[![React Native](https://img.shields.io/badge/React%20Native-0.81-61dafb.svg)](https://reactnative.dev/)
Expand Down
3 changes: 2 additions & 1 deletion app/(tabs)/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useAutoLock } from '@/hooks/auto-lock-store';
import { useTabAnimation } from '@/hooks/use-tab-animation';
import { useWallet } from '@/hooks/wallet-store';
import { HapticService } from '@/services/haptic-service';
import { APP_VERSION } from '@/constants/app-version';

import type { FiatCurrency } from '@/types/wallet';
import { getWalletTypeDisplayName } from '@/types/wallet';
Expand Down Expand Up @@ -377,7 +378,7 @@ function SettingsScreenContent() {
<SettingItem
icon={Info}
title="About BitSleuth Wallet"
subtitle="Version 1.2.1"
subtitle={`Version ${APP_VERSION}`}
onPress={() => router.push('/about')}
/>

Expand Down
14 changes: 12 additions & 2 deletions app/about.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useWallet } from '@/hooks/wallet-store';
import { GradientBackground } from '@/components/GradientBackground';
import { AndroidSafeContainer } from '@/components/AndroidSafeContainer';
import crashlyticsService from '@/services/crashlytics-service';
import { APP_VERSION } from '@/constants/app-version';

interface DropdownSectionProps {
title: string;
Expand Down Expand Up @@ -103,11 +104,20 @@ export default function AboutScreen() {
About BitSleuth Wallet
</Text>
<Text style={[styles.version, { color: theme.colors.textSecondary }]}>
Version 1.2.1
Version {APP_VERSION}
</Text>
</View>

<DropdownSection title="What's New in 1.2.1?" defaultExpanded={true}>
<DropdownSection title="What's New in 1.2.2?" defaultExpanded={true}>
<BulletPoint text="Open Source Release: BitSleuth Wallet is now open source under the AGPL-3.0 license, with CI/CD, documentation, and community contribution support." />
<BulletPoint text="Satoshi API Fee Fallback: Fee recommendations stay available even when the primary Esplora fee endpoint fails." />
<BulletPoint text="Firebase Performance Monitoring: App performance tracking alongside crash reporting (no analytics)." />
<BulletPoint text="UI Polish: Premium animations, haptic feedback, and micro-interactions across wallet flows." />
<BulletPoint text="Build Fixes: Resolved iOS (Xcode 26) build errors and Android EAS build failures." />
<BulletPoint text="Performance: Faster Receive tab QR rendering and wallet import, plus stricter Bitcoin address checksum validation." />
</DropdownSection>

<DropdownSection title="What's New in 1.2.1?">
<BulletPoint text="Device Optimization: App now optimized exclusively for mobile phone screens (iPhone and Android phones only)." />
</DropdownSection>

Expand Down
3 changes: 2 additions & 1 deletion components/SplashScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
View,
} from 'react-native';
import Svg, { Circle, Path } from 'react-native-svg';
import { APP_VERSION } from '@/constants/app-version';

interface SplashScreenProps {
onAnimationComplete?: () => void;
Expand Down Expand Up @@ -122,7 +123,7 @@ export default function SplashScreen({ onAnimationComplete }: SplashScreenProps)

{/* Version and description */}
<Animated.View style={[styles.versionContainer, { opacity: textOpacity }]}>
<Text style={styles.versionText}>v1.2.1</Text>
<Text style={styles.versionText}>{`v${APP_VERSION}`}</Text>
<Text style={styles.walletText}>Bitcoin Wallet</Text>
</Animated.View>
</View>
Expand Down
6 changes: 6 additions & 0 deletions constants/app-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Constants from 'expo-constants';

// Single source of truth for the displayed app version, read from app.json.
// Bump expo.version in app.json and every consumer (splash screen, About,
// Settings, Crashlytics) updates automatically.
export const APP_VERSION: string = Constants.expoConfig?.version ?? '0.0.0';
3 changes: 2 additions & 1 deletion services/crashlytics-service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Platform } from 'react-native';
import { APP_VERSION } from '@/constants/app-version';

// Firebase Crashlytics with fallback for web/missing native module
let crashlytics: any = null;
Expand Down Expand Up @@ -253,7 +254,7 @@ if (isInitialized && crashlytics && !isExpoGo) {
crashlytics.setUserId('anonymous');
crashlytics.setAttributes({
platform: Platform.OS,
appVersion: '1.2.1',
appVersion: APP_VERSION,
buildType: __DEV__ ? 'debug' : 'release',
environment: 'development-build',
});
Expand Down
Loading