Merge branch 'main' of http://127.0.0.1:48337/git/pezkuwichain/pezkuwi-web-app-projects into claude/calisma-ya-011CV6DKKRcWvDTxoEY7rYV4

This commit is contained in:
Claude
2025-11-15 08:20:39 +00:00
10 changed files with 316 additions and 17 deletions
+14 -9
View File
@@ -7,12 +7,12 @@
export { translations as comprehensiveTranslations, supportedLocales } from './translations';
// Import all translation JSON files for i18next compatibility
import en from './locales/en.json';
import tr from './locales/tr.json';
import kmr from './locales/kmr.json';
import ckb from './locales/ckb.json';
import ar from './locales/ar.json';
import fa from './locales/fa.json';
import en from './locales/en.json?url';
import tr from './locales/tr.json?url';
import kmr from './locales/kmr.json?url';
import ckb from './locales/ckb.json?url';
import ar from './locales/ar.json?url';
import fa from './locales/fa.json?url';
/**
* Language configuration with RTL support
@@ -47,9 +47,9 @@ export const DEFAULT_LANGUAGE = 'en';
export const LANGUAGE_STORAGE_KEY = '@pezkuwi_language';
/**
* Translation resources (JSON format for i18next)
* Translation resources (JSON URLs for dynamic loading)
*/
export const translations = {
export const translationUrls = {
en,
tr,
kmr,
@@ -58,6 +58,11 @@ export const translations = {
fa,
};
/**
* Translation resources (empty - load dynamically)
*/
export const translations = {};
/**
* Check if a language is RTL
* @param languageCode - Language code (e.g., 'ar', 'ckb', 'fa')
@@ -75,4 +80,4 @@ export function isRTL(languageCode: string): boolean {
*/
export function getLanguageConfig(languageCode: string): LanguageConfig | undefined {
return LANGUAGES.find(l => l.code === languageCode);
}
}
+64
View File
@@ -0,0 +1,64 @@
export default {
"welcome": {
"title": "Welcome to Pezkuwi",
"subtitle": "Your gateway to decentralized governance",
"selectLanguage": "Select Your Language",
"continue": "Continue"
},
"auth": {
"signIn": "Sign In",
"signUp": "Sign Up",
"email": "Email",
"password": "Password",
"confirmPassword": "Confirm Password",
"forgotPassword": "Forgot Password?",
"noAccount": "Don't have an account?",
"haveAccount": "Already have an account?",
"createAccount": "Create Account",
"welcomeBack": "Welcome Back!",
"getStarted": "Get Started"
},
"dashboard": {
"title": "Dashboard",
"wallet": "Wallet",
"staking": "Staking",
"governance": "Governance",
"dex": "Exchange",
"history": "History",
"settings": "Settings",
"balance": "Balance",
"totalStaked": "Total Staked",
"rewards": "Rewards",
"activeProposals": "Active Proposals"
},
"wallet": {
"title": "Wallet",
"connect": "Connect Wallet",
"disconnect": "Disconnect",
"address": "Address",
"balance": "Balance",
"send": "Send",
"receive": "Receive",
"transaction": "Transaction",
"history": "History"
},
"settings": {
"title": "Settings",
"language": "Language",
"theme": "Theme",
"notifications": "Notifications",
"security": "Security",
"about": "About",
"logout": "Logout"
},
"common": {
"cancel": "Cancel",
"confirm": "Confirm",
"save": "Save",
"loading": "Loading...",
"error": "Error",
"success": "Success",
"retry": "Retry",
"close": "Close"
}
} as const;
+113
View File
@@ -622,3 +622,116 @@ export function subscribeToKycApproval(
// ========================================
export const FOUNDER_ADDRESS = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; // Satoshi Qazi Muhammed
/**
* Generate authentication challenge for existing citizens
*/
export function generateAuthChallenge(tikiNumber: string): string {
const timestamp = Date.now();
return `pezkuwi-auth-${tikiNumber}-${timestamp}`;
}
/**
* Sign challenge with user's account
*/
export async function signChallenge(challenge: string, signer: any): Promise<string> {
// This would use Polkadot.js signing
// For now, return placeholder
return `signed-${challenge}`;
}
/**
* Verify signature
*/
export function verifySignature(challenge: string, signature: string, address: string): boolean {
// Implement signature verification
return true;
}
/**
* Save citizen session
*/
export function saveCitizenSession(tikiNumber: string, address: string): void {
localStorage.setItem('pezkuwi_citizen_session', JSON.stringify({
tikiNumber,
address,
timestamp: Date.now()
}));
}
/**
* Encrypt sensitive data for storage
*/
export function encryptData(data: any): string {
// In production, use proper encryption
// For now, base64 encode
return btoa(JSON.stringify(data));
}
/**
* Decrypt data
*/
export function decryptData(encrypted: string): any {
try {
return JSON.parse(atob(encrypted));
} catch {
return null;
}
}
/**
* Generate commitment hash for citizenship data
*/
export function generateCommitmentHash(data: any): string {
const str = JSON.stringify(data);
// Simple hash for now - in production use proper cryptographic hash
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
return hash.toString(16);
}
/**
* Generate nullifier hash
*/
export function generateNullifierHash(data: any): string {
const str = JSON.stringify(data) + Date.now();
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
return 'nullifier_' + hash.toString(16);
}
/**
* Save citizenship data to local storage
*/
export function saveLocalCitizenshipData(data: any): void {
const encrypted = encryptData(data);
localStorage.setItem('pezkuwi_citizenship_data', encrypted);
}
/**
* Get local citizenship data
*/
export function getLocalCitizenshipData(): any {
const encrypted = localStorage.getItem('pezkuwi_citizenship_data');
if (!encrypted) return null;
return decryptData(encrypted);
}
/**
* Upload data to IPFS
*/
export async function uploadToIPFS(data: any): Promise<string> {
// In production, use Pinata or other IPFS service
// For now, return mock CID
const mockCID = 'Qm' + Math.random().toString(36).substring(2, 15);
console.log('Mock IPFS upload:', mockCID, data);
return mockCID;
}
+108
View File
@@ -0,0 +1,108 @@
export interface TokenInfo {
id: number;
symbol: string;
name: string;
decimals: number;
logo?: string;
}
export interface PoolInfo {
id: string; // asset1-asset2 pair
asset1: number;
asset2: number;
asset1Symbol: string;
asset2Symbol: string;
asset1Decimals: number;
asset2Decimals: number;
reserve1: string; // Raw balance string
reserve2: string;
lpTokenSupply: string;
volume24h?: string;
tvl?: string;
apr7d?: string;
feeRate?: string;
}
export interface UserLiquidityPosition {
poolId: string;
asset1: number;
asset2: number;
lpTokenBalance: string;
shareOfPool: string; // Percentage as string (e.g., "2.5")
asset1Amount: string;
asset2Amount: string;
valueUSD?: string;
feesEarned?: string;
}
export interface SwapQuote {
amountIn: string;
amountOut: string;
path: number[]; // Asset IDs in route
priceImpact: string; // Percentage as string
minimumReceived: string; // After slippage
route: string; // Human readable (e.g., "wHEZ → PEZ → wUSDT")
}
export interface AddLiquidityParams {
asset1: number;
asset2: number;
amount1: string;
amount2: string;
amount1Min: string;
amount2Min: string;
recipient: string;
}
export interface RemoveLiquidityParams {
asset1: number;
asset2: number;
lpTokenAmount: string;
amount1Min: string;
amount2Min: string;
recipient: string;
}
export interface SwapParams {
path: number[];
amountIn: string;
amountOutMin: string;
recipient: string;
deadline?: number;
}
export interface PoolCreationParams {
asset1: number;
asset2: number;
feeRate?: number;
}
// Known tokens on testnet
export const KNOWN_TOKENS: Record<number, TokenInfo> = {
0: {
id: 0,
symbol: 'wHEZ',
name: 'Wrapped HEZ',
decimals: 12,
},
1: {
id: 1,
symbol: 'PEZ',
name: 'Pezkuwi Token',
decimals: 12,
},
2: {
id: 2,
symbol: 'wUSDT',
name: 'Wrapped USDT',
decimals: 6,
},
};
// Transaction status
export enum TransactionStatus {
IDLE = 'idle',
PENDING = 'pending',
SUCCESS = 'success',
ERROR = 'error',
}
+1 -1
View File
@@ -1,5 +1,5 @@
import { ApiPromise } from '@polkadot/api';
import { KNOWN_TOKENS, PoolInfo, SwapQuote } from '../types/dex';
import { KNOWN_TOKENS, PoolInfo, SwapQuote } from '@pezkuwi/types/dex';
/**
* Format balance with proper decimals
@@ -7,8 +7,8 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com
import { Loader2, CheckCircle, AlertTriangle, Shield } from 'lucide-react';
import { usePolkadot } from '@/contexts/PolkadotContext';
import { verifyNftOwnership } from '@pezkuwi/lib/citizenship-workflow';
import { generateAuthChallenge, signChallenge, verifySignature, saveCitizenSession } from '@pezkuwi/lib/citizenship-crypto';
import type { AuthChallenge } from '@pezkuwi/lib/citizenship-crypto';
import { generateAuthChallenge, signChallenge, verifySignature, saveCitizenSession } from '@pezkuwi/lib/citizenship-workflow';
import type { AuthChallenge } from '@pezkuwi/lib/citizenship-workflow';
interface ExistingCitizenAuthProps {
onClose: () => void;
@@ -12,7 +12,7 @@ import { Loader2, AlertTriangle, CheckCircle, User, Users as UsersIcon, MapPin,
import { usePolkadot } from '@/contexts/PolkadotContext';
import type { CitizenshipData, Region, MaritalStatus } from '@pezkuwi/lib/citizenship-workflow';
import { FOUNDER_ADDRESS, submitKycApplication, subscribeToKycApproval, getKycStatus } from '@pezkuwi/lib/citizenship-workflow';
import { generateCommitmentHash, generateNullifierHash, encryptData, saveLocalCitizenshipData, uploadToIPFS } from '@pezkuwi/lib/citizenship-crypto';
import { generateCommitmentHash, generateNullifierHash, encryptData, saveLocalCitizenshipData, uploadToIPFS } from '@pezkuwi/lib/citizenship-workflow';
interface NewCitizenApplicationProps {
onClose: () => void;
@@ -8,7 +8,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '../ui/card';
import { Badge } from '../ui/badge';
import { Progress } from '../ui/progress';
import { usePolkadot } from '../../contexts/PolkadotContext';
import { formatBalance } from '../@pezkuwi/lib/wallet';
import { formatBalance } from '@pezkuwi/lib/wallet';
interface GovernanceStats {
activeProposals: number;
+2
View File
@@ -7,6 +7,8 @@ import './i18n/config'
declare global {
interface Window {
ethereum?: any;
Buffer: any;
global: any;
}
}
+10 -3
View File
@@ -19,6 +19,10 @@ export default defineConfig(({ mode }) => ({
plugins: [
react()
].filter(Boolean),
define: {
'global': 'globalThis',
'process.env': {}
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
@@ -27,11 +31,14 @@ export default defineConfig(({ mode }) => ({
"@pezkuwi/utils": path.resolve(__dirname, "../shared/utils"),
"@pezkuwi/theme": path.resolve(__dirname, "../shared/theme"),
"@pezkuwi/types": path.resolve(__dirname, "../shared/types"),
'buffer': 'buffer/',
},
},
json: {
stringify: true,
optimizeDeps: {
esbuildOptions: {
define: {
global: 'globalThis'
}
}
},
assetsInclude: ['**/*.json'],
}));