Android support: mobile node, wallet, FFI and platform-specific fixes #38

Closed
Aquacongas wants to merge 2 commits from main into main
Aquacongas commented 2026-08-29 11:24:31 +00:00 (Migrated from github.com)

Hi, I wanted to open this as a PR rather than just keep the Android work in my fork, so you can clearly see what I changed and why.

My main goal is not to force the Android application itself into Parano1d, but to reduce the amount of upstream code I have to patch locally. If the reusable Android compatibility changes and mobile components make sense upstream, merging them would make it much easier for me to pull future Parano1d updates and continue maintaining the Android version.

This PR adds the Android/mobile implementation I have been using for ParanO1c and keeps the Android-specific changes as isolated as possible from the existing Parano1d desktop/mainnet code.

The main reason for opening this PR is maintainability.

I am actively developing and testing an Android wallet/full-node based directly on Parano1d. Keeping all Android adaptations only in my fork makes every upstream update harder to integrate. If the Android-compatible parts of this work are acceptable upstream, merging them would make it much easier for me to keep the Android implementation synchronized with Parano1d and continue contributing fixes without maintaining a large permanent fork.

Main additions

  • Dedicated mobile crates:

    • noid_mobile_node
    • noid_mobile_ffi
    • noid_mobile_wallet
    • noid_mobile_networking
    • noid_mobile_sync_apply
    • noid_mobile_history_runtime
  • Android application project and JNI/FFI integration.

  • Mobile full-node runtime using the same Parano1d chain, mempool and P2P components.

  • Android wallet support including:

    • wallet recovery
    • address management
    • balance/UTXO synchronization
    • transaction construction and submission
    • SEND ALL support
    • pending transaction tracking
  • Mobile chain/bootstrap/snapshot synchronization.

  • Mempool synchronization and transaction relay using the existing Parano1d networking mechanisms.

  • Mobile mempool bootstrap policy aligned with the mainnet node:

    • only locally selected peers are proactively queried
    • requests are tracked
    • at most four peers are used for proactive mempool bootstrap

Android-specific compatibility changes

The changes to existing upstream crates are intentionally small and guarded by target_os = "android" where appropriate.

  1. P2P DNS initialization

On Android the normal libp2p DNS builder path did not work correctly in the mobile environment and resulted in no usable peers.

The Android build therefore skips the standard .with_dns() builder step while non-Android builds retain the existing behavior.

  1. MDBX map size

The desktop configuration uses a very large virtual MDBX map.

On Android this caused virtual-memory allocation failures. The Android target uses a 64 GiB maximum map size while non-Android targets keep the existing 1 TiB value.

  1. Snapshot staging

The normal snapshot staging path uses hard_link.

On Android this produced Permission denied (os error 13) in the application storage environment.

The Android implementation uses a same-directory rename for the staged file while preserving the existing behavior on other targets.

  1. libmdbx Android compatibility

The repository includes the libmdbx source used by the Android build because the crates.io version required a small Android compilation compatibility fix for the current NDK/toolchain.

Design goal

I have tried to avoid changing Parano1d protocol or consensus behavior.

The Android implementation reuses the existing Parano1d chain, transaction, mempool and networking logic. Platform-specific behavior is kept behind Android compile-time guards or inside the dedicated mobile crates.

I would especially appreciate review of the small changes made to the existing upstream crates.

If you are comfortable merging the reusable Android support into Parano1d, it would make future development much easier for me because I could keep my Android application close to upstream instead of repeatedly carrying and rebasing the same compatibility patches.

If some parts are not appropriate for upstream, I am also happy to split this into smaller PRs, for example:

  • Android platform compatibility fixes
  • mobile core crates
  • Android application/FFI layer

The current Android build has been tested on a real ARM64 Android device, including node synchronization, wallet recovery, address handling, mempool synchronization and successful transaction submission/confirmation.

ParanO1c remains an experimental community-developed Android project and is not presented as an official Parano1d release.

Hi, I wanted to open this as a PR rather than just keep the Android work in my fork, so you can clearly see what I changed and why. My main goal is not to force the Android application itself into Parano1d, but to reduce the amount of upstream code I have to patch locally. If the reusable Android compatibility changes and mobile components make sense upstream, merging them would make it much easier for me to pull future Parano1d updates and continue maintaining the Android version. This PR adds the Android/mobile implementation I have been using for ParanO1c and keeps the Android-specific changes as isolated as possible from the existing Parano1d desktop/mainnet code. The main reason for opening this PR is maintainability. I am actively developing and testing an Android wallet/full-node based directly on Parano1d. Keeping all Android adaptations only in my fork makes every upstream update harder to integrate. If the Android-compatible parts of this work are acceptable upstream, merging them would make it much easier for me to keep the Android implementation synchronized with Parano1d and continue contributing fixes without maintaining a large permanent fork. Main additions - Dedicated mobile crates: - noid_mobile_node - noid_mobile_ffi - noid_mobile_wallet - noid_mobile_networking - noid_mobile_sync_apply - noid_mobile_history_runtime - Android application project and JNI/FFI integration. - Mobile full-node runtime using the same Parano1d chain, mempool and P2P components. - Android wallet support including: - wallet recovery - address management - balance/UTXO synchronization - transaction construction and submission - SEND ALL support - pending transaction tracking - Mobile chain/bootstrap/snapshot synchronization. - Mempool synchronization and transaction relay using the existing Parano1d networking mechanisms. - Mobile mempool bootstrap policy aligned with the mainnet node: - only locally selected peers are proactively queried - requests are tracked - at most four peers are used for proactive mempool bootstrap Android-specific compatibility changes The changes to existing upstream crates are intentionally small and guarded by target_os = "android" where appropriate. 1. P2P DNS initialization On Android the normal libp2p DNS builder path did not work correctly in the mobile environment and resulted in no usable peers. The Android build therefore skips the standard `.with_dns()` builder step while non-Android builds retain the existing behavior. 2. MDBX map size The desktop configuration uses a very large virtual MDBX map. On Android this caused virtual-memory allocation failures. The Android target uses a 64 GiB maximum map size while non-Android targets keep the existing 1 TiB value. 3. Snapshot staging The normal snapshot staging path uses `hard_link`. On Android this produced `Permission denied (os error 13)` in the application storage environment. The Android implementation uses a same-directory rename for the staged file while preserving the existing behavior on other targets. 4. libmdbx Android compatibility The repository includes the libmdbx source used by the Android build because the crates.io version required a small Android compilation compatibility fix for the current NDK/toolchain. Design goal I have tried to avoid changing Parano1d protocol or consensus behavior. The Android implementation reuses the existing Parano1d chain, transaction, mempool and networking logic. Platform-specific behavior is kept behind Android compile-time guards or inside the dedicated mobile crates. I would especially appreciate review of the small changes made to the existing upstream crates. If you are comfortable merging the reusable Android support into Parano1d, it would make future development much easier for me because I could keep my Android application close to upstream instead of repeatedly carrying and rebasing the same compatibility patches. If some parts are not appropriate for upstream, I am also happy to split this into smaller PRs, for example: - Android platform compatibility fixes - mobile core crates - Android application/FFI layer The current Android build has been tested on a real ARM64 Android device, including node synchronization, wallet recovery, address handling, mempool synchronization and successful transaction submission/confirmation. ParanO1c remains an experimental community-developed Android project and is not presented as an official Parano1d release.
ignotusnemo commented 2026-08-29 16:28:33 +00:00 (Migrated from github.com)

This is out of scope for the Parano1d core repository. ParanO1c is a separate community product, and its Android app, mobile crates, FFI, dependencies and platform-specific code must remain in its own repository. Closing this PR.

This is out of scope for the Parano1d core repository. ParanO1c is a separate community product, and its Android app, mobile crates, FFI, dependencies and platform-specific code must remain in its own repository. Closing this PR.
Aquacongas commented 2026-08-29 16:41:57 +00:00 (Migrated from github.com)

Understood, and I agree that ParanO1c should remain a separate community product and repository.

I just want to clarify one technical point about the way I currently maintain it.

ParanO1c is built directly on top of the Parano1d workspace and reuses the Parano1d crates, networking, chain, mempool and transaction code. Because of that, my Android/mobile crates currently need to live inside a Parano1d checkout/workspace in order for me to compile and develop the Android application efficiently.

So even if the Android code remains completely separate from the Parano1d core repository, I still need a workflow where I can regularly pull upstream Parano1d changes into my working tree and keep the mobile code alongside it locally.

I am not asking for the Android application or mobile crates to be merged anymore. I mainly want to keep ParanO1c as a clean downstream project that can follow Parano1d closely without making upstream updates unnecessarily difficult.

If you have a preferred way for downstream projects to depend on or track the Parano1d workspace, I would be happy to follow that structure.

Understood, and I agree that ParanO1c should remain a separate community product and repository. I just want to clarify one technical point about the way I currently maintain it. ParanO1c is built directly on top of the Parano1d workspace and reuses the Parano1d crates, networking, chain, mempool and transaction code. Because of that, my Android/mobile crates currently need to live inside a Parano1d checkout/workspace in order for me to compile and develop the Android application efficiently. So even if the Android code remains completely separate from the Parano1d core repository, I still need a workflow where I can regularly pull upstream Parano1d changes into my working tree and keep the mobile code alongside it locally. I am not asking for the Android application or mobile crates to be merged anymore. I mainly want to keep ParanO1c as a clean downstream project that can follow Parano1d closely without making upstream updates unnecessarily difficult. If you have a preferred way for downstream projects to depend on or track the Parano1d workspace, I would be happy to follow that structure.
Aquacongas commented 2026-08-29 16:45:48 +00:00 (Migrated from github.com)

Would you be open to accepting only the three small platform-specific compatibility changes that I currently have to reapply after every Parano1d update?

They are:

noid_p2p/src/network.rs — Android-specific handling around the libp2p DNS builder
noid_chain/src/storage/mdbx_store.rs — smaller MDBX virtual map size on Android
noid_chain/src/storage/snapshot_staging.rs — same-directory rename on Android instead of hard_link

These changes can stay fully isolated behind #[cfg(target_os = "android")], so they do not change the current desktop/mainnet behavior.

If you are okay with that, I can prepare a very small PR containing only these three compatibility changes, with no Android app, no mobile crates, no FFI and no ParanO1c-specific code.

That would make maintaining ParanO1c much easier because I would no longer need to patch the same core files after every upstream release.

Would you be open to accepting only the three small platform-specific compatibility changes that I currently have to reapply after every Parano1d update? They are: noid_p2p/src/network.rs — Android-specific handling around the libp2p DNS builder noid_chain/src/storage/mdbx_store.rs — smaller MDBX virtual map size on Android noid_chain/src/storage/snapshot_staging.rs — same-directory rename on Android instead of hard_link These changes can stay fully isolated behind #[cfg(target_os = "android")], so they do not change the current desktop/mainnet behavior. If you are okay with that, I can prepare a very small PR containing only these three compatibility changes, with no Android app, no mobile crates, no FFI and no ParanO1c-specific code. That would make maintaining ParanO1c much easier because I would no longer need to patch the same core files after every upstream release.
ignotusnemo commented 2026-08-29 23:33:59 +00:00 (Migrated from github.com)

This is exactly what a downstream fork is for. Keep the Android compatibility changes as commits in your fork and merge or rebase new upstream releases into your branch. Git will preserve those changes automatically, except where an actual conflict requires downstream resolution. Parano1d does not currently support Android as a core target, so I will not add target-specific code without an official support policy, CI coverage and security review. Please maintain these patches in ParanO1c.

This is exactly what a downstream fork is for. Keep the Android compatibility changes as commits in your fork and merge or rebase new upstream releases into your branch. Git will preserve those changes automatically, except where an actual conflict requires downstream resolution. Parano1d does not currently support Android as a core target, so I will not add target-specific code without an official support policy, CI coverage and security review. Please maintain these patches in ParanO1c.

Pull request closed

Sign in to join this conversation.
No description provided.