Root cause: Token symbol mismatch between TokenSwap component and WalletContext
- WalletContext stored balance with key 'USDT'
- TokenSwap used symbol 'wUSDT' for lookups
- This caused balances['wUSDT'] to return undefined
- Triggered false "insufficient balance" errors
Changes:
- Updated TokenSwap.tsx to use 'USDT' symbol consistently
- Fixed token symbol in AVAILABLE_TOKENS array
- Updated asset ID mapping in swap transaction logic
- Fixed swap history token display
Also includes:
- Added new DEX components (SwapInterface, PoolBrowser, etc.)
- Added TypeScript type definitions for DEX
- Added DEX utility functions
- Removed obsolete test scripts
- Updated WalletContext with USDT balance support
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Make AddLiquidityModal dynamic to support all pool combinations (HEZ-PEZ, HEZ-USDT, PEZ-USDT)
- Pass asset0 and asset1 props from PoolDashboard to AddLiquidityModal
- Rename balance key from wUSDT to USDT in WalletContext for user-facing consistency
- Display USDT instead of wUSDT in PriceChart for better UX
- Backend still uses wUSDT (Asset ID 2), but frontend shows USDT to users
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- check-asset-state.mjs: Asset state verification
- check-balances.mjs: Balance checking utilities
- check-founder-balances.mjs: Founder account balance checks
- check-hez-balance.mjs: HEZ token balance verification
- check-pool-balances-detailed.mjs: Detailed pool balance analysis
- create-all-pools.mjs: Automated pool creation
- create-pez-wusdt-pool.mjs: PEZ/wUSDT pool setup
- mint-and-create-pools.mjs: Mint tokens and create pools
- mint-whez.mjs: wHEZ minting utility
- verify-pool-state.mjs: Pool state verification
- wrap-hez-and-create-all-pools.mjs: HEZ wrapping and pool setup
These scripts support DEX pool management and testing for beta testnet.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Major improvements to wallet dashboard and DEX functionality:
## USDT Integration
- Add wUSDT (Asset ID 2) support with 6 decimal precision
- Display USDT balances in wallet dashboard
- Integrate USDT into swap and pool interfaces
## Dynamic Token Pricing
- Fetch real-time HEZ and PEZ prices from liquidity pools
- Calculate USD values using pool reserve ratios
- Display live USD equivalent for token balances
## User Experience Improvements
- Hide wrapped tokens (wHEZ, wUSDT) from user interface
- Show only HEZ, PEZ, USDT as user-facing tokens
- Handle wrapping/unwrapping transparently in backend
- Add balance validation before swap transactions
- Prevent insufficient balance swaps with clear warnings
## Pool Dashboard Enhancements
- Support multiple pool pairs (HEZ/PEZ, HEZ/USDT, PEZ/USDT)
- Dynamic pool selection interface
- User-friendly token names throughout pool interface
## Technical Improvements
- Correct decimal handling (6 for USDT, 12 for others)
- Proper pool account ID derivation using blake2 hash
- Balance subscriptions for real-time updates
- Custom token support with Add Token modal
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Switch pool display from wHEZ/PEZ to PEZ/wUSDT
- Fix wUSDT decimal conversion (1e6 instead of 1e12)
- Update TokenSwap to support beta testnet endpoint
- Add wallet reconnection on network change
- Update API endpoint to wss://beta.pezkuwichain.com
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- README_DEX_IMPROVEMENTS.md: Belgekirin û rave kirinên DEX
- check-pool.mjs: Amûra kontrolkirina rewşa pool
- create-beta-pool.mjs: Script ji bo çêkirina pool li beta testnet
- create-beta-pool.js: Versiyona JavaScript ya scripta çêkirina pool
Ev pel ji bo pêşkeftin û testing in.
🤖 Bi [Claude Code](https://claude.com/claude-code) re hate çêkirin
Co-Authored-By: Claude <noreply@anthropic.com>
- poolAccountIds fonksiyona API tune ne, ji ber vê hataye derket
- Niha pool account bi AccountIdConverter û blake2 hash tê hesabkirin
- PalletId "py/ascon" bi (u32, u32) poolId re tê hash kirin
- Ev guhertin hem ji bo AddLiquidityModal û hem jî PoolDashboard
Taybetmendî:
✅ Add liquidity niha bi rast dixebite
✅ Pool metrics rast têne xuyakirin
✅ Reserve balances rast têne hesabkirin
✅ LP position tracking çêbû
🤖 Bi [Claude Code](https://claude.com/claude-code) re hate çêkirin
Co-Authored-By: Claude <noreply@anthropic.com>
- Add AddLiquidityModal with automatic HEZ to wHEZ wrapping and 10% slippage tolerance
- Add RemoveLiquidityModal with automatic wHEZ to HEZ unwrapping
- Add PoolDashboard component with metrics, APR calculation, and impermanent loss calculator
- Add /pool route and integrate Pool button in WalletDashboard
- Display real-time pool reserves, TVL, and user positions
- Support batched transactions for optimal UX
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed default endpoint from ws://127.0.0.1:9944 to wss://beta.pezkuwichain.io
- Preparing for multi-validator beta testnet deployment
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The path is an array of tuples [[assetId, amount], [assetId, amount]],
not an array of objects. Fixed to access asset ID at index 0 of each tuple.
Previous code was trying to access object properties (nativeOrAsset.asset)
which don't exist on arrays, causing all swaps to default to HEZ→HEZ.
The SwapExecuted event has 5 fields (who, send_to, amountIn, amountOut, path),
not 4. The old code was missing send_to, which caused the path (asset array)
to be assigned the recipient address instead, resulting in all swaps showing
as HEZ→HEZ regardless of actual token pairs.
This fixes the swap history display to show correct token symbols.
- Fixed path array parsing for SwapExecuted events
- Handle different Polkadot.js enum formats (nativeOrAsset vs NativeOrAsset)
- Added toJSON() conversion for proper array parsing
- Now correctly shows HEZ↔PEZ swaps instead of HEZ→HEZ
- Applied fix to both initial history load and post-swap refresh
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Reduced file size from 719KB to 243KB (66% reduction)
- Updated DKstate.png with optimized version
- Improved page load performance
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added DKstate.png to public folder (719KB PNG)
- Replaced Kurdish Flag CDN image with local DKstate background
- Updated alt text to "DKstate Background"
- Maintained gradient overlay styling
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added PezkuwiChain logo to public folder (179KB PNG)
- Replaced CDN image with local logo in RewardDistribution component
- Updated alt text to "PezkuwiChain Logo"
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fetch trust score from blockchain via api.query.trust.trustScores
- Display trust score in AccountBalance component (Account Info card)
- Show between Address and Source fields with Award icon
- Use purple-cyan gradient styling for visual consistency
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added comprehensive console logs to debug trust score fetching:
- API readiness check
- Account availability check
- Query execution log
- Detailed error logging with stack trace
This will help identify the exact point of failure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed from `trustScoreOf` to `trustScores` to match the actual
storage item name in pallet_trust. Polkadot.js API uses storage names,
not getter function names.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fetch trust score from pallet_trust via API
- Display score in WalletModal with Award icon
- Shows user's current trust score from blockchain
- Gradient styling (purple to cyan) for visual appeal
- Fallback to '-' when API not ready or score unavailable
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fetch total staked tokens from pallet_staking.erasTotalStake()
- Count unique voters from pallet_conviction_voting.votingFor.keys()
- Display real-time data instead of hardcoded values
- Shows '-' when data is unavailable (e.g. no current era)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated HeroSection to fetch real governance data:
- Active Proposals from pallet_referenda (was hardcoded to 127)
- Replaced all hardcoded stats with dynamic blockchain queries
- Shows "-" for unavailable data (totalVoters, tokensStaked, trustScore)
- Real-time updates using PolkadotContext API
Now homepage shows actual on-chain referendum count instead of mock data.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Connected governance overview to actual blockchain data:
- Active proposals from pallet_referenda
- Treasury balance from treasury account
- Parliament (Council) members from pallet_collective
- Real-time data fetching using PolkadotContext API
- Replaced mock data with live blockchain queries
Todo: Add total voters and participation rate calculation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added Pezkuwi whitepaper PDF to repository and updated navigation:
- Added public/Whitepaper.pdf (738KB)
- Updated Docs links to download whitepaper from GitHub
- Both header and footer navigation now link to GitHub raw PDF
- Users can download whitepaper by clicking Docs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added animated Kurdistan-themed loading indicator that displays during swap transactions:
- KurdistanSun component with 21 rays (Kurdistan flag symbolism)
- White center sun with glow effects
- Rotating colored halos: green (outer), red (middle), yellow (inner)
- Full-screen overlay with backdrop blur during processing
- Fixed timing: dialog closes before animation shows
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Cleaned up console.log statements added during debugging:
- Removed verbose logging from ProfileSettings loadProfile
- Removed verbose logging from ProfileSettings updateProfile
- Removed verbose logging from Dashboard fetchProfile
Kept only essential error logging for production.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
1. Created migration 004_create_upsert_function.sql:
- Creates upsert_user_profile() function with SECURITY DEFINER
- Bypasses RLS to allow profile creation/updates
- Only accessible to authenticated users via auth.uid()
2. Updated ProfileSettings.tsx:
- Changed from direct upsert to RPC function call
- Updated updateProfile() to use supabase.rpc()
- Updated updateNotificationSettings() to use same function
This solves the RLS policy violation by using a secure
server-side function that properly handles authentication.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated migration 003 to properly handle RLS:
- Make username nullable with default
- Drop all existing policies and recreate them
- Add proper INSERT policy with WITH CHECK clause
- Add UPDATE policy with both USING and WITH CHECK
This fixes RLS error blocking profile creation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
1. Created migration 003_fix_profile_creation.sql:
- Added INSERT policy for profiles table
- Made username nullable with default value
- Created upsert_profile function for safe upserts
2. Updated ProfileSettings.tsx:
- Changed from .update() to .upsert()
- Added id field to upsert data
- Added loadProfile() call after save to refresh state
This fixes the issue where users couldn't update their profile
because no profile row existed in the database.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added detailed console logging to track data flow:
- ProfileSettings: Log data being saved and save responses
- ProfileSettings: Log data being loaded when page opens
- Dashboard: Log profile data being fetched and set to state
This will help identify where profile data is being lost between
save in ProfileSettings and display in Dashboard.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Issue: Dashboard was throwing 400 Bad Request when updating profiles table
Root Cause:
- Dashboard tried to update profiles.email_verified column
- But this column doesn't exist in profiles table
- Migration only has: username, email, full_name, avatar_url, referral fields
Solution:
- Removed sync logic that updates profiles.email_verified
- Email verification is now ONLY read from Supabase Auth (user.email_confirmed_at)
- No need to duplicate verification status in profiles table
Benefits:
- No more 400 errors
- Single source of truth (Supabase Auth)
- Cleaner code, less database writes
UI still works correctly:
- Account Status card checks: user?.email_confirmed_at || profile?.email_verified
- Since user.email_confirmed_at exists, profile.email_verified is never needed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root Cause:
- Dashboard was checking profiles.email_verified column
- But Supabase Auth uses user.email_confirmed_at field
- This caused verified emails to show as "Unverified"
Changes:
1. Dashboard now checks BOTH sources:
- Primary: user.email_confirmed_at (Supabase Auth)
- Fallback: profile.email_verified (profiles table)
2. Auto-sync profiles table:
- When loading profile, sync email_verified from Auth
- Updates profiles table if verification status differs
3. UI Improvements:
- Show verification date in Account Status card
- Display "Verified" badge next to email instead of button
- Hide warning message if email is verified
- Only show "Verify Email" button if truly unverified
This ensures consistent verification status across:
- Account Status card (top)
- Profile tab (email field)
- Security tab (warning message)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented comprehensive tiki (role) system integration with Dashboard:
New Features:
- Created src/lib/tiki.ts utility library based on real pallet-tiki implementation
- Added fetchUserTikis() to query user roles from blockchain
- Implemented role scoring, categorization, and display helpers
- Added "Roles & Tikis" tab to Dashboard showing:
* Primary role from highest-scoring tiki
* Total tiki score (sum of all role scores)
* All assigned roles with emoji indicators
* Role categories (Government, Judiciary, Education, etc.)
* Connected wallet address
Role System Details:
- 49 different tiki types from pallet-tiki (Serok, Wezir, Dadger, etc.)
- Role assignment types: Automatic, Appointed, Elected, Earned
- Score-based hierarchy (10-250 points per role)
- Dynamic role display based on blockchain state
- Fallback to "Member" when no wallet connected or no tikis assigned
Dashboard Improvements:
- Fixed email verification using Supabase auth.resend()
- Fixed Edit Profile button to navigate to /profile/settings
- Added Tiki Score card showing total score and role count
- Expanded stats grid to 4 columns (Status, Join Date, Role, Tiki Score)
- Real-time role updates when wallet connects/disconnects
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed white/light text on white/light backgrounds across multiple pages by adding text-gray-900 classes to ensure proper contrast and readability. This addresses the issue where text was unreadable until hover/click on delegation, proposal, swap, and other pages.
Changes:
- DelegationManager: Added dark text to green-50 TabsList
- DelegateProfile: Fixed text color in blue-50 and green-50 Alert components
- ProposalWizard: Added dark text to green-50 success Alert
- Dashboard: Fixed text color in yellow-50 verification warning
- TokenSwap: Added dark text to all gray-50 and blue-50 containers (6 instances)
- DiscussionThread: Fixed markdown help card with gray-50 background
- FundingProposal: Added dark text to yellow-50 milestone warning
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem: Translation keys were showing on screen instead of actual text
- "hero.exploreGovernance" instead of "Explore Governance"
- "nav.proposals" instead of "Proposals"
- "common.backToHome" instead of "Back to Home"
Root Cause: en.ts had only 59 lines while en.json had 244 lines
- config.ts imports en.ts (not en.json)
- Missing keys caused i18n to display the key itself
Solution: Converted all keys from en.json to en.ts flat format
- Added all 280+ translation keys
- Includes: nav, hero, governance, identity, proposals, delegation,
profile, common, notifications, websocket, auth, wallet, login
- Now matches the complete en.json structure
Result: All translation keys now display proper English text
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>