Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
103e492
docs(wallet-integration): add research document for Nos wallet integr…
rabble Jul 23, 2025
e1c3942
docs(evaluation): add detailed Cashu library evaluation for Nos integ…
rabble Jul 23, 2025
cc1f66c
docs(cashu-integration): add comprehensive CashuKit integration docum…
rabble Jul 23, 2025
584f110
chore(project): add CashuSwift package dependency to Xcode project
rabble Jul 23, 2025
bbcac50
feat(cashu-wallet): add Cashu wallet and Nutzap services with integra…
rabble Jul 23, 2025
f73c7fe
feat(wallet): add Cashu wallet integration with nutzap support
rabble Jul 23, 2025
4dded1e
feat(wallet): add Cashu wallet integration and UI components
rabble Jul 23, 2025
07db64f
feat(wallet): add Lightning integration and transaction history views
rabble Jul 23, 2025
99059d0
feat(cashu-wallet): integrate Cashu wallet with real CashuSwift types…
rabble Jul 24, 2025
450bd03
feat(wallet): add persistent token storage and dependency injection f…
rabble Jul 24, 2025
13afab1
feat(wallet): add Cashu wallet support with new features and dependen…
rabble Jul 24, 2025
6b4bb5a
style(coredata, wallet, service): remove redundant ABOUTME comments a…
rabble Jul 24, 2025
e32a735
fix(dependency): fix CashuSwift package dependency to use main branch
rabble Jul 24, 2025
92cfb47
feat(wallet): add comprehensive Cashu ecash wallet support with NIP-6…
rabble Jul 24, 2025
661f670
docs(core-data): add detailed Core Data migration guide for Cashu wallet
rabble Jul 24, 2025
2656ab6
feat(coredata): add new Core Data model version Nos 24 with updated e…
rabble Jul 24, 2025
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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Release Notes
- Fixed: crash in Event.trackDelete(on:context:).
- Added: "nostr:" prefix to event links following NIP-01 standard.
- Added: Cashu wallet support for sending and receiving ecash via NIP-60 and NIP-61.
- Added: Nutzaps - a new way to send value using P2PK-locked Cashu tokens.
- Added: Wallet balance display with offline viewing capability.
- Added: Wallet onboarding flow with mnemonic backup.
- Added: Transaction history view for tracking ecash movements.

### Internal Changes
- Fixed: Contact Support event fires too often.
- Performance improvements for RepliesLabel, AuthorLabel, NoteCardHeader, Date+Elapsed
- Added: CashuSwift package dependency for Cashu protocol support.
- Added: Core Data entities for local wallet caching (CashuWalletCache, CashuTokenCache, CashuTransaction).
- Added: NIP-44 encryption for wallet and token events.
- Added: Dependency injection for CashuWalletService, NutzapService, and CashuCacheService.
- Added: Support for new event kinds - 7375 (cashuToken), 7376 (cashuHistory), 17375 (cashuWallet), 9321 (nutzap), 10019 (nutzapInfo).

## [1.2.1] - 2025-02-19Z

Expand Down
193 changes: 193 additions & 0 deletions CORE_DATA_MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
# Core Data Migration Guide for Cashu Wallet

## Overview
This guide walks through adding the Cashu wallet entities to the Core Data model in Xcode. This is a **required manual step** that cannot be done via code.

## Step 1: Create New Model Version

1. **Open Xcode** and load the Nos project
2. **Navigate to** `Nos/Models/CoreData/Nos.xcdatamodeld`
3. **Select the file** in the project navigator
4. **Create new version**:
- Menu: Editor → Add Model Version...
- Base model on: Nos 23 (current version)
- Version name: `Nos 24`
- Click "Finish"

## Step 2: Set Current Model Version

1. **Select** `Nos.xcdatamodeld` in project navigator
2. **Open File Inspector** (right panel)
3. **Under "Model Version"**, change Current to `Nos 24`
4. **Green checkmark** should move to Nos 24

## Step 3: Add CashuWalletCache Entity

1. **Select** `Nos 24.xcdatamodel`
2. **Click "Add Entity"** button at bottom
3. **Name**: `CashuWalletCache`
4. **Add Attributes** (click + in Attributes section):

| Attribute | Type | Optional | Default | Indexed |
|-----------|------|----------|---------|---------|
| id | String | NO | - | YES |
| name | String | NO | - | NO |
| primaryMintURL | String | NO | - | NO |
| trustedMints | Transformable | YES | - | NO |
| walletPublicKey | String | NO | - | NO |
| lightningAddress | String | YES | - | NO |
| lightningGateway | String | YES | - | NO |
| totalBalance | Integer 64 | NO | 0 | NO |
| lastSyncDate | Date | NO | - | NO |
| createdAt | Date | NO | - | NO |
| updatedAt | Date | NO | - | NO |

5. **Configure Transformable**:
- Select `trustedMints` attribute
- In Data Model Inspector:
- Custom Class: `NSSet`
- Transformer: `NSSecureUnarchiveFromDataTransformer`

## Step 4: Add CashuTokenCache Entity

1. **Click "Add Entity"**
2. **Name**: `CashuTokenCache`
3. **Add Attributes**:

| Attribute | Type | Optional | Default | Indexed |
|-----------|------|----------|---------|---------|
| id | String | NO | - | YES |
| mintURL | String | NO | - | NO |
| amount | Integer 64 | NO | - | NO |
| tokenData | Binary | NO | - | NO |
| isSpent | Boolean | NO | NO | NO |
| spentAt | Date | YES | - | NO |
| createdAt | Date | NO | - | NO |
| updatedAt | Date | NO | - | NO |

4. **Configure Binary**:
- Select `tokenData` attribute
- Check "Allows External Storage"

## Step 5: Add CashuTransaction Entity

1. **Click "Add Entity"**
2. **Name**: `CashuTransaction`
3. **Add Attributes**:

| Attribute | Type | Optional | Default | Indexed |
|-----------|------|----------|---------|---------|
| id | String | NO | - | YES |
| type | String | NO | - | NO |
| amount | Integer 64 | NO | - | NO |
| mintURL | String | NO | - | NO |
| lightningInvoice | String | YES | - | NO |
| recipientPubkey | String | YES | - | NO |
| comment | String | YES | - | NO |
| status | String | NO | "pending" | NO |
| createdAt | Date | NO | - | NO |
| completedAt | Date | YES | - | NO |

## Step 6: Add Relationships

### CashuWalletCache Relationships:
1. **Select** `CashuWalletCache` entity
2. **Add Relationships** (click + in Relationships section):

| Relationship | Destination | Inverse | Type | Delete Rule | Optional |
|--------------|-------------|---------|------|-------------|----------|
| author | Author | cashuWallets | To One | Nullify | NO |
| tokens | CashuTokenCache | wallet | To Many | Cascade | YES |
| transactions | CashuTransaction | wallet | To Many | Cascade | YES |
| walletEvent | Event | cashuWallet | To One | Nullify | YES |

### CashuTokenCache Relationships:

| Relationship | Destination | Inverse | Type | Delete Rule | Optional |
|--------------|-------------|---------|------|-------------|----------|
| wallet | CashuWalletCache | tokens | To One | Nullify | NO |
| tokenEvent | Event | cashuTokens | To One | Nullify | YES |
| transaction | CashuTransaction | tokens | To One | Nullify | YES |

### CashuTransaction Relationships:

| Relationship | Destination | Inverse | Type | Delete Rule | Optional |
|--------------|-------------|---------|------|-------------|----------|
| wallet | CashuWalletCache | transactions | To One | Nullify | NO |
| tokens | CashuTokenCache | transaction | To Many | Nullify | YES |
| nutzapEvent | Event | cashuTransaction | To One | Nullify | YES |

## Step 7: Update Existing Entities

### Update Author Entity:
1. **Select** `Author` entity
2. **Add Relationship**:
- Name: `cashuWallets`
- Destination: `CashuWalletCache`
- Type: To Many
- Delete Rule: Cascade
- Inverse: `author`

### Update Event Entity:
1. **Select** `Event` entity
2. **Add Relationships**:

| Relationship | Destination | Inverse | Type | Delete Rule |
|--------------|-------------|---------|------|-------------|
| cashuWallet | CashuWalletCache | walletEvent | To One | Nullify |
| cashuTokens | CashuTokenCache | tokenEvent | To Many | Nullify |
| cashuTransaction | CashuTransaction | nutzapEvent | To One | Nullify |

## Step 8: Generate NSManagedObject Subclasses

1. **Select all three new entities** (Cmd+click each)
2. **Menu**: Editor → Create NSManagedObject Subclass...
3. **Select** `Nos 24` data model
4. **Select** all three Cashu entities
5. **Choose**:
- Language: Swift
- Module: Current Product Module
- Codegen: Manual/None
6. **Save to**: `Nos/Models/CoreData/`
7. **Delete generated files** (we already created custom ones)

## Step 9: Build and Test

1. **Build the project** (Cmd+B)
2. **Check for errors** related to Core Data
3. **Run on simulator** to test migration
4. **Verify** no crashes on app launch

## Troubleshooting

### If app crashes on launch:
1. Delete app from simulator/device
2. Clean build folder (Shift+Cmd+K)
3. Rebuild and run

### If relationships don't work:
1. Double-check inverse relationships
2. Ensure delete rules are correct
3. Verify optional settings match code

### If migration fails:
1. Check PersistenceController.swift for migration settings
2. Ensure lightweight migration is enabled
3. Consider adding mapping model if needed

## Verification

After completing migration:
1. **Create a test wallet** in the app
2. **Check Core Data browser** to see entities
3. **Verify relationships** are properly connected
4. **Test CRUD operations** on wallet data

## Important Notes

- **DO NOT** skip this step - the app will crash without these entities
- **DO NOT** modify Nos 23 model - always create new version
- **DO** test on a clean install after migration
- **DO** backup any test data before migration

This completes the Core Data migration setup!
15 changes: 15 additions & 0 deletions Nos.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2176,6 +2176,7 @@
03C49ABF2C938A9C00502321 /* SwiftSoup */,
039389222CA4985C00698978 /* SDWebImageWebPCoder */,
C98905A12CD3B8CF00C17EE0 /* Inject */,
C9BF90152E323CCA1FEE24A2 /* CashuSwift */,
);
productName = Nos;
productReference = C9DEBFCE298941000078B43A /* Nos.app */;
Expand Down Expand Up @@ -2273,6 +2274,7 @@
03C49ABE2C938A9C00502321 /* XCRemoteSwiftPackageReference "SwiftSoup" */,
039389212CA4985C00698978 /* XCRemoteSwiftPackageReference "SDWebImageWebPCoder" */,
C98905A02CD3B8CF00C17EE0 /* XCRemoteSwiftPackageReference "Inject" */,
C9BF90152E323CCA1FEE24A1 /* XCRemoteSwiftPackageReference "CashuSwift" */,
);
productRefGroup = C9DEBFCF298941000078B43A /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -3840,6 +3842,14 @@
revision = 8968ec00caa51d03d48bd2e91e70f121950fa05d;
};
};
C9BF90152E323CCA1FEE24A1 /* XCRemoteSwiftPackageReference "CashuSwift" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/zeugmaster/CashuSwift";
requirement = {
branch = main;
kind = branch;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
Expand Down Expand Up @@ -4002,6 +4012,11 @@
package = C94D855D29914D2300749478 /* XCRemoteSwiftPackageReference "swiftui-navigation" */;
productName = SwiftUINavigation;
};
C9BF90152E323CCA1FEE24A2 /* CashuSwift */ = {
isa = XCSwiftPackageProductDependency;
package = C9BF90152E323CCA1FEE24A1 /* XCRemoteSwiftPackageReference "CashuSwift" */;
productName = CashuSwift;
};
/* End XCSwiftPackageProductDependency section */

/* Begin XCVersionGroup section */
Expand Down
Loading
Loading