mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-06-09 21:21:03 +00:00
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:
+14
-9
@@ -7,12 +7,12 @@
|
|||||||
export { translations as comprehensiveTranslations, supportedLocales } from './translations';
|
export { translations as comprehensiveTranslations, supportedLocales } from './translations';
|
||||||
|
|
||||||
// Import all translation JSON files for i18next compatibility
|
// Import all translation JSON files for i18next compatibility
|
||||||
import en from './locales/en.json';
|
import en from './locales/en.json?url';
|
||||||
import tr from './locales/tr.json';
|
import tr from './locales/tr.json?url';
|
||||||
import kmr from './locales/kmr.json';
|
import kmr from './locales/kmr.json?url';
|
||||||
import ckb from './locales/ckb.json';
|
import ckb from './locales/ckb.json?url';
|
||||||
import ar from './locales/ar.json';
|
import ar from './locales/ar.json?url';
|
||||||
import fa from './locales/fa.json';
|
import fa from './locales/fa.json?url';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Language configuration with RTL support
|
* Language configuration with RTL support
|
||||||
@@ -47,9 +47,9 @@ export const DEFAULT_LANGUAGE = 'en';
|
|||||||
export const LANGUAGE_STORAGE_KEY = '@pezkuwi_language';
|
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,
|
en,
|
||||||
tr,
|
tr,
|
||||||
kmr,
|
kmr,
|
||||||
@@ -58,6 +58,11 @@ export const translations = {
|
|||||||
fa,
|
fa,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translation resources (empty - load dynamically)
|
||||||
|
*/
|
||||||
|
export const translations = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a language is RTL
|
* Check if a language is RTL
|
||||||
* @param languageCode - Language code (e.g., 'ar', 'ckb', 'fa')
|
* @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 {
|
export function getLanguageConfig(languageCode: string): LanguageConfig | undefined {
|
||||||
return LANGUAGES.find(l => l.code === languageCode);
|
return LANGUAGES.find(l => l.code === languageCode);
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
@@ -622,3 +622,116 @@ export function subscribeToKycApproval(
|
|||||||
// ========================================
|
// ========================================
|
||||||
|
|
||||||
export const FOUNDER_ADDRESS = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; // Satoshi Qazi Muhammed
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
@@ -1,5 +1,5 @@
|
|||||||
import { ApiPromise } from '@polkadot/api';
|
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
|
* 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 { Loader2, CheckCircle, AlertTriangle, Shield } from 'lucide-react';
|
||||||
import { usePolkadot } from '@/contexts/PolkadotContext';
|
import { usePolkadot } from '@/contexts/PolkadotContext';
|
||||||
import { verifyNftOwnership } from '@pezkuwi/lib/citizenship-workflow';
|
import { verifyNftOwnership } from '@pezkuwi/lib/citizenship-workflow';
|
||||||
import { generateAuthChallenge, signChallenge, verifySignature, saveCitizenSession } from '@pezkuwi/lib/citizenship-crypto';
|
import { generateAuthChallenge, signChallenge, verifySignature, saveCitizenSession } from '@pezkuwi/lib/citizenship-workflow';
|
||||||
import type { AuthChallenge } from '@pezkuwi/lib/citizenship-crypto';
|
import type { AuthChallenge } from '@pezkuwi/lib/citizenship-workflow';
|
||||||
|
|
||||||
interface ExistingCitizenAuthProps {
|
interface ExistingCitizenAuthProps {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { Loader2, AlertTriangle, CheckCircle, User, Users as UsersIcon, MapPin,
|
|||||||
import { usePolkadot } from '@/contexts/PolkadotContext';
|
import { usePolkadot } from '@/contexts/PolkadotContext';
|
||||||
import type { CitizenshipData, Region, MaritalStatus } from '@pezkuwi/lib/citizenship-workflow';
|
import type { CitizenshipData, Region, MaritalStatus } from '@pezkuwi/lib/citizenship-workflow';
|
||||||
import { FOUNDER_ADDRESS, submitKycApplication, subscribeToKycApproval, getKycStatus } 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 {
|
interface NewCitizenApplicationProps {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '../ui/card';
|
|||||||
import { Badge } from '../ui/badge';
|
import { Badge } from '../ui/badge';
|
||||||
import { Progress } from '../ui/progress';
|
import { Progress } from '../ui/progress';
|
||||||
import { usePolkadot } from '../../contexts/PolkadotContext';
|
import { usePolkadot } from '../../contexts/PolkadotContext';
|
||||||
import { formatBalance } from '../@pezkuwi/lib/wallet';
|
import { formatBalance } from '@pezkuwi/lib/wallet';
|
||||||
|
|
||||||
interface GovernanceStats {
|
interface GovernanceStats {
|
||||||
activeProposals: number;
|
activeProposals: number;
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import './i18n/config'
|
|||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
ethereum?: any;
|
ethereum?: any;
|
||||||
|
Buffer: any;
|
||||||
|
global: any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-3
@@ -19,6 +19,10 @@ export default defineConfig(({ mode }) => ({
|
|||||||
plugins: [
|
plugins: [
|
||||||
react()
|
react()
|
||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
|
define: {
|
||||||
|
'global': 'globalThis',
|
||||||
|
'process.env': {}
|
||||||
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
"@": path.resolve(__dirname, "./src"),
|
"@": path.resolve(__dirname, "./src"),
|
||||||
@@ -27,11 +31,14 @@ export default defineConfig(({ mode }) => ({
|
|||||||
"@pezkuwi/utils": path.resolve(__dirname, "../shared/utils"),
|
"@pezkuwi/utils": path.resolve(__dirname, "../shared/utils"),
|
||||||
"@pezkuwi/theme": path.resolve(__dirname, "../shared/theme"),
|
"@pezkuwi/theme": path.resolve(__dirname, "../shared/theme"),
|
||||||
"@pezkuwi/types": path.resolve(__dirname, "../shared/types"),
|
"@pezkuwi/types": path.resolve(__dirname, "../shared/types"),
|
||||||
'buffer': 'buffer/',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
json: {
|
optimizeDeps: {
|
||||||
stringify: true,
|
esbuildOptions: {
|
||||||
|
define: {
|
||||||
|
global: 'globalThis'
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
assetsInclude: ['**/*.json'],
|
assetsInclude: ['**/*.json'],
|
||||||
}));
|
}));
|
||||||
Reference in New Issue
Block a user