- Use PezkuwiExchange.png logo instead of emoji for exchange app icon
- External link opens exchange.pezkuwichain.io in new tab (noopener)
- No auth required (exchange is publicly accessible)
- Added imgIcon and href fields to AppItem interface
B2B button now opens Bereketli (bereketli.pezkiwi.app) embedded in an
iframe. PWAP exchanges the user's Supabase JWT for a Bereketli JWT
via the existing /v1/auth/exchange endpoint, then passes tokens to
the iframe via postMessage. User never sees a login screen.
- New /bereketli route (ProtectedRoute)
- Token caching in localStorage (10 min TTL)
- Camera + geolocation permissions on iframe
- Desktop and mobile layouts supported
- Re-auth on token expiry via postMessage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Section titles (FINANCE, GOVERNANCE, SOCIAL, EDUCATION) and all app
names are now translated via i18n keys instead of hard-coded English.
Added translations for all 6 languages (en, tr, kmr, ckb, ar, fa).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mobile app is distributed via Play Store DApps browser, no longer
built/deployed from this repo. Deploy and security audit now only
depend on the web job passing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mobile users (<768px) now see a native app-style home page with:
- Green gradient header with avatar, greeting, language/wallet/notification
- Horizontal scrollable score cards (auth-aware: login prompt for guests)
- App grid sections (Finance, Governance, Social, Education) with 4-col layout
- Bottom tab bar (Home / Citizen / Referral)
- MobileShell wrapper for consistent mobile navigation across pages
BeCitizen page redesigned for mobile with full-viewport hero screen,
scroll-to-reveal content, and compact benefits/process cards.
New Identity page (/identity) with realistic Kurdistan Republic ID card
and passport design. Users can fill personal info, upload photo from
camera/gallery, and save to device (localStorage only).
Desktop layout completely untouched. i18n keys added for all 6 languages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mobile users only see the Mainnet detail card (WebSocket endpoint,
Chain ID, explorer button, services grid). The individual chain
cards (Staging, Testnet, Beta, etc.) and subdomains box are hidden
on mobile and visible on md+ screens.
Mobile users only see the Mainnet detail card (WebSocket endpoint,
Chain ID, explorer button, services grid). The individual chain
cards (Staging, Testnet, Beta, etc.) and subdomains box are hidden
on mobile and visible on md+ screens.
Google blocks OAuth in WebViews (disallowed_useragent policy).
Detect WebView and hide the Google button, users in DApps browser
use email/password instead. Google sign-in still works in real
browsers (Chrome, Safari, etc).
Google blocks OAuth in WebViews (disallowed_useragent policy).
Detect WebView and hide the Google button, users in DApps browser
use email/password instead. Google sign-in still works in real
browsers (Chrome, Safari, etc).
Mobile users now see ChainSpecs (Mainnet card) right below the hero
section instead of scrolling far down. "Learn More" button hidden on
mobile since Mainnet card replaces its function.
Mobile users now see ChainSpecs (Mainnet card) right below the hero
section instead of scrolling far down. "Learn More" button hidden on
mobile since Mainnet card replaces its function.
- Call refreshInbox() immediately after setupKey/unlockKey so messages
decrypt instantly instead of waiting for 12s polling interval
- Query both current and previous era to prevent message loss at era
boundaries
- Add toJSON fallback for robust field parsing in getInbox
- Improve debug logging with era, address, and field diagnostics
- Call refreshInbox() immediately after setupKey/unlockKey so messages
decrypt instantly instead of waiting for 12s polling interval
- Query both current and previous era to prevent message loss at era
boundaries
- Add toJSON fallback for robust field parsing in getInbox
- Improve debug logging with era, address, and field diagnostics
messaging.inbox and messaging.sendCount are StorageDoubleMaps keyed by
(era, address). Passing [era, address] as a single array produced empty
results; split into two arguments so the API constructs the correct
storage key.
messaging.inbox and messaging.sendCount are StorageDoubleMaps keyed by
(era, address). Passing [era, address] as a single array produced empty
results; split into two arguments so the API constructs the correct
storage key.
- Check isPalletAvailable() BEFORE requesting wallet signature
- All chain queries return safe defaults if pallet not in runtime
- Show orange banner when messaging pallet needs runtime upgrade
- Add floating back-to-home button on messaging page
- Check isPalletAvailable() BEFORE requesting wallet signature
- All chain queries return safe defaults if pallet not in runtime
- Show orange banner when messaging pallet needs runtime upgrade
- Add floating back-to-home button on messaging page
- x25519 ECDH + XChaCha20-Poly1305 encryption via @noble libs
- Key derivation from wallet signRaw, private key held in memory only
- Messaging pallet integration (registerEncryptionKey, sendMessage, inbox)
- Inbox polling every 12s, auto-decrypt when key unlocked
- ComposeDialog with recipient key validation and 512-byte limit
- Settings moved from grid to nav bar gear icon, PEZMessage takes its slot
- i18n translations for all 6 languages (en, tr, kmr, ckb, ar, fa)
- x25519 ECDH + XChaCha20-Poly1305 encryption via @noble libs
- Key derivation from wallet signRaw, private key held in memory only
- Messaging pallet integration (registerEncryptionKey, sendMessage, inbox)
- Inbox polling every 12s, auto-decrypt when key unlocked
- ComposeDialog with recipient key validation and 512-byte limit
- Settings moved from grid to nav bar gear icon, PEZMessage takes its slot
- i18n translations for all 6 languages (en, tr, kmr, ckb, ar, fa)
1. Fixed enum map missing NotStarted at index 0, causing all status
indices to be off by one (ReferrerApproved decoded as PendingReferral)
2. Restricted founder bypass to only show applications with no referrer,
not all applications regardless of referrer