SatoshiQaziMuhammed 35c71062f0 Strip native libraries; XCM by genesis; CodeQL for Kotlin; bridge credits in history (#31)
* Strip native libraries in the app and keep light client line tables

The app module named no NDK, so AGP expected its default 27.0 against the 26.1 that CI installs,
could not strip any native library and made no native-debug-symbols.zip for Play. Pin 26.1 in the
app. The light client now keeps line tables for that symbol file; the packaged library is still
stripped to 8.6 MB.

Also adds an XCM encoding test for PezkuwiChain networks. This commit points WESTEND at Zagros
to check that the test fails against that change.

* Fix the encoding test's read of the interior field

* Encode PezkuwiChain networks by genesis in XCM

WESTEND held a stale genesis labelled Zagros. The runtimes declare ThisNetwork as ByGenesis and
the XCM v5 NetworkId has no Westend or Zagros variant, so the named mapping is removed and every
PezkuwiChain network is encoded as ByGenesis.

* Run CodeQL for every language on hosted runners, Kotlin with a build

Default setup analyses Java without a build and leaves out every Kotlin file, and the Java job on the
self-hosted runner stopped at the NDK install because sudo asks for a password, so Kotlin had not been
analysed since February. One matrix job covers actions, JavaScript/TypeScript, Rust and Java/Kotlin.

* Use CodeQL Action v4, v3 is deprecated in December 2026

* Build for CodeQL without Gradle and Kotlin daemons so the analysis has the memory

* Show incoming USDT bridge credits in history without a refresh

The realtime transfer extractor for assets pallets knew only transfer and transfer_keep_alive. The
bridge credits with transfer_approved, spending the multisig's allowance, so a credit appeared only
after the indexer caught up and the user refreshed. transfer_approved is now a transfer from owner to
destination; the signing delegate is not the sender.

* Stop the light client five minutes after RPC is back

A chain registered with the light client kept syncing for as long as the process lived. Measured on
the emulator over 5-minute windows, that was about 14 MB of data an hour and 2% of a core while the
wallet read nothing from it.

Once RPC has stayed connected for five minutes after a fallback, the connection releases the light
client: LightClients unregisters the chain, a relay chain only after its teyrchains. The engine gains
remove_chain. Its database saver now checks, under the registry lock, that the chain is still
registered: smoldot panics on a request to a removed chain. The next fallback starts cold from the
saved database.

* Refresh light client specifications from the signed config while RPC works

The light client started from the checkpoint the APK was built with, so a first fallback months after
a release warp-synced from months back, and on a phone that never fell back there is no saved database
to help. The fallback is wanted when RPC is blocked, and then the config repository may be blocked too.

On the first RPC connection of the process, each chain's specification is fetched from the config
repository through the app's HTTP client, which checks it against the signed targets and falls back to
the mirrors. It is kept when it is the same chain (id and genesis state root) with a later checkpoint;
an older file never rolls the checkpoint back. Registration uses the kept file when it is later than the
APK's own.

* Close the light client's peer connections once its last chain is removed

smoldot keeps its peer-to-peer network service, with the connections in it, for as long as the client
lives, so removing every chain left them open: on the emulator, four libp2p connections were still up
eleven minutes after the release, and data use stayed above the RPC-only level. The engine now
replaces the client once no chain and no loopback connection is left; the connections close about 20 s
later, when the attempts under way finish.

The database saver now checks a per-registration number instead of the smoldot chain id, which smoldot
reuses after a removal: a saver of a removed chain could otherwise keep running for the next chain
that got the same id. A connection whose chain is removed between the handshake and its setup now
ends instead of panicking.

* Obfuscate the app's own classes and build the R8 variant in pull requests

-keep class io.novafoundation.nova.** { *; } with -keepnames left 2.6% of the app's 26,602 classes
renamed in the 1.3.0 Play build (15.6% of all classes). It is replaced by keeping only the field names
of the app's classes, which Gson reads by name where a class has no @SerializedName, so class and method
names are obfuscated. No persisted value or reflective lookup in the app depends on a class or method
name: class names appear only in logs and in an in-memory cache key.

@JavascriptInterface methods had no rule of their own; the blanket keep covered the DApp browser's web3
bridge, its integrity check and the Transak bridge. They are kept explicitly.

Pull requests built only the unminified develop variant, so an R8 break would first show in the Play
build. A second job builds releaseTest (the release rules, debug-signed) and uploads its APK and mapping.

* Give the releaseTest build the debug package, which the CI Firebase config knows

* Build releaseTest under the production package, the one its Firebase config has

* Stop keeping every app class under the JNI rule

-keep class io.novafoundation.nova.** { native <methods>; } keeps every class the pattern matches,
whether or not it has a native method, so the app's class names stayed unobfuscated after the blanket
keep went: 2.6% of its classes were renamed in the R8 build. The rule under it already keeps the names
of classes with native methods and of those methods, which is what JNI binds by name; the Rust
bindings look up no other app class.

* Keep TypeToken and Retrofit generic signatures under R8 full mode

The R8 build failed to map every chain from the local database: R8 full mode keeps generic signatures
only on kept classes, and the app's anonymous TypeToken subclasses had been kept by the blanket rule.
These are the rules Gson 2.11 and Retrofit 2.10 ship; the app is on Gson 2.10.1 and Retrofit 2.9.0.

* Keep constructors of the app's classes so Gson can instantiate its models

The R8 build failed to read the DApp list: R8 full mode had made DappMetadataResponse abstract because
nothing in the code instantiates it, and Gson does so reflectively. It matches none of the name
patterns the rules keep models by. Keeping constructors costs no obfuscation, since they are all named
<init>.

* Keep the type argument of web3j TypeReference subclasses under R8 full mode

* Run R8 in compatibility mode

After the app's own classes became obfuscatable, the full-mode R8 build kept breaking reflective
decoding in new places: TypeToken and TypeReference subclasses lost their type argument, a Gson model
was made abstract, and SubQueryResponse<T> lost its class signature so a proxy query decoded to a
LinkedTreeMap. Full mode keeps generic signatures only on explicitly kept classes, and this code base
has many generic models outside any name pattern. Compatibility mode keeps them everywhere under
-keepattributes Signature and does not make uninstantiated classes abstract; obfuscation is unchanged.

* Allow the java.beans classes Jackson's Java 7 support refers to, missing on Android
2026-11-03 18:07:55 +04:00
2026-02-12 05:19:41 +03:00
2026-02-12 05:19:41 +03:00
2026-02-12 05:19:41 +03:00

Pezkuwi Wallet Android

Next generation mobile wallet for Pezkuwichain and the Polkadot ecosystem.

About

Pezkuwi Wallet is a next-generation mobile application for the Pezkuwichain and Polkadot ecosystem. It provides a transparent, community-oriented wallet experience with convenient UX/UI, fast performance, and strong security.

Key Features:

  • Full Pezkuwichain support (HEZ & PEZ tokens)
  • Full Polkadot ecosystem compatibility
  • Staking, Governance, DeFi
  • NFT support
  • Cross-chain transfers (XCM)
  • Hardware wallet support (Ledger, Polkadot Vault)
  • WalletConnect v2
  • Push notifications

Native Tokens

Token Network Description
HEZ Relay Chain Native token for fees and staking
PEZ Asset Hub Governance token

Build Instructions

Clone Repository

git clone git@github.com:pezkuwichain/pezkuwi-wallet-android.git

Install NDK

Install NDK version 26.1.10909125 from SDK Manager: Tools -> SDK Manager -> SDK Tools -> NDK (Side by Side)

Install Rust

Install Rust by following official instructions.

Add Android build targets:

rustup target add armv7-linux-androideabi
rustup target add i686-linux-android
rustup target add x86_64-linux-android
rustup target add aarch64-linux-android

Update local.properties

Add the following lines to your local.properties:

ACALA_PROD_AUTH_TOKEN=mock
ACALA_TEST_AUTH_TOKEN=mock
CI_KEYSTORE_KEY_ALIAS=mock
CI_KEYSTORE_KEY_PASS=mock
CI_KEYSTORE_PASS=mock
DEBUG_GOOGLE_OAUTH_ID=mock
RELEASE_GOOGLE_OAUTH_ID=mock
DWELLIR_API_KEY=mock
EHTERSCAN_API_KEY_ETHEREUM=mock
EHTERSCAN_API_KEY_MOONBEAM=mock
EHTERSCAN_API_KEY_MOONRIVER=mock
INFURA_API_KEY=mock
MERCURYO_PRODUCTION_SECRET=mock
MERCURYO_TEST_SECRET=mock
MOONBEAM_PROD_AUTH_TOKEN=mock
MOONBEAM_TEST_AUTH_TOKEN=mock
MOONPAY_PRODUCTION_SECRET=mock
MOONPAY_TEST_SECRET=mock
WALLET_CONNECT_PROJECT_ID=mock

Note: Firebase and Google-related features (Notifications, Cloud Backups) require proper configuration.

Build Types

  • debug: Uses fixed keystore for Google services
  • debugLocal: Uses your local debug keystore
  • release: Production build

Supported Languages

  • English
  • Turkish (Türkçe)
  • Kurdish Kurmanji (Kurmancî)
  • Spanish (Español)
  • French (Français)
  • German (Deutsch)
  • Russian (Русский)
  • Japanese (日本語)
  • Chinese (中文)
  • Korean (한국어)
  • Portuguese (Português)
  • Vietnamese (Tiếng Việt)
  • And more...

Resources

License

Pezkuwi Wallet Android is available under the Apache 2.0 license. See the LICENSE file for more info.

Based on Nova Wallet (https://novawallet.io) - © Novasama Technologies GmbH

© Dijital Kurdistan Tech Institute 2026

S
Description
No description provided
Readme
200 MiB
1 Watchers 0 Forks
Languages
Kotlin 99.2%
Rust 0.6%
Java 0.1%