Phase 2: DigiAssets v2, Digi-ID, IPFS, Tor (v3.0.0-beta1)#2
Phase 2: DigiAssets v2, Digi-ID, IPFS, Tor (v3.0.0-beta1)#2JohnnyLawDGB merged 13 commits intodevelopfrom
Conversation
…t quantity, tor config New tables: asset_metadata (DigiAsset metadata cache), digiid_history (Digi-ID login history). New column: utxos.asset_quantity (decoded from OP_RETURN, not satoshi value). New columns: wallet_config.torEnabled, torPromptShown. AssetBalance projection class for grouped asset balance queries. Room exportSchema=true for migration testing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New installs get random 32-byte passphrase encrypted via Android Keystore. Phase 1 upgrades continue using legacy passphrase (documented compromise). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Single shared OkHttpClient provided via Hilt. PriceProvider retrofitted to accept injected client. All future HTTP services (IPFS, Digi-ID, DigiScope) will use the same client, enabling Tor SOCKS5 proxy.
CidVerifier: manual CIDv0/v1 parsing (no external IPFS library needed), Base58/Base32/hex multibase decoding, varint reader, SHA-256 digest extraction and content verification. IpfsClient: multi-gateway fallback (trustless-gateway.link, dweb.link, ipfs.io), 5MB response size guard, per-response CID hash check — a malicious gateway cannot inject fake metadata. AssetMetadataService: fetch JSON from IPFS, parse name/symbol/description/ decimals/totalSupply/issuerAddress/imageUrl, cache in Room permanently (CID = content-addressed, immutable — cache is always valid). AssetData / OwnedAsset / AssetMetadata model classes. Tests: 23 passing — CidVerifier (CIDv0, CIDv1 base32, invalid CIDs, edge cases) and IpfsClient (happy path, hash mismatch, gateway fallback, network exception, 5MB size limit, all-gateways-fail). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DigiAssetDecoder: detects 0x4441 DA prefix, parses BitIO-encoded fields for version, opcode, quantities, metadata hash. Supports v2/v3 issuance (opcodes 01-05), transfer (0x15), burn (0x25). Extracts issuance flags (divisibility, locked, aggregation), total quantity via fixed-precision decoding, and IPFS CIDv1 from SHA256 metadata hash. BitReader: bit-level reader ported from digiasset-core BitIO.cpp and digibyte-js Precision.js. Implements the variable-width fixed-precision number format (1-7 bytes, mantissa * 10^exponent). DigiAssetRules: basic transfer validation stub for Phase 2 (quantity check, dispersed/NFT indivisibility). Full rules engine (royalties, KYC, expiry, deflation) deferred to Phase 3. Tested with 48 unit tests including real mainnet DigiAsset v2 transfer from block 11000208 (txid 1af59aea...5651e3). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jni_asset.c: isAssetTransaction() wrapping BRTXContainsAsset(), getOpReturnData() extracting OP_RETURN script bytes. AssetManager: combines UTXO balances with metadata, processes asset UTXOs, queues IPFS metadata fetch. NativeCallback.onAssetDetected added (SyncService stub). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tadata Wire AssetManager into SyncService. Asset transactions detected via onAssetDetected callback from C core. UTXOs marked with asset data. Metadata fetched from IPFS in background. Hilt providers for all Phase 2 services (AssetManager, IpfsClient, AssetMetadataService). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AssetListScreen: grid of owned assets with metadata display. AssetDetailScreen: full asset info, DigiNexum marketplace link, transfer history, send button. AssetSendScreen: address input, quantity, fee, confirmation flow. Navigation wired from WalletScreen Assets button. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DigiIdManager: parse digiid:// URIs, sign challenges, POST to callback. QrScannerScreen: CameraX + ZXing, routes to Digi-ID or Send based on URI. DigiIdScreen + DigiIdConfirmScreen: scan, review, approve with history. DigiIdRequest parser with domain extraction and unsecure detection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DigiScopeClient: JWT-authenticated API client for api.digiscope.me. Login via Digi-ID, handle registration, tip wallet linking, profile. digiscope:// deep link intent filter. Certificate pinning placeholder (pins to be extracted at deployment). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TorManager: lifecycle management with StateFlow, preference persistence. BRPeer.c: SOCKS5 handshake patch for proxied peer connections, with thread-safe global proxy state and BRPeerSetSocksProxy/Clear/Has API. JNI: setSocksProxy/clearSocksProxy bridge functions in jni_peer.c. NetworkModule: OkHttpClient with dynamic ProxySelector for Tor routing. AppModule: TorManager provided as @singleton via Hilt DI. JniProxyTest: 3 instrumented tests verifying JNI proxy bridge stability. Tor binary embedding pending — wallet gracefully degrades without it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NetworkInfoScreen: live Tor toggle with state display (Disabled / Starting / Connecting / Connected (port N) / Failed: reason). SettingsRow: optional subtitleColor parameter for colored state text. SettingsViewModel: injects TorManager, exposes torState + torEnabled StateFlows, and setTorEnabled() persists choice to both SharedPrefs and WalletConfigEntity. WalletScreen: TorIndicator badge rendered below SyncIndicator in the hero header — visible only when TorState is Connected, invisible otherwise (graceful when Tor binary is not yet embedded). WalletViewModel: injects TorManager, exposes torState StateFlow. SyncService: injects TorManager; startSyncWithTor() attempts Tor startup before calling NativeBridge.startSync(). On success wires setSocksProxy(); on failure clears any stale proxy and proceeds directly — sync is never blocked. Notification shows via Tor suffix when proxy is active. MainActivity: applyTorDefaults() detects new installs (no config row) and enables Tor by default. Phase 1 upgrades (config exists, torPromptShown=false) surface a one-time AlertDialog asking to enable Tor — choice persisted to TorManager prefs + WalletConfigEntity. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace outdated 2021 README with comprehensive documentation reflecting the modernized wallet: architecture, features, build instructions, testing, security docs, development phases, and related projects.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3ba5f88b56
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| val json = JSONObject().apply { | ||
| put("uri", rawUri) | ||
| put("address", address) | ||
| put("signature", "placeholder_signature") |
There was a problem hiding this comment.
Sign Digi-ID challenges before posting them
Every authentication request currently sends "placeholder_signature" instead of a signature over the Digi-ID challenge. Compliant Digi-ID servers verify that signature against the callback URI, so this new login flow will be rejected in production even though the UI presents it as available.
Useful? React with 👍 / 👎.
| // AssetMetadataService with a null CID; it will no-op until the CID is | ||
| // learned later (e.g. via processAssetUtxo once the full tx is confirmed). | ||
| assetManager.getAssetHistory(assetId) // touches the DAO, warms the flow |
There was a problem hiding this comment.
Persist asset UTXOs when an asset transfer is detected
This callback never writes an asset UTXO or queues metadata resolution; it only inserts a TransactionEntity and then calls a read-only history flow. The new asset screens derive balances from utxos.is_asset rows via AssetManager.getOwnedAssets(), and AssetManager.processAssetUtxo() is the only codepath that creates those rows, so a detected asset transfer still leaves the DigiAssets tab empty.
Useful? React with 👍 / 👎.
| onDigiByteUri = { uri -> | ||
| // Navigate to send with pre-filled address (and optional amount) | ||
| navController.navigate("send") { | ||
| popUpTo("qr_scanner") { inclusive = true } |
There was a problem hiding this comment.
Carry scanned DigiByte URIs into the send screen
The parsed uri is ignored here: the QR flow just navigates to send without storing the scanned address or amount anywhere, and SendScreen has no route arguments to recover it. In the new shared QR scanner flow, scanning a digibyte: payment request lands the user on a blank send form, so scan-to-pay does not work.
Useful? React with 👍 / 👎.
Phase 2: DigiAssets v2, Digi-ID, Trustless IPFS, Tor
Builds on Phase 1 (PR #1) — adds the four major feature subsystems for the beta release.
DigiAssets v2
BRTXContainsAsset), parses OP_RETURN, stores UTXOs withis_asset=true,asset_id, and decodedasset_quantity(not satoshi dust value).CoinSelectoralready protects asset UTXOs. Phase 2 adds quantity tracking and grouped balance queries.Trustless IPFS
Digi-ID + DigiScope
ImageAnalysis.Analyzer. Routesdigiid://to Digi-ID flow,digibyte:to Send flow. Camera permission handling.digiid://URIs, sign challenge (signing stub pending full JNI), POST to callback, biometric approval, login history in Room.api.digiscope.mewith login, handle registration, tip wallet linking. Certificate pinning placeholder.digiscope://deep link handler.Tor Integration
StateFlow<TorState>. Preference persistence. New-install default ON, upgrade prompt for Phase 1 users.ProxySelectorthat queries TorManager on every request. No singleton rebuild needed.Infrastructure
asset_metadata,digiid_history. New columns:utxos.asset_quantity,wallet_config.torEnabled/torPromptShown. RoomexportSchema=truewithMigrationTestHelpertests.NetworkModuleprovides singleton client. All services (PriceProvider, IPFS, Digi-ID, DigiScope) use it. Tor proxy applied dynamically.Test Results
Tested on Samsung Galaxy Note 8 (SM-N950U, Android 9, API 28).
What's NOT in this PR (Phase 3-4)
Commits (12)
🤖 Generated with Claude Code