Adds a real EVM address for the Founder account - derived via standard
BIP44 (m/44'/60'/0'/0/0) from the same already-verified mnemonic used
for the substrate address, since no dedicated founder EVM wallet record
exists anywhere. Ethereum's USDT-ERC20 assetId isn't a fixed integer
like Substrate assets (EvmAssetsSyncService hashes the contract address
at sync time), so it's resolved dynamically via ChainAssetDao instead
of hardcoded in the JSON fixture.
This closes the loop on all 3 originally-reported symptoms from this
investigation: Tron disabled (fixed, unaffected by any revert), Pezkuwi
tokens missing (fixed - ordering bug), USDT on Polkadot AH/Ethereum
missing (Polkadot AH already covered, Ethereum added here). Ethereum
ERC20 sync uses an entirely separate mechanism (EthereumRequestsAggregator,
not Substrate's StorageSubscriptionMultiplexer) so it was likely never
actually broken by anything this session touched - this verifies that
directly instead of assuming it from code reading.
Public TronGrid rate-limits aggressively, and this test now runs on
every PR (plus its own 8h schedule) - a bare 429 was failing runs for
a transient, infrastructure reason unrelated to code correctness. Add
exponential backoff retry instead of treating it as an accepted flake.
Also required-status-check balances_test.yml's run-tests job on main
now that both this and the wallet-utils phantom-asset fix are confirmed
clean - it was deliberately left optional until proven, per "don't
promise gates you haven't verified."
removeAll { assetDao.getAsset(...) } failed to compile ("Suspension
functions can only be called within coroutine body"). filter{} is
unambiguously inline and safe for a suspend call inside a suspend
function; pair it with the plain Collection-based removeAll(elements)
overload instead, which takes no lambda at all.
Was HEZ-on-Asset-Hub-only. Now data-driven from wallet-utils' new
pezkuwi_assets_for_testBalance.json (TEST_ASSETS_URL), asserting every
asset - HEZ/PEZ/USDT/DOT/ETH/BTC across Pezkuwi's 3 chains - gets an
assets DB row written via a single shared BalancesUpdateSystem run, not
just one asset on one chain. Failure message lists exactly which assets
never synced, by name and chain.
Root cause found via 4 rounds of CI diagnostics: HEZ (native asset) on
Pezkuwi Asset Hub was correctly present+enabled in the Chain domain model,
correctly dispatched to NativeAssetBalance, and its System.Account storage
key was correctly computed - but the raw subscriptionBuilder.subscribe(key)
call never actually reached the RPC connection, with zero exceptions and
zero data, while the chain's 5 other assets (all statemine-type, all using
the same SharedRequestsBuilder) synced fine. The same NativeAssetBalance
code worked correctly for every OTHER native asset on every OTHER chain
tested, ruling out a generic bug in the class.
Switched startSyncingBalance() to the typed remoteStorage.subscribe { }
DSL (metadata.system.account.observeWithRaw) - the same mechanism this
class's own subscribeAccountBalanceUpdatePoint() and PooledBalanceUpdater/
BalanceLocksUpdater already use successfully on the same busy chain
connection, instead of the raw subscriptionBuilder.subscribe(key) call
that appears to silently drop registration in that specific configuration.
Also removes the diagnostic logging added during the investigation
(BalancesUpdateSystem's per-chain balancesSync trace, FullSyncPaymentUpdater's
per-chain asset dump) - kept the one genuinely valuable permanent addition,
the "listenForUpdates() threw synchronously" error log for a previously
silent failure mode.
First run of this test produced zero BalancesDiag output at all - not even a
single balancesSync() call for any chain. Root cause: BalancesUpdateSystem.start()
is a cold flow only ever collected by RootInteractor, which is wired to the root
Activity/ViewModel lifecycle. This bare instrumented test never launches that
Activity, so the pipeline was never started - the test's own timeout, not the
production bug, explained the failure. Now collect the same AssetsFeatureApi.
updateSystem instance directly instead of relying on app UI lifecycle.
BalancesUpdateSystem.launchChainUpdaters() wrapped updater.listenForUpdates() in a
try/catch that discarded synchronous exceptions with zero logging - a silent failure
point that could explain a chain's balances never syncing with no trace in logcat.
Also add a full-architecture instrumented test that persists a real watch-only
MetaAccount and polls AssetDao through the actual BalancesUpdateSystem pipeline,
instead of bypassing it like the existing BalancesIntegrationTest does.
Tron is a REST API (TronGrid), not a Substrate runtime, so it never goes
through BalancesIntegrationTest's chainRegistry-based mechanism at all -
it had zero CI coverage. This exercises the exact TronGridApi the
production app uses for balance reads, via a standalone Retrofit client
(TronGridApi isn't exposed through a public feature API for tests to
reach through the DI graph).
Test account is the mainnet Founder's Tron address, verified live via
TronGrid's public API on 2026-07-09: 3,925.23 TRX native + 625,213.92
USDT-TRC20 - substantial real balances, not a guessed or empty account.
* redesign(colors): purge forbidden magenta/purple from palette
Brand book permits only the Kurdistan palette (kesk/sor/zer/fire) + navy.
Replace the four Nova-legacy violations in common colors.xml (names preserved,
so no references break):
- crowdloan_banner_gradient_start #BD387F -> #009639 (kesk)
- networks_banner_gradient_end #661D78 -> #017A2F (kesk-700)
- chip_on_card_background #443679 -> #3D999EC7 (frosted periwinkle)
- button_wallet_connect_background #353D67 -> #1F2A4D (neutral navy)
Repo-wide grep confirmed no other hardcoded magenta/purple literals or
purple/pink-named resources remain.
* redesign(type): adopt brand fonts (Space Grotesk / Plus Jakarta Sans / JetBrains Mono)
Brand book typography. Add OFL static fonts under common/res/font and repoint
the theme font attrs (consumed app-wide via ?attr/font* in styles.xml):
- fontRegular -> Plus Jakarta Sans Regular (body/UI)
- fontSemiBold -> Plus Jakarta Sans SemiBold
- fontBold/ExtraBold -> Space Grotesk Bold (display: balances, titles)
- fontExtraLight -> Plus Jakarta Sans Light
- Monospace text appearance (addresses/hashes) -> JetBrains Mono
Static TTFs chosen (minSdk 24 < variable-font API 26). All five verified to
cover Turkish + Kurdish Kurmancî glyphs (ş ğ ı İ ê î û ç …).
* redesign(splash): replace map+wordmark logo with Newroz flame brand mark
The first-launch splash logo (ic_loading_screen_logo) showed a Kurdistan map
with a baked-in wordmark. Per the brand book the mark is the Newroz flame.
Rasterized assets/nevroz-fire-flame.svg into the existing 6 density slots
(same pixel dimensions = drop-in, no bg_splash.xml change, transparent WebP so
it composites cleanly over the splash background).
* redesign(onboarding): welcome hero -> Global United States of Pezkuwi
Replace the legacy onboarding hero (ic_create_wallet_background, whose six
density PNGs had inconsistent broken dimensions) with the brand 'Global United
States of Pezkuwi' infographic. Consolidate to a single high-res WebP in
drawable-nodpi (1408x768, 204K vs 1.75MB PNG) and switch the welcome ImageView
scaleType centerCrop -> fitCenter so it shows full and uncropped above the
CTA buttons, per the brand book.
* redesign(assets): purge magenta/purple from raster illustrations
colors.xml only covers named colors; these raster drawables still carried
forbidden magenta/purple/pink pixels. Selectively rotate the 255-350 deg hue
band (purple-magenta-pink) toward kesk green/teal across all densities,
preserving gradients, shapes and the on-brand blues:
- ic_pink_siri, ic_networks_banner_image, ic_no_added_networks,
ic_import_option_hardware, tinder_gov (6 densities each).
Third-party ic_powered_by_oak (OAK Network trademark) left untouched.
crowdloan_banner_image is being handled separately.
* redesign(assets): de-pink crowdloan banner across all densities
The crowdloan banner's magenta sphere was recolored to brand sor red (xxxhdpi).
Propagate that fix to the other five densities by downscaling the corrected
xxxhdpi master (LANCZOS), so every device shows the same brand-clean banner.
Pink-pixel scan now 0% on all six variants.
* chore: remove pre-production debug code (release-blocker)
CHANGELOG_PEZKUWI listed debug code to strip before production; two items were
still live:
- FeeLoaderV2Provider: the fee-retry dialog showed a raw "DEBUG: <err> | Runtime:
<diagnostics>" string to users -> reverted to the localized resource string and
dropped the diagnostics lookup.
- RuntimeFactory: removed the companion lastDiagnostics field and its assignment
(plus the now-dangling diagnostic vars), and the matching log line in the
PezkuwiLiveTransferTest androidTest.
Items #3-#6 were already clean. Repo now has no 'DEBUG:' literals or
lastDiagnostics references. CHANGELOG marked cleaned.
* docs: add BRAND.md — enforceable wallet brand rules
Kurdistan-only palette (no pink/magenta/purple), brand fonts, Newroz flame mark,
a PR brand checklist with a raster pink-scan snippet, the third-party-logo
exception, and the Apache-2.0 attribution rule (keep LICENSE/NOTICE). Points to
the canonical brand book at wiki.pezkuwichain.io/brand.
* release: bump versionName to 1.1.0 (brand-book UI redesign)
Live Play version is 1.0.4; minor bump for the UI redesign. versionCode stays
CI-managed (CI_BUILD_ID). Add the v1.1.0 entry to CHANGELOG_PEZKUWI.
Branch.io was inherited from Nova Wallet fork but never configured.
Removed SDK integration, manifest intent filters, Gradle dependencies,
Dagger DI modules, and string resources. Deep linking now routes
exclusively through app.pezkuwichain.io with verified assetlinks.json.
- Rebuild renderscript-toolkit.aar from source with NDK 27 and 16KB alignment
- Rebuild libsr25519java.so from substrate-sdk source with 16KB alignment
- Realign libsqlcipher.so ELF segments to 16KB (preserves JNI API compatibility)
- Add jniLibs overrides for sr25519java and sqlcipher to replace AAR versions
- All native .so files now have 0x4000 (16KB) LOAD segment alignment