add agent/readme docs
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
# Garnet Integration into Amethyst - Project Notes & Learnings
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Item | Value |
|
||||
|------|-------|
|
||||
| **Garnet repo** | https://github.com/retrnull/garnet |
|
||||
| **Amethyst repo** | https://github.com/vitorpamplona/amethyst |
|
||||
| **Garnet base amethyst commit** | `175b79b29` (April 2024) |
|
||||
| **Garnet fork date** | ~July 10, 2024 |
|
||||
| **Latest amethyst commit** | `c19f0be57` (May 2026) |
|
||||
| **Commits since fork** | ~9,330 |
|
||||
| **Garnet version** | v0.3.0 |
|
||||
| **Monero source** | https://github.com/retrnull/monero (branch: `release-v0.18.3.3-garnet`) |
|
||||
|
||||
---
|
||||
|
||||
## What Garnet Adds to Amethyst
|
||||
|
||||
Garnet adds **Monero tipping/zapping** support, mirroring how Amethyst already handles Lightning (Zap) tips. Key features:
|
||||
|
||||
1. **Monero wallet generation** - Derives a Monero spend key from the Nostr private key
|
||||
2. **Tip integration** - "monero" tags on posts (similar to NIP-57 zap tags)
|
||||
3. **3 tip modes** - Private, Anonymous, Public
|
||||
4. **Tip event (kind 1814)** - Records on-chain transactions
|
||||
5. **Tip display** - Counter on tipped notes and user profile
|
||||
6. **Wallet balance display & transfers** - Internal Monero wallet with send to external wallet
|
||||
|
||||
### Code Changes Summary (vs Amethyst base at fork time)
|
||||
- **103 files changed**, 11,569 insertions, 537 deletions
|
||||
- **~1,750 lines** of C++ (Monero JNI bridge: monerujo.cpp + monerujo.h)
|
||||
- **~30 Kotlin source files** (model, service, UI, quartz events)
|
||||
- **New resources** - monero.xml icon, monero-specific strings
|
||||
|
||||
---
|
||||
|
||||
## Build Findings
|
||||
|
||||
### 1. Base amethyst builds cleanly (verified)
|
||||
```bash
|
||||
cd ~/projects/amethyst && ./gradlew assembleFdroidDebug
|
||||
# BUILD SUCCESSFUL - ~116 tasks in 2m44s
|
||||
```
|
||||
|
||||
### 2. Monero native libraries can be extracted from prebuilt APK
|
||||
Download garnet v0.3.0 APK, extract `.so` files:
|
||||
- `libmonerujo.so` - Monero JNI bridge (contains all monero dependencies)
|
||||
- `libsodium.so` - Cryptographic library
|
||||
- `libsecp256k1-jni.so` - secp256k1
|
||||
- `libc++_shared.so` - C++ runtime
|
||||
|
||||
Place in `jniLibs/`, no CMake needed for these prebuilt binaries.
|
||||
|
||||
### 3. Garnet build is blocked by dependency issues
|
||||
- `compose-richtext:richtext-ui:077a2cde64` **cannot be resolved from jitpack.io** (even though it shows "ok" on jitpack status)
|
||||
- Workaround version `e9e0869266` exists but pulls kotlin-stdlib 2.2.0 incompatible with garnet's Kotlin 1.9.23
|
||||
|
||||
### 4. Monero Kotlin code has 667+ compilation errors when copied to latest amethyst
|
||||
The monero integration was written against amethyst v0.4.x (April 2024). Key breaking changes since then:
|
||||
|
||||
#### Quartz Event Model
|
||||
- **Old structure**: Single `quartz/src/main/java/com/vitorpamplona/quartz/events/Event.kt`
|
||||
- **New structure**: Split across modules, `commonMain/kotlin`, KMP targets
|
||||
- `HexKey`, `EventInterface`, `AddressableEvent`, `NostrSigner` moved to new packages in `nip01Core/`
|
||||
|
||||
#### Material3 / Compose
|
||||
- `rememberRipple(Boolean, Dp, Color)` is deprecated and removed (error, not warning)
|
||||
- `autoCorrect` parameter renamed/removed in TextField
|
||||
- `HeadingStyle` moved/renamed
|
||||
|
||||
#### Module Structure
|
||||
- `quartz` is now Kotlin Multiplatform (`commonMain`, `androidMain`, `jvmMain`)
|
||||
- `commons` is KMP
|
||||
- `gem` module removed, `geode` module added
|
||||
- Settings.gradle changed from `.gradle` to `.gradle.kts`, modules renamed
|
||||
|
||||
#### API Changes
|
||||
- Kotlin 1.9.23 → 2.3.21 → various dependency incompatibilities
|
||||
- Gradle 8.4 → 9.x
|
||||
- Compose BOM 2024.04.00 → 2026.05.00
|
||||
- Material3 ripple API changed
|
||||
|
||||
---
|
||||
|
||||
## Docker / Monero Build Findings
|
||||
|
||||
### The Docker build approach is fragile
|
||||
The monero build Dockerfiles (`android64.Dockerfile`, etc.) have multiple issues:
|
||||
|
||||
1. **Old Debian base** - `debian:stable` → `debian:bookworm` required
|
||||
2. **Hardcoded NDK r17c** - Old, needs upgrade for modern toolchain
|
||||
3. **Hash mismatches** - boost, zlib, openssl hashes no longer match available versions
|
||||
4. **Missing dependencies** - Docker build fails without fixes to apt packages
|
||||
|
||||
### Alternative: Use system NDK
|
||||
System NDK available at `~/Android/Sdk/ndk/29.0.13846066/`
|
||||
- Toolchains: `aarch64-linux-android21-clang`, `armv7a-linux-androideabi21-clang`, `x86_64-linux-android21-clang`, `i686-linux-android21-clang`
|
||||
- Monero make targets: `release-static-android-armv8-wallet_api`, `release-static-android-armv7-wallet_api`, `release-static-android-x86_64-wallet_api`, `release-static-android-x86-wallet_api`
|
||||
|
||||
### The prebuilt APK approach works
|
||||
Since the monero libs are fully self-contained in `libmonerujo.so`, we can skip rebuilding monero entirely and use the released APK's `.so` files as a temporary solution.
|
||||
|
||||
---
|
||||
|
||||
## File Structure Mapping
|
||||
|
||||
### Garnet → Amethyst file mapping
|
||||
|
||||
| Garnet file (old) | New location (amethyst) |
|
||||
|---|---|
|
||||
| `app/src/main/java/.../model/` | `amethyst/src/main/java/.../model/` |
|
||||
| `app/src/main/java/.../service/` | `amethyst/src/main/java/.../service/` |
|
||||
| `app/src/main/java/.../ui/` | `amethyst/src/main/java/.../ui/` |
|
||||
| `app/src/main/java/.../ui/note/` | `amethyst/src/main/java/.../ui/note/` |
|
||||
| `app/src/main/java/.../ui/screen/` | `amethyst/src/main/java/.../ui/screen/` |
|
||||
| `app/src/main/java/.../ui/dal/` | `amethyst/src/main/java/.../ui/dal/` |
|
||||
| `quartz/src/main/java/com/vitorpamplona/quartz/events/` | **Moved to KMP - see below** |
|
||||
| `app/src/main/res/` | `amethyst/src/main/res/` |
|
||||
| `app/src/main/cpp/` | `amethyst/src/main/cpp/` |
|
||||
|
||||
### Quartz event files - the biggest restructure
|
||||
Garnet adds/modifies these quartz event files:
|
||||
- `TipEvent.kt` (new) - **Must be adapted for KMP structure**
|
||||
- `Event.kt` - Modified (adds Monero-specific handling)
|
||||
- `EventInterface.kt` - Modified
|
||||
- `CryptoUtils.kt` - Modified
|
||||
- Various event subclasses modified
|
||||
|
||||
In latest amethyst, quartz events live in:
|
||||
```
|
||||
/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/events/
|
||||
```
|
||||
and reference types from:
|
||||
```
|
||||
/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Learnings for Next Session
|
||||
|
||||
1. **Start from latest amethyst, NOT garnet** - 9,330 commits since fork makes reverse-merging impossible
|
||||
2. **Diff garnet against amethyst base 175b79b29** - This gives exact changes to apply
|
||||
3. **Follow existing event patterns** - Study TipEvent.kt, LnZapEvent.kt in latest amethyst for the new structure
|
||||
4. **Material3 APIs have changed** - Replace `rememberRipple` calls, check TextField parameters
|
||||
5. **KMP quartz module** - Quartz event classes need to be in `commonMain/kotlin` not `main/java`
|
||||
6. **Dependencies may need updating** - richtext version, kotlin version, compose BOM
|
||||
7. **Prebuilt .so files work** - Can skip monero build if needed; use garnet APK's libmonerujo.so
|
||||
8. **Amethyst builds cleanly** - Use as baseline; verify after each change
|
||||
9. **gradle/libs.versions.toml** is the single source of truth for all version updates
|
||||
|
||||
---
|
||||
|
||||
## Next Session Task Plan
|
||||
|
||||
See [GARNET_MERGE_PLAN.md](./GARNET_MERGE_PLAN.md) for the detailed step-by-step plan.
|
||||
|
||||
## Commands Used in This Session
|
||||
|
||||
```bash
|
||||
# Find garnet repo
|
||||
curl -s "https://api.github.com/search/repositories?q=garnet+nostr&sort=stars"
|
||||
|
||||
# Clone repos
|
||||
git clone https://github.com/retrnull/garnet.git
|
||||
git clone https://github.com/vitorpamplona/amethyst.git
|
||||
|
||||
# Get garnet diff against amethyst base
|
||||
cd garnet; git diff 99614f07..bfaf92e5 --stat
|
||||
|
||||
# Extract monero APK libs
|
||||
curl -L -o garnet.apk "https://github.com/retrnull/garnet/releases/download/v0.3.0/app-mainnet-fdroid-universal-release.apk"
|
||||
unzip garnet.apk -d extracted-libs/
|
||||
# libmonerujo.so was all we needed
|
||||
|
||||
# Verify amethyst builds
|
||||
./gradlew assembleFdroidDebug 2>&1 | tail -3
|
||||
|
||||
# Build garnet (fail - richtext dependency)
|
||||
./gradlew assembleMainnetFdroidDebug 2>&1 | tail -10
|
||||
|
||||
# Count monero compilation errors in amethyst
|
||||
./gradlew compileFdroidDebugKotlin 2>&1 | grep "^e:" | wc -l # 667 errors
|
||||
```
|
||||
@@ -0,0 +1,303 @@
|
||||
# Plan: Integrate Garnet (Monero Tipping) into Latest Amethyst
|
||||
|
||||
## Approach
|
||||
|
||||
Create a new branch in amethyst and port all 30+ Kotlin source files from garnet, adapting them for the current amethyst codebase. The C++ monero bridge (`monerujo.cpp/.h`) can be copied with minor changes. Prebuilt `.so` files from garnet APK will be used temporarily to avoid the broken monero build process.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Investigation (No changes)
|
||||
|
||||
### Step 1.1: Identify all changes in garnet
|
||||
|
||||
Garnet's diff against amethyst base (`175b79b29`):
|
||||
- 103 files changed, 11,569 insertions, 537 deletions
|
||||
- See `~/projects/garnet` diff output for full list
|
||||
|
||||
### Step 1.2: Generate the exact diff
|
||||
|
||||
Command to run:
|
||||
```bash
|
||||
cd ~/projects/garnet
|
||||
# The base amethyst commit that garnet was derived from is 175b79b29
|
||||
# We need the full diff between garnet and amethyst at that commit
|
||||
# First, find the exact amethyst code at fork point:
|
||||
git diff bfaf92e5~1..HEAD --name-only # All changed files in garnet
|
||||
```
|
||||
|
||||
### Step 1.3: Identify which files need porting vs which are already in latest amethyst
|
||||
|
||||
Some monero-related UI elements may already exist in amethyst (zap UI, lightning), so we should check if any garnet UI work overlaps with existing features.
|
||||
|
||||
### Step 1.4: Study the new amethyst event patterns
|
||||
|
||||
Study these files in latest amethyst to understand the new Quartz/KMP event structure:
|
||||
```
|
||||
/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/events/TipEvent.kt
|
||||
/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/events/LnZapEvent.kt
|
||||
/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/HexKey.kt
|
||||
/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/AddressableEvent.kt
|
||||
/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/signers/NostrSigner.kt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Native Library Setup
|
||||
|
||||
### Step 2.1: Extract and place prebuilt libmonerujo.so
|
||||
|
||||
Since the monero build Docker approach is broken and the prebuilt .so from garnet APK works:
|
||||
|
||||
```bash
|
||||
# Download garnet APK and extract libmonerujo.so
|
||||
curl -L -o /tmp/garnet.apk "https://github.com/retrnull/garnet/releases/download/v0.3.0/app-mainnet-fdroid-universal-release.apk"
|
||||
mkdir -p /tmp/garnet-extract && unzip -o /tmp/garnet.apk -d /tmp/garnet-extract/
|
||||
```
|
||||
|
||||
Place extracted `.so` files into `amethyst/amethyst/src/main/jniLibs/`:
|
||||
```
|
||||
jniLibs/arm64-v8a/libmonerujo.so
|
||||
jniLibs/arm64-v8a/libsodium.so
|
||||
jniLibs/arm64-v8a/libc++_shared.so
|
||||
jniLibs/arm64-v8a/libsecp256k1-jni.so
|
||||
jniLibs/armeabi-v7a/ (same)
|
||||
jniLibs/x86_64/ (same)
|
||||
```
|
||||
|
||||
### Step 2.2: Copy monero C++ source files
|
||||
|
||||
Copy from garnet to amethyst:
|
||||
- `garnet/app/src/main/cpp/monerujo.cpp` → `amethyst/amethyst/src/main/cpp/monerujo.cpp`
|
||||
- `garnet/app/src/main/cpp/monerujo.h` → `amethyst/amethyst/src/main/cpp/monerujo.h`
|
||||
- `garnet/external-libs/monero/src/wallet/api/wallet2_api.h` → `amethyst/amethyst/src/main/cpp/wallet2_api.h`
|
||||
|
||||
### Step 2.3: Remove CMakeLists.txt or make it optional
|
||||
|
||||
If the amethyst build doesn't have a `CMakeLists.txt`, we need to either:
|
||||
- Add a minimal one that doesn't try to compile anything
|
||||
- Or ensure the build.gradle doesn't reference CMake at all
|
||||
- Or make `amethyst/src/main/cpp/` only be used when the .so files are present
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Port Kotlin Source Files (Model Layer)
|
||||
|
||||
Copy these files from garnet to latest amethyst, adapting for the new structure:
|
||||
|
||||
### New files (create in amethyst):
|
||||
|
||||
| Garnet Source | Destination | Priority |
|
||||
|---|---|---|
|
||||
| `MoneroWalletListener.kt` | `amethyst/model/` | High |
|
||||
| `Wallet.kt` | `amethyst/model/` | High |
|
||||
| `WalletManager.kt` | `amethyst/model/` | High |
|
||||
| `MoneroDataSource.kt` | `amethyst/service/` | High |
|
||||
| `TipEventDataSource.kt` | `amethyst/service/` | High |
|
||||
| `TipHandler.kt` | `amethyst/service/` | High |
|
||||
| `WalletService.kt` | `amethyst/service/` | High |
|
||||
| `PendingTransaction.kt` | `amethyst/model/` | Medium |
|
||||
| `ProofInfo.kt` | `amethyst/model/` | Medium |
|
||||
| `Subaddress.kt` | `amethyst/model/` | Medium |
|
||||
| `Transaction.kt` | `amethyst/model/` | Medium |
|
||||
| `TransactionHistory.kt` | `amethyst/model/` | Medium |
|
||||
| `TransactionInfo.kt` | `amethyst/model/` | Medium |
|
||||
| `Transfer.kt` | `amethyst/model/` | Medium |
|
||||
|
||||
### Existing files that need modification:
|
||||
|
||||
| File | Changes needed |
|
||||
|---|---|
|
||||
| `Account.kt` | Add monero address management (key derivation, address storage) |
|
||||
| `LocalCache.kt` | Add monero preferences |
|
||||
| `LocalPreferences.kt` | Add monero-specific preference keys |
|
||||
| `Note.kt` | Add monero tag handling |
|
||||
| `User.kt` | Add monero address from type-0 event |
|
||||
| `ServiceManager.kt` | Add wallet service lifecycle |
|
||||
| `NostrAccountDataSource.kt` | Add monero account methods |
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Port Quartz Event Files (KMP Module)
|
||||
|
||||
### New TipEvent.kt for KMP structure
|
||||
|
||||
Study the existing `TipEvent.kt` in amethyst and `TipEvent.kt` in garnet (kind 1814). Adapt garnet's Monero TipEvent to follow the new pattern:
|
||||
|
||||
```kotlin
|
||||
// Pattern to follow (from LnZapEvent.kt):
|
||||
package com.vitorpamplona.quartz.events
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.core.IEvent
|
||||
|
||||
class MoneroTipEvent(
|
||||
id: HexKey,
|
||||
pubKey: HexKey,
|
||||
createdAt: Long,
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
// ... monero-specific logic
|
||||
companion object {
|
||||
const val KIND = 1814
|
||||
// factory methods, tip proof parsing, etc.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Place at: `/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/events/MoneroTipEvent.kt`
|
||||
|
||||
### Modify Event.kt and EventFactory.kt
|
||||
|
||||
Garnet adds Monero-specific event handling in:
|
||||
- `Event.kt` - Add Monero tag extraction from type-0 metadata
|
||||
- `EventFactory.kt` - Add Monero events to factory
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Port UI Components
|
||||
|
||||
### New UI files:
|
||||
|
||||
| Garnet Source | Destination | Priority |
|
||||
|---|---|---|
|
||||
| `MoneroScreen.kt` | `ui/screen/loggedIn/` | High |
|
||||
| `Tip.kt` | `ui/components/` | Medium |
|
||||
| `TipCustomDialog.kt` | `ui/note/` | Medium |
|
||||
| `TipNoteCompose.kt` | `ui/note/` | Medium |
|
||||
| `TipUserSetCompose.kt` | `ui/note/` | Medium |
|
||||
| `UpdateTipAmountDialog.kt` | `ui/note/` | Medium |
|
||||
| `DisplayTipSplits.kt` | `ui/note/elements/` | Medium |
|
||||
| `TipFeedViewModel.kt` | `ui/screen/` | High |
|
||||
| `TipFeedState.kt` | `ui/screen/` | High |
|
||||
| `TipFeedView.kt` | `ui/screen/` | High |
|
||||
| `UserProfileTipsFeedFilter.kt` | `ui/dal/` | Medium |
|
||||
|
||||
### Existing files that need modification:
|
||||
|
||||
| File | Changes needed |
|
||||
|---|---|
|
||||
| `Routes.kt` | Add monero route |
|
||||
| `AppNavigation.kt` | Add monero navigation |
|
||||
| `AppTopBar.kt` | Add monero icon/button |
|
||||
| `MainScreen.kt` | Add monero screen |
|
||||
| `NoteCompose.kt` | Integrate monero tips display |
|
||||
| `ReactionsRow.kt` | Add monero tip reactions |
|
||||
| `ProfileScreen.kt` | Add monero tips tab |
|
||||
| `NewPostView.kt` / `NewPostViewModel.kt` | Add monero tag to new posts |
|
||||
|
||||
### Adapt UI for Material3 changes:
|
||||
- Replace `rememberRipple(Boolean, Dp, Color)` → use `LocalRippleInfo.current`
|
||||
- Replace `autoCorrect` → check TextField API
|
||||
- Adapt to any Compose parameter changes
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Resources and Build Configuration
|
||||
|
||||
### Strings
|
||||
|
||||
Add Monero-specific strings to `amethyst/amethyst/src/main/res/values/strings.xml`:
|
||||
(129 strings changed in garnet diff)
|
||||
|
||||
### Icons
|
||||
|
||||
Add `monero.xml` to `amethyst/amethyst/src/main/res/drawable/`
|
||||
|
||||
### Build Configuration
|
||||
|
||||
Update `amethyst/amethyst/build.gradle.kts`:
|
||||
- Ensure JNA dependency for monero JNI
|
||||
- Add libsodium dependency (or verify it's transitively included)
|
||||
|
||||
---
|
||||
|
||||
## Phase 7: Build and Verify
|
||||
|
||||
### Build without failures:
|
||||
```bash
|
||||
cd ~/projects/amethyst
|
||||
./gradlew assembleFdroidDebug
|
||||
```
|
||||
|
||||
### Expected issues to fix:
|
||||
1. **Import paths** - Update all quartz imports to new KMP locations (`nip01Core.core.*`, etc.)
|
||||
2. **API changes** - Fix `rememberRipple`, TextField parameters, etc.
|
||||
3. **Kotlin type inference** - Add explicit type parameters where needed
|
||||
4. **Missing companion objects** - Add `companion object { val KIND = ... }`
|
||||
5. **Jackson serialization** - Ensure Jackson annotations match new patterns
|
||||
|
||||
---
|
||||
|
||||
## Risk Assessment
|
||||
|
||||
| Risk | Likelihood | Mitigation |
|
||||
|---|---|---|
|
||||
| Monero TipEvent conflicts with existing Zap TipEvent | Medium | Study existing implementation before starting |
|
||||
| Quartz KMP structure causes issues | High | Study existing events first; use as template |
|
||||
| Material3 API changes cause errors | Medium | Fix iteratively as they appear |
|
||||
| Dependencies break build | Low | Start clean, add one file at a time |
|
||||
| Monoro .so ABI mismatch with target SDK | Low | Use same ABI as garnet (arm64-v8a, armeabi-v7a, x86_64) |
|
||||
|
||||
---
|
||||
|
||||
## Execution Strategy
|
||||
|
||||
1. **Start with one file at a time** - Verify build after each addition
|
||||
2. **Order: Model → Service → Quartz → UI → Navigation**
|
||||
3. **Study first, copy second, adapt last** - Understand each pattern before applying
|
||||
4. **Use git to track progress** - Small commits, easy to revert if needed
|
||||
5. **Verify after each phase** - Ensure base amethyst still builds
|
||||
|
||||
---
|
||||
|
||||
## Files to Port (Complete List)
|
||||
|
||||
### New files to create:
|
||||
- `amethyst/src/main/java/.../model/MoneroWalletListener.kt`
|
||||
- `amethyst/src/main/java/.../model/Wallet.kt`
|
||||
- `amethyst/src/main/java/.../model/WalletManager.kt`
|
||||
- `amethyst/src/main/java/.../service/MoneroDataSource.kt`
|
||||
- `amethyst/src/main/java/.../service/TipEventDataSource.kt`
|
||||
- `amethyst/src/main/java/.../service/TipHandler.kt`
|
||||
- `amethyst/src/main/java/.../service/WalletService.kt`
|
||||
- `amethyst/src/main/java/.../ui/screen/loggedIn/MoneroScreen.kt`
|
||||
- `amethyst/src/main/java/.../ui/screen/TipFeedState.kt`
|
||||
- `amethyst/src/main/java/.../ui/screen/TipFeedView.kt`
|
||||
- `amethyst/src/main/java/.../ui/screen/TipFeedViewModel.kt`
|
||||
- `amethyst/src/main/java/.../ui/components/Tip.kt`
|
||||
- `amethyst/src/main/java/.../ui/note/TipCustomDialog.kt`
|
||||
- `amethyst/src/main/java/.../ui/note/TipNoteCompose.kt`
|
||||
- `amethyst/src/main/java/.../ui/note/TipUserSetCompose.kt`
|
||||
- `amethyst/src/main/java/.../ui/note/UpdateTipAmountDialog.kt`
|
||||
- `amethyst/src/main/java/.../ui/note/elements/DisplayTipSplits.kt`
|
||||
- `amethyst/src/main/java/.../ui/dal/UserProfileTipsFeedFilter.kt`
|
||||
- `quartz/src/commonMain/kotlin/.../events/MoneroTipEvent.kt`
|
||||
|
||||
### Files to modify:
|
||||
- `Account.kt` - Monero address management
|
||||
- `LocalPreferences.kt` - Add monero prefs
|
||||
- `LocalCache.kt` - Add monero cache keys
|
||||
- `Note.kt` - Add monero tag extraction
|
||||
- `User.kt` - Add monero address from metadata
|
||||
- `ServiceManager.kt` - Add wallet service
|
||||
- `Routes.kt` - Add monero route
|
||||
- `AppNavigation.kt` - Add monero navigation
|
||||
- `AppTopBar.kt` - Add monero icon
|
||||
- `MainScreen.kt` - Add monero screen
|
||||
- `NoteCompose.kt` - Display monero tips
|
||||
- `ReactionsRow.kt` - Monero tip reactions
|
||||
- `ProfileScreen.kt` - Monero tips tab
|
||||
- `NewPostView.kt` / `NewPostViewModel.kt` - Add monero tags
|
||||
- `strings.xml` - Add monero strings
|
||||
- `Event.kt` - Add Monero metadata handling (quartz)
|
||||
|
||||
### Files to copy (native):
|
||||
- `amethyst/src/main/cpp/monerujo.cpp`
|
||||
- `amethyst/src/main/cpp/monerujo.h`
|
||||
- `amethyst/src/main/cpp/wallet2_api.h`
|
||||
- `amethyst/src/main/jniLibs/*/libmonerujo.so`
|
||||
- `amethyst/src/main/jniLibs/*/libsodium.so`
|
||||
- `amethyst/src/main/res/drawable/monero.xml`
|
||||
@@ -0,0 +1,66 @@
|
||||
# Garnet Merge Attempt — Status & Notes
|
||||
|
||||
## What is Garnet?
|
||||
|
||||
Garnet ([github.com/retrnull/garnet](https://github.com/retrnull/garnet)) is an Amethyst fork that adds **Monero tipping/zapping** support alongside Lightning (zap) tips. Key features:
|
||||
|
||||
- Monero wallet key derived from the user's Nostr private key
|
||||
- Three tip modes: private, anonymous, public
|
||||
- `monero` tags on posts (similar to NIP-57 zap tags)
|
||||
- Tip counter on notes and profiles, like zaps
|
||||
- Send received tips to an external wallet
|
||||
|
||||
## Summary of Merge Attempt (May 2026)
|
||||
|
||||
We attempted to merge Garnet's Monero integration into the latest Amethyst codebase. The effort produced the following artifacts (in `~/projects/amethyst/`):
|
||||
|
||||
| File | Purpose |
|
||||
|---|---|
|
||||
| `AGENTS.md` | Detailed build findings, API changes, file mappings, lesson learned |
|
||||
| `GARNET_MERGE_PLAN.md` | 7-phase step-by-step plan for porting 30+ source files |
|
||||
| `GARNET_README.md` | ← this file |
|
||||
|
||||
### Key Findings
|
||||
|
||||
| ✓ Success | ✗ Failed |
|
||||
|---|---|
|
||||
| Base Amethyst builds cleanly (~116 tasks in ~3 min) | Garnet's richtext dependency (`077a2cde64`) no longer resolves from jitpack.io |
|
||||
| Prebuilt `libmonerujo.so` extracted from garnet releases works with Amethyst | Direct merge of monero Kotlin code → 667+ compilation errors |
|
||||
| Amethyst v0.4.x → current version gap = 9,330 commits | Amethyst moved to KMP; quartz events are now in `commonMain/kotlin` |
|
||||
|
||||
### Why the merge is non-trivial
|
||||
|
||||
Garnet was forked from Amethyst at commit `175b79b29` (April 2024). Since then, Amethyst has:
|
||||
|
||||
1. **Moved to KMP** — `quartz/` and `commons/` are now Kotlin Multiplatform modules (`commonMain/`, `androidMain/`)
|
||||
2. **Restructured internals** — types like `HexKey`, `NostrSigner`, `EventInterface` moved into `nip01Core/` packages
|
||||
3. **Upgraded Material3** — `rememberRipple(Boolean, Dp, Color)` removed (was an error, not warning)
|
||||
4. **Updated toolchain** — Kotlin 1.9.23 → 2.3.21, Gradle 8.4 → 9.x, Compose BOM 2024.04 → 2026.05
|
||||
|
||||
The monero code (~11,500 lines across 103 files) was written against 2024-era Amethyst APIs and needs adaptation for the current structure.
|
||||
|
||||
### Recommended path forward
|
||||
|
||||
1. Start from **latest Amethyst** (not Garnet) — the 9,330-commit merge would be painful
|
||||
2. Copy ~30 source files from Garnet into Amethyst, adapting imports, package paths, and Material3 APIs
|
||||
3. Use the prebuilt `libmonerujo.so` from garnet releases to skip rebuilding monero via Docker (the Docker build is broken in 2026)
|
||||
4. Port one file at a time, verifying `./gradlew assembleFdroidDebug` after each phase
|
||||
|
||||
See `AGENTS.md` for the full investigation log and `GARNET_MERGE_PLAN.md` for the detailed step-by-step plan.
|
||||
|
||||
### Quick commands for a new session
|
||||
|
||||
```bash
|
||||
# Verify baseline builds
|
||||
cd ~/projects/amethyst && ./gradlew assembleFdroidDebug | tail -3
|
||||
|
||||
# Get the diff between Garnet and the fork point
|
||||
cd ~/projects/garnet
|
||||
git diff 99614f07..bfaf92e5 --stat # 103 files
|
||||
git diff 99614f07..bfaf92e5 --name-status # file list with A/M/D status
|
||||
|
||||
# Extract native libs from garnet releases
|
||||
curl -L -o /tmp/garnet.apk "https://github.com/retrnull/garnet/releases/download/v0.3.0/app-mainnet-fdroid-universal-release.apk"
|
||||
unzip -o /tmp/garnet.apk -d /tmp/garnet/
|
||||
# libmonerujo.so is in extracted-libs/lib/<abi>/
|
||||
```
|
||||
Reference in New Issue
Block a user