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
28 changes: 28 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,34 @@ E2E_BACKEND=network E2E_NETWORK=regtest \
build
```

### Running on Physical Device

**From Terminal:**
```bash
# List connected devices
xcrun devicectl list devices

# Set device ID from the list above
DEVICE_ID="<device-identifier-from-list>"

# Build for device
xcodebuild -project Bitkit.xcodeproj -scheme Bitkit -configuration Debug \
-destination 'generic/platform=iOS' -derivedDataPath build build

# Install app on device
xcrun devicectl device install app --device $DEVICE_ID build/Build/Products/Debug-iphoneos/Bitkit.app

# Launch app with console output
xcrun devicectl device process launch --device $DEVICE_ID to.bitkit --console
```

**From Xcode:**
1. Open `Bitkit.xcodeproj`
2. Select your device from the destination dropdown
3. Press Cmd+R to build and run

**Note:** The project includes a "Remove Static Framework Stubs" build phase that removes empty LDKNodeFFI.framework from the app bundle. This is needed because LDKNodeFFI is a static library (linked at compile time), not a dynamic framework.

### Code Formatting
```bash
# Install SwiftFormat
Expand Down
22 changes: 22 additions & 0 deletions Bitkit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@
};
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
96EMBED0012026012000FRAME /* Remove Static Framework Stubs */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Remove Static Framework Stubs";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# Remove static framework stubs from app bundle\\n# LDKNodeFFI is a static library - its code is linked into the main executable.\\n# The empty framework structure causes iOS install errors.\\nFRAMEWORK_PATH=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Frameworks/LDKNodeFFI.framework\"\\n\\nif [ -d \"$FRAMEWORK_PATH\" ]; then\\n echo \"Removing LDKNodeFFI static framework stub...\"\\n rm -rf \"$FRAMEWORK_PATH\"\\n echo \"Done.\"\\nfi\\n";
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXFileReference section */
961058DC2C355B5500E1F1D8 /* BitkitNotification.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = BitkitNotification.appex; sourceTree = BUILT_PRODUCTS_DIR; };
96FE1F612C2DE6AA006D0C8B /* Bitkit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Bitkit.app; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -252,6 +273,7 @@
96FE1F5E2C2DE6AA006D0C8B /* Frameworks */,
96FE1F5F2C2DE6AA006D0C8B /* Resources */,
961058E72C355B5500E1F1D8 /* Embed Foundation Extensions */,
96EMBED0012026012000FRAME /* Remove Static Framework Stubs */,
);
buildRules = (
);
Expand Down
4 changes: 2 additions & 2 deletions Bitkit/Components/Activity/ActivityBanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ struct ActivityBanner: View {

private var bannerText: String {
if let duration = remainingDuration {
return tTodo("TRANSFER READY IN \(duration)")
return t("wallet__activity_transfer_ready_in", variables: ["duration": duration])
} else {
return tTodo("TRANSFER IN PROGRESS")
return t("wallet__activity_transfer_in_progress")
}
}

Expand Down
2 changes: 1 addition & 1 deletion Bitkit/Components/Home/Suggestions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ let cards: [SuggestionCardData] = [
SuggestionCardData(
id: "notifications",
title: t("cards__notifications__title"),
description: tTodo("When Bitkit is closed"),
description: t("cards__notifications__description_alt"),
imageName: "bell-card-figure",
color: .purple24,
action: .notifications
Expand Down
2 changes: 1 addition & 1 deletion Bitkit/Components/IncomingTransfer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct IncomingTransfer: View {

// Show duration if available (force close scenario), otherwise standard transfer text
if let duration = remainingDuration {
CaptionBText(tTodo("From Spending (±\(duration)): "))
CaptionBText(t("wallet__activity_transfer_savings_pending", variables: ["duration": duration]))
} else {
CaptionBText(t("wallet__details_transfer_subtitle"))
}
Expand Down
4 changes: 2 additions & 2 deletions Bitkit/Components/NodeStateView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ struct NodeStateView: View {
try await wallet.disconnectPeer(peer)
app.toast(
type: .info,
title: tTodo("success"),
description: tTodo("Peer disconnected.")
title: t("common__success"),
description: t("lightning__peer_disconnected")
)
} catch {
app.toast(
Expand Down
8 changes: 4 additions & 4 deletions Bitkit/MainNavView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,8 @@ struct MainNavView: View {
Logger.error("Failed to sync push notifications with backend: \(error)")
app.toast(
type: .error,
title: tTodo("Notification Registration Failed"),
description: tTodo("Bitkit was unable to register for push notifications.")
title: t("other__notification_registration_failed_title"),
description: t("other__notification_registration_failed_description")
)
}
}
Expand All @@ -228,8 +228,8 @@ struct MainNavView: View {
Logger.error("Failed to sync push notifications: \(error)")
app.toast(
type: .error,
title: tTodo("Notification Registration Failed"),
description: tTodo("Bitkit was unable to register for push notifications.")
title: t("other__notification_registration_failed_title"),
description: t("other__notification_registration_failed_description")
)
}
}
Expand Down
24 changes: 12 additions & 12 deletions Bitkit/Managers/ScannerManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,17 +150,17 @@ class ScannerManager: ObservableObject {
else {
app.toast(
type: .error,
title: "Error",
description: tTodo("Sorry. Bitkit wasn't able to load this image.")
title: t("common__error"),
description: t("other__qr_error_load_image")
)
return
}

guard let cgImage = image.cgImage else {
app.toast(
type: .error,
title: "Error",
description: tTodo("Sorry. Bitkit wasn't able to process this image.")
title: t("common__error"),
description: t("other__qr_error_process_image")
)
return
}
Expand All @@ -171,8 +171,8 @@ class ScannerManager: ObservableObject {
DispatchQueue.main.async {
app.toast(
type: .error,
title: tTodo("Detection Error"),
description: tTodo("Failed to process the image for QR codes.")
title: t("other__qr_error_detection_title"),
description: t("other__qr_error_detection_description")
)
}
return
Expand All @@ -183,8 +183,8 @@ class ScannerManager: ObservableObject {
DispatchQueue.main.async {
app.toast(
type: .error,
title: tTodo("No QR Code Found"),
description: tTodo("Sorry. Bitkit wasn't able to detect a QR code in this image.")
title: t("other__qr_error_no_qr_title"),
description: t("other__qr_error_no_qr_description")
)
}
return
Expand All @@ -198,8 +198,8 @@ class ScannerManager: ObservableObject {
DispatchQueue.main.async {
app.toast(
type: .error,
title: tTodo("No QR Code Found"),
description: tTodo("Sorry. Bitkit wasn't able to detect a QR code in this image.")
title: t("other__qr_error_no_qr_title"),
description: t("other__qr_error_no_qr_description")
)
}
return
Expand Down Expand Up @@ -230,8 +230,8 @@ class ScannerManager: ObservableObject {
Logger.error(error, context: "Failed to process image")
app.toast(
type: .error,
title: tTodo("Error"),
description: tTodo("Sorry. An error occurred when trying to process this image.")
title: t("common__error"),
description: t("other__qr_error_generic_description")
)
}
}
Expand Down
Loading
Loading