From 31a0f86382e97c3a5561df82f2883cf1671c5f13 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 14 Nov 2025 19:48:43 +0000 Subject: [PATCH] Organize shared code across web, mobile, and SDK UI projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Centralized common code into shared/ folder to eliminate duplication and improve maintainability across all three frontend projects (web, mobile, pezkuwi-sdk-ui). Changes: - Added token types and constants to shared/types/tokens.ts - TokenInfo, PoolInfo, SwapQuote, and other DEX types - KNOWN_TOKENS with HEZ, PEZ, wUSDT definitions - Token logos (🟡🟣💵) - Added Kurdistan color palette to shared/constants/ - Kesk, Sor, Zer, Spî, Reş color definitions - Added TOKEN_DISPLAY_SYMBOLS mapping (USDT vs wUSDT) - Updated blockchain configuration in shared/blockchain/polkadot.ts - Added beta testnet endpoint (wss://beta-rpc.pezkuwi.art) - Defined DEFAULT_ENDPOINT constant - Moved i18n to shared/i18n/ - Centralized translation files for 6 languages (EN, TR, KMR, CKB, AR, FA) - Added LANGUAGES configuration with RTL support - Created isRTL() helper function - Updated web and mobile to import from shared - web/src/types/dex.ts now re-exports from shared - web/src/contexts/PolkadotContext.tsx uses DEFAULT_ENDPOINT - mobile/src/i18n/index.ts uses shared translations - mobile/src/contexts/PolkadotContext.tsx uses DEFAULT_ENDPOINT - Updated shared/README.md with comprehensive documentation This architecture reduces code duplication and ensures consistency across all frontend projects. --- mobile/src/contexts/PolkadotContext.tsx | 3 +- mobile/src/i18n/index.ts | 49 +++++----- shared/README.md | 41 ++++++-- shared/blockchain/polkadot.ts | 10 +- shared/constants/index.ts | 50 ++++++++++ shared/i18n/index.ts | 74 +++++++++++++++ shared/i18n/json.d.ts | 4 + shared/i18n/locales/ar.json | 64 +++++++++++++ shared/i18n/locales/ckb.json | 64 +++++++++++++ shared/i18n/locales/en.json | 64 +++++++++++++ shared/i18n/locales/fa.json | 64 +++++++++++++ shared/i18n/locales/kmr.json | 64 +++++++++++++ shared/i18n/locales/tr.json | 64 +++++++++++++ shared/types/index.ts | 3 + shared/types/tokens.ts | 90 ++++++++++++++++++ web/src/contexts/PolkadotContext.tsx | 3 +- web/src/types/dex.ts | 120 +++--------------------- 17 files changed, 684 insertions(+), 147 deletions(-) create mode 100644 shared/i18n/index.ts create mode 100644 shared/i18n/json.d.ts create mode 100644 shared/i18n/locales/ar.json create mode 100644 shared/i18n/locales/ckb.json create mode 100644 shared/i18n/locales/en.json create mode 100644 shared/i18n/locales/fa.json create mode 100644 shared/i18n/locales/kmr.json create mode 100644 shared/i18n/locales/tr.json create mode 100644 shared/types/tokens.ts diff --git a/mobile/src/contexts/PolkadotContext.tsx b/mobile/src/contexts/PolkadotContext.tsx index da19cb7d..d821f80d 100644 --- a/mobile/src/contexts/PolkadotContext.tsx +++ b/mobile/src/contexts/PolkadotContext.tsx @@ -4,6 +4,7 @@ import { Keyring } from '@polkadot/keyring'; import { KeyringPair } from '@polkadot/keyring/types'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { cryptoWaitReady } from '@polkadot/util-crypto'; +import { DEFAULT_ENDPOINT } from '../../../shared/blockchain/polkadot'; interface Account { address: string; @@ -39,7 +40,7 @@ interface PolkadotProviderProps { export const PolkadotProvider: React.FC = ({ children, - endpoint = 'wss://beta-rpc.pezkuwi.art', // Beta testnet RPC + endpoint = DEFAULT_ENDPOINT, // Beta testnet RPC from shared config }) => { const [api, setApi] = useState(null); const [isApiReady, setIsApiReady] = useState(false); diff --git a/mobile/src/i18n/index.ts b/mobile/src/i18n/index.ts index 561b9969..e27af39a 100644 --- a/mobile/src/i18n/index.ts +++ b/mobile/src/i18n/index.ts @@ -2,31 +2,25 @@ import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import AsyncStorage from '@react-native-async-storage/async-storage'; -// Import all translations -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 shared translations and language configurations +import { + translations, + LANGUAGES, + DEFAULT_LANGUAGE, + LANGUAGE_STORAGE_KEY, + isRTL as checkIsRTL, +} from '../../../shared/i18n'; -// Language storage key -export const LANGUAGE_KEY = '@pezkuwi_language'; +// Language storage key (re-export for compatibility) +export const LANGUAGE_KEY = LANGUAGE_STORAGE_KEY; -// Available languages -export const languages = [ - { code: 'en', name: 'English', nativeName: 'English', rtl: false }, - { code: 'tr', name: 'Turkish', nativeName: 'Türkçe', rtl: false }, - { code: 'kmr', name: 'Kurdish (Kurmanji)', nativeName: 'Kurmancî', rtl: false }, - { code: 'ckb', name: 'Kurdish (Sorani)', nativeName: 'سۆرانی', rtl: true }, - { code: 'ar', name: 'Arabic', nativeName: 'العربية', rtl: true }, - { code: 'fa', name: 'Persian', nativeName: 'فارسی', rtl: true }, -]; +// Available languages (re-export for compatibility) +export const languages = LANGUAGES; // Initialize i18n const initializeI18n = async () => { // Try to get saved language - let savedLanguage = 'en'; // Default fallback + let savedLanguage = DEFAULT_LANGUAGE; try { const stored = await AsyncStorage.getItem(LANGUAGE_KEY); if (stored) { @@ -40,15 +34,15 @@ const initializeI18n = async () => { .use(initReactI18next) .init({ resources: { - en: { translation: en }, - tr: { translation: tr }, - kmr: { translation: kmr }, - ckb: { translation: ckb }, - ar: { translation: ar }, - fa: { translation: fa }, + en: { translation: translations.en }, + tr: { translation: translations.tr }, + kmr: { translation: translations.kmr }, + ckb: { translation: translations.ckb }, + ar: { translation: translations.ar }, + fa: { translation: translations.fa }, }, lng: savedLanguage, - fallbackLng: 'en', + fallbackLng: DEFAULT_LANGUAGE, compatibilityJSON: 'v3', interpolation: { escapeValue: false, @@ -74,8 +68,7 @@ export const getCurrentLanguage = () => i18n.language; // Check if language is RTL export const isRTL = (languageCode?: string) => { const code = languageCode || i18n.language; - const lang = languages.find(l => l.code === code); - return lang?.rtl || false; + return checkIsRTL(code); }; export { initializeI18n }; diff --git a/shared/README.md b/shared/README.md index 025ae042..b272f54c 100644 --- a/shared/README.md +++ b/shared/README.md @@ -1,25 +1,49 @@ # Shared Code -This directory contains code shared between web and mobile applications. +This directory contains code shared between web, mobile, and SDK UI applications. ## Structure - **types/** - TypeScript type definitions and interfaces -- **utils/** - Utility functions and helpers -- **blockchain/** - Blockchain-related utilities (Polkadot API wrappers, transaction helpers) + - `blockchain.ts` - Blockchain-related types (WalletAccount, Transaction, etc.) + - `tokens.ts` - Token and DEX types (TokenInfo, PoolInfo, SwapQuote, etc.) + - **constants/** - Shared constants and configuration values + - `KNOWN_TOKENS` - Token definitions (HEZ, PEZ, USDT) + - `KURDISTAN_COLORS` - Color palette (Kesk, Sor, Zer, Spî, Reş) + - `SUPPORTED_LANGUAGES` - Available languages (EN, TR, KMR, CKB, AR, FA) + - `TOKEN_DISPLAY_SYMBOLS` - Display vs blockchain symbol mapping + +- **blockchain/** - Blockchain-related utilities + - `polkadot.ts` - Polkadot/Substrate utilities and endpoints + - `DEFAULT_ENDPOINT` - Current blockchain endpoint (beta testnet) + +- **i18n/** - Internationalization + - `locales/` - Translation files for 6 languages + - `LANGUAGES` - Language configurations with RTL support + - `translations` - All locale data + +- **utils/** - Utility functions and helpers + - `formatting.ts` - Address and number formatting + - `validation.ts` - Input validation utilities ## Usage Import shared code in your projects: ```typescript -// Web project -import { SomeType } from '../shared/types'; -import { someUtil } from '../shared/utils'; +// Token types and constants +import { TokenInfo, KNOWN_TOKENS } from '../../../shared/types/tokens'; +import { KURDISTAN_COLORS, TOKEN_DISPLAY_SYMBOLS } from '../../../shared/constants'; -// Mobile project -import { SomeType } from '../shared/types'; +// Blockchain utilities +import { DEFAULT_ENDPOINT, BLOCKCHAIN_ENDPOINTS } from '../../../shared/blockchain/polkadot'; + +// i18n +import { translations, LANGUAGES, isRTL } from '../../../shared/i18n'; + +// Formatting utilities +import { formatAddress, formatTokenAmount } from '../../../shared/utils/formatting'; ``` ## Guidelines @@ -28,3 +52,4 @@ import { SomeType } from '../shared/types'; - Add comprehensive JSDoc comments - Write unit tests for utilities - Avoid platform-specific dependencies +- Use relative imports: `../../../shared/...` from web/mobile/SDK UI diff --git a/shared/blockchain/polkadot.ts b/shared/blockchain/polkadot.ts index 590e5096..74c5a82b 100644 --- a/shared/blockchain/polkadot.ts +++ b/shared/blockchain/polkadot.ts @@ -9,7 +9,7 @@ import type { BlockchainNetwork } from '../types/blockchain'; */ export const PEZKUWI_NETWORK: BlockchainNetwork = { name: 'Pezkuwi', - endpoint: 'wss://pezkuwichain.app:9944', + endpoint: 'wss://beta-rpc.pezkuwi.art', chainId: 'pezkuwi', }; @@ -17,10 +17,16 @@ export const PEZKUWI_NETWORK: BlockchainNetwork = { * Common blockchain endpoints */ export const BLOCKCHAIN_ENDPOINTS = { - pezkuwi: 'wss://pezkuwichain.app:9944', + mainnet: 'wss://pezkuwichain.app:9944', + beta: 'wss://beta-rpc.pezkuwi.art', local: 'ws://127.0.0.1:9944', } as const; +/** + * Default endpoint (currently using beta testnet) + */ +export const DEFAULT_ENDPOINT = BLOCKCHAIN_ENDPOINTS.beta; + /** * Get block explorer URL for a transaction * @param txHash - Transaction hash diff --git a/shared/constants/index.ts b/shared/constants/index.ts index 17fbc8ab..da8d687a 100644 --- a/shared/constants/index.ts +++ b/shared/constants/index.ts @@ -2,6 +2,8 @@ * Shared constants for Pezkuwi Web App Projects */ +import type { TokenInfo } from '../types/tokens'; + /** * Application version */ @@ -32,3 +34,51 @@ export const TIMEOUTS = { BLOCKCHAIN_QUERY: 60000, TRANSACTION: 120000, } as const; + +/** + * Kurdistan color palette + */ +export const KURDISTAN_COLORS = { + kesk: '#00A94F', // Green (Kesk) + sor: '#EE2A35', // Red (Sor) + zer: '#FFD700', // Yellow/Gold (Zer) + spi: '#FFFFFF', // White (Spî) + res: '#000000', // Black (Reş) +} as const; + +/** + * Known tokens on the Pezkuwi blockchain + */ +export const KNOWN_TOKENS: Record = { + 0: { + id: 0, + symbol: 'wHEZ', + name: 'Wrapped HEZ', + decimals: 12, + logo: '🟡', + }, + 1: { + id: 1, + symbol: 'PEZ', + name: 'Pezkuwi Token', + decimals: 12, + logo: '🟣', + }, + 2: { + id: 2, + symbol: 'wUSDT', + name: 'Wrapped USDT', + decimals: 6, + logo: '💵', + }, +}; + +/** + * Display token symbols (what users see vs. blockchain IDs) + * Example: Users see "USDT" but it's wUSDT (asset ID 2) on blockchain + */ +export const TOKEN_DISPLAY_SYMBOLS: Record = { + 'wHEZ': 'HEZ', // Display HEZ instead of wHEZ + 'wUSDT': 'USDT', // Display USDT instead of wUSDT + 'PEZ': 'PEZ', // PEZ stays as is +}; diff --git a/shared/i18n/index.ts b/shared/i18n/index.ts new file mode 100644 index 00000000..68e6df83 --- /dev/null +++ b/shared/i18n/index.ts @@ -0,0 +1,74 @@ +/** + * Shared i18n configuration and translations + */ + +// Import all translations +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'; + +/** + * Language configuration with RTL support + */ +export interface LanguageConfig { + code: string; + name: string; + nativeName: string; + rtl: boolean; +} + +/** + * Available languages + */ +export const LANGUAGES: LanguageConfig[] = [ + { code: 'en', name: 'English', nativeName: 'English', rtl: false }, + { code: 'tr', name: 'Turkish', nativeName: 'Türkçe', rtl: false }, + { code: 'kmr', name: 'Kurdish (Kurmanji)', nativeName: 'Kurmancî', rtl: false }, + { code: 'ckb', name: 'Kurdish (Sorani)', nativeName: 'سۆرانی', rtl: true }, + { code: 'ar', name: 'Arabic', nativeName: 'العربية', rtl: true }, + { code: 'fa', name: 'Persian', nativeName: 'فارسی', rtl: true }, +]; + +/** + * Default language code + */ +export const DEFAULT_LANGUAGE = 'en'; + +/** + * Language storage key (for AsyncStorage/localStorage) + */ +export const LANGUAGE_STORAGE_KEY = '@pezkuwi_language'; + +/** + * Translation resources + */ +export const translations = { + en, + tr, + kmr, + ckb, + ar, + fa, +}; + +/** + * Check if a language is RTL + * @param languageCode - Language code (e.g., 'ar', 'ckb', 'fa') + * @returns true if RTL, false otherwise + */ +export function isRTL(languageCode: string): boolean { + const lang = LANGUAGES.find(l => l.code === languageCode); + return lang?.rtl || false; +} + +/** + * Get language configuration + * @param languageCode - Language code + * @returns Language configuration or undefined + */ +export function getLanguageConfig(languageCode: string): LanguageConfig | undefined { + return LANGUAGES.find(l => l.code === languageCode); +} diff --git a/shared/i18n/json.d.ts b/shared/i18n/json.d.ts new file mode 100644 index 00000000..bbab69d2 --- /dev/null +++ b/shared/i18n/json.d.ts @@ -0,0 +1,4 @@ +declare module '*.json' { + const value: any; + export default value; +} diff --git a/shared/i18n/locales/ar.json b/shared/i18n/locales/ar.json new file mode 100644 index 00000000..8c6c8f62 --- /dev/null +++ b/shared/i18n/locales/ar.json @@ -0,0 +1,64 @@ +{ + "welcome": { + "title": "مرحباً بك في بيزكوي", + "subtitle": "بوابتك للحوكمة اللامركزية", + "selectLanguage": "اختر لغتك", + "continue": "متابعة" + }, + "auth": { + "signIn": "تسجيل الدخول", + "signUp": "إنشاء حساب", + "email": "البريد الإلكتروني", + "password": "كلمة المرور", + "confirmPassword": "تأكيد كلمة المرور", + "forgotPassword": "نسيت كلمة المرور؟", + "noAccount": "ليس لديك حساب؟", + "haveAccount": "هل لديك حساب بالفعل؟", + "createAccount": "إنشاء حساب", + "welcomeBack": "مرحباً بعودتك!", + "getStarted": "ابدأ الآن" + }, + "dashboard": { + "title": "لوحة التحكم", + "wallet": "المحفظة", + "staking": "التخزين", + "governance": "الحوكمة", + "dex": "البورصة", + "history": "السجل", + "settings": "الإعدادات", + "balance": "الرصيد", + "totalStaked": "إجمالي المخزن", + "rewards": "المكافآت", + "activeProposals": "المقترحات النشطة" + }, + "wallet": { + "title": "المحفظة", + "connect": "ربط المحفظة", + "disconnect": "فصل الاتصال", + "address": "العنوان", + "balance": "الرصيد", + "send": "إرسال", + "receive": "استقبال", + "transaction": "المعاملة", + "history": "السجل" + }, + "settings": { + "title": "الإعدادات", + "language": "اللغة", + "theme": "المظهر", + "notifications": "الإشعارات", + "security": "الأمان", + "about": "حول", + "logout": "تسجيل الخروج" + }, + "common": { + "cancel": "إلغاء", + "confirm": "تأكيد", + "save": "حفظ", + "loading": "جاري التحميل...", + "error": "خطأ", + "success": "نجاح", + "retry": "إعادة المحاولة", + "close": "إغلاق" + } +} diff --git a/shared/i18n/locales/ckb.json b/shared/i18n/locales/ckb.json new file mode 100644 index 00000000..f6e7b8c2 --- /dev/null +++ b/shared/i18n/locales/ckb.json @@ -0,0 +1,64 @@ +{ + "welcome": { + "title": "بەخێربێیت بۆ پێزکووی", + "subtitle": "دەرگای تۆ بۆ بەڕێوەبردنی نامەرکەزی", + "selectLanguage": "زمانەکەت هەڵبژێرە", + "continue": "بەردەوام بە" + }, + "auth": { + "signIn": "چوونەژوورەوە", + "signUp": "تۆمارکردن", + "email": "ئیمەیڵ", + "password": "وشەی نهێنی", + "confirmPassword": "پشتڕاستکردنەوەی وشەی نهێنی", + "forgotPassword": "وشەی نهێنیت لەبیرکردووە؟", + "noAccount": "هەژمارت نییە؟", + "haveAccount": "هەژمارت هەیە؟", + "createAccount": "دروستکردنی هەژمار", + "welcomeBack": "بەخێربێیتەوە!", + "getStarted": "دەست پێبکە" + }, + "dashboard": { + "title": "سەرەتا", + "wallet": "جزدان", + "staking": "ستەیکینگ", + "governance": "بەڕێوەبردن", + "dex": "ئاڵوگۆڕ", + "history": "مێژوو", + "settings": "ڕێکخستنەکان", + "balance": "باڵانس", + "totalStaked": "کۆی گشتی", + "rewards": "خەڵات", + "activeProposals": "پێشنیارە چالاکەکان" + }, + "wallet": { + "title": "جزدان", + "connect": "گرێدانی جزدان", + "disconnect": "پچڕاندنی گرێدان", + "address": "ناونیشان", + "balance": "باڵانس", + "send": "ناردن", + "receive": "وەرگرتن", + "transaction": "مامەڵە", + "history": "مێژوو" + }, + "settings": { + "title": "ڕێکخستنەکان", + "language": "زمان", + "theme": "ڕووکار", + "notifications": "ئاگادارییەکان", + "security": "پاراستن", + "about": "دەربارە", + "logout": "دەرچوون" + }, + "common": { + "cancel": "هەڵوەشاندنەوە", + "confirm": "پشتڕاستکردنەوە", + "save": "پاشەکەوتکردن", + "loading": "بارکردن...", + "error": "هەڵە", + "success": "سەرکەوتوو", + "retry": "هەوڵ بدەرەوە", + "close": "داخستن" + } +} diff --git a/shared/i18n/locales/en.json b/shared/i18n/locales/en.json new file mode 100644 index 00000000..6cbd4bff --- /dev/null +++ b/shared/i18n/locales/en.json @@ -0,0 +1,64 @@ +{ + "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" + } +} diff --git a/shared/i18n/locales/fa.json b/shared/i18n/locales/fa.json new file mode 100644 index 00000000..05105e2b --- /dev/null +++ b/shared/i18n/locales/fa.json @@ -0,0 +1,64 @@ +{ + "welcome": { + "title": "به پێزکووی خوش آمدید", + "subtitle": "دروازه شما به حکمرانی غیرمتمرکز", + "selectLanguage": "زبان خود را انتخاب کنید", + "continue": "ادامه" + }, + "auth": { + "signIn": "ورود", + "signUp": "ثبت نام", + "email": "ایمیل", + "password": "رمز عبور", + "confirmPassword": "تأیید رمز عبور", + "forgotPassword": "رمز عبور را فراموش کرده‌اید؟", + "noAccount": "حساب کاربری ندارید؟", + "haveAccount": "قبلاً حساب کاربری دارید؟", + "createAccount": "ایجاد حساب", + "welcomeBack": "خوش آمدید!", + "getStarted": "شروع کنید" + }, + "dashboard": { + "title": "داشبورد", + "wallet": "کیف پول", + "staking": "سپرده‌گذاری", + "governance": "حکمرانی", + "dex": "صرافی", + "history": "تاریخچه", + "settings": "تنظیمات", + "balance": "موجودی", + "totalStaked": "کل سپرده", + "rewards": "پاداش‌ها", + "activeProposals": "پیشنهادات فعال" + }, + "wallet": { + "title": "کیف پول", + "connect": "اتصال کیف پول", + "disconnect": "قطع اتصال", + "address": "آدرس", + "balance": "موجودی", + "send": "ارسال", + "receive": "دریافت", + "transaction": "تراکنش", + "history": "تاریخچه" + }, + "settings": { + "title": "تنظیمات", + "language": "زبان", + "theme": "تم", + "notifications": "اعلان‌ها", + "security": "امنیت", + "about": "درباره", + "logout": "خروج" + }, + "common": { + "cancel": "لغو", + "confirm": "تأیید", + "save": "ذخیره", + "loading": "در حال بارگذاری...", + "error": "خطا", + "success": "موفق", + "retry": "تلاش مجدد", + "close": "بستن" + } +} diff --git a/shared/i18n/locales/kmr.json b/shared/i18n/locales/kmr.json new file mode 100644 index 00000000..fcac36a0 --- /dev/null +++ b/shared/i18n/locales/kmr.json @@ -0,0 +1,64 @@ +{ + "welcome": { + "title": "Bi xêr hatî Pezkuwî", + "subtitle": "Deriyê te yê bo rêveberiya desentralîze", + "selectLanguage": "Zimanê Xwe Hilbijêre", + "continue": "Bidomîne" + }, + "auth": { + "signIn": "Têkeve", + "signUp": "Tomar bibe", + "email": "E-posta", + "password": "Şîfre", + "confirmPassword": "Şîfreyê Bipejirîne", + "forgotPassword": "Şîfreyê te ji bîr kiriye?", + "noAccount": "Hesabê te tune ye?", + "haveAccount": "Jixwe hesabê te heye?", + "createAccount": "Hesab Biafirîne", + "welcomeBack": "Dîsa bi xêr hatî!", + "getStarted": "Dest pê bike" + }, + "dashboard": { + "title": "Serûpel", + "wallet": "Berîk", + "staking": "Staking", + "governance": "Rêvebir", + "dex": "Guherîn", + "history": "Dîrok", + "settings": "Mîheng", + "balance": "Bilanço", + "totalStaked": "Hemû Stake", + "rewards": "Xelat", + "activeProposals": "Pêşniyarên Çalak" + }, + "wallet": { + "title": "Berîk", + "connect": "Berîkê Girêde", + "disconnect": "Girêdanê Rake", + "address": "Navnîşan", + "balance": "Bilanço", + "send": "Bişîne", + "receive": "Bistîne", + "transaction": "Ragihandin", + "history": "Dîrok" + }, + "settings": { + "title": "Mîheng", + "language": "Ziman", + "theme": "Tema", + "notifications": "Agahdarî", + "security": "Ewlekarî", + "about": "Derbarê", + "logout": "Derkeve" + }, + "common": { + "cancel": "Betal bike", + "confirm": "Bipejirîne", + "save": "Tomar bike", + "loading": "Tê barkirin...", + "error": "Çewtî", + "success": "Serkeftin", + "retry": "Dîsa biceribîne", + "close": "Bigire" + } +} diff --git a/shared/i18n/locales/tr.json b/shared/i18n/locales/tr.json new file mode 100644 index 00000000..6d2357fc --- /dev/null +++ b/shared/i18n/locales/tr.json @@ -0,0 +1,64 @@ +{ + "welcome": { + "title": "Pezkuwi'ye Hoş Geldiniz", + "subtitle": "Merkezi olmayan yönetim kapınız", + "selectLanguage": "Dilinizi Seçin", + "continue": "Devam Et" + }, + "auth": { + "signIn": "Giriş Yap", + "signUp": "Kayıt Ol", + "email": "E-posta", + "password": "Şifre", + "confirmPassword": "Şifreyi Onayla", + "forgotPassword": "Şifremi Unuttum", + "noAccount": "Hesabınız yok mu?", + "haveAccount": "Zaten hesabınız var mı?", + "createAccount": "Hesap Oluştur", + "welcomeBack": "Tekrar Hoş Geldiniz!", + "getStarted": "Başlayın" + }, + "dashboard": { + "title": "Ana Sayfa", + "wallet": "Cüzdan", + "staking": "Stake Etme", + "governance": "Yönetişim", + "dex": "Borsa", + "history": "Geçmiş", + "settings": "Ayarlar", + "balance": "Bakiye", + "totalStaked": "Toplam Stake", + "rewards": "Ödüller", + "activeProposals": "Aktif Teklifler" + }, + "wallet": { + "title": "Cüzdan", + "connect": "Cüzdan Bağla", + "disconnect": "Bağlantıyı Kes", + "address": "Adres", + "balance": "Bakiye", + "send": "Gönder", + "receive": "Al", + "transaction": "İşlem", + "history": "Geçmiş" + }, + "settings": { + "title": "Ayarlar", + "language": "Dil", + "theme": "Tema", + "notifications": "Bildirimler", + "security": "Güvenlik", + "about": "Hakkında", + "logout": "Çıkış Yap" + }, + "common": { + "cancel": "İptal", + "confirm": "Onayla", + "save": "Kaydet", + "loading": "Yükleniyor...", + "error": "Hata", + "success": "Başarılı", + "retry": "Tekrar Dene", + "close": "Kapat" + } +} diff --git a/shared/types/index.ts b/shared/types/index.ts index 935dd4a6..0e8f5838 100644 --- a/shared/types/index.ts +++ b/shared/types/index.ts @@ -8,4 +8,7 @@ // Export blockchain-related types here export * from './blockchain'; +// Export token-related types +export * from './tokens'; + // Add more type exports as needed diff --git a/shared/types/tokens.ts b/shared/types/tokens.ts new file mode 100644 index 00000000..797c4483 --- /dev/null +++ b/shared/types/tokens.ts @@ -0,0 +1,90 @@ +/** + * Token-related type definitions + */ + +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; +} + +// Transaction status +export enum TransactionStatus { + IDLE = 'idle', + PENDING = 'pending', + SUCCESS = 'success', + ERROR = 'error', +} diff --git a/web/src/contexts/PolkadotContext.tsx b/web/src/contexts/PolkadotContext.tsx index ba3d8393..508a2a99 100644 --- a/web/src/contexts/PolkadotContext.tsx +++ b/web/src/contexts/PolkadotContext.tsx @@ -2,6 +2,7 @@ import React, { createContext, useContext, useEffect, useState, ReactNode } from import { ApiPromise, WsProvider } from '@polkadot/api'; import { web3Accounts, web3Enable, web3FromAddress } from '@polkadot/extension-dapp'; import type { InjectedAccountWithMeta } from '@polkadot/extension-inject/types'; +import { DEFAULT_ENDPOINT } from '../../../shared/blockchain/polkadot'; interface PolkadotContextType { api: ApiPromise | null; @@ -24,7 +25,7 @@ interface PolkadotProviderProps { export const PolkadotProvider: React.FC = ({ children, - endpoint = 'wss://beta-rpc.pezkuwi.art' // Beta testnet RPC + endpoint = DEFAULT_ENDPOINT // Beta testnet RPC from shared config }) => { const [api, setApi] = useState(null); const [isApiReady, setIsApiReady] = useState(false); diff --git a/web/src/types/dex.ts b/web/src/types/dex.ts index dc26c7b1..4d01a12a 100644 --- a/web/src/types/dex.ts +++ b/web/src/types/dex.ts @@ -1,108 +1,14 @@ -export interface TokenInfo { - id: number; - symbol: string; - name: string; - decimals: number; - logo?: string; -} +// Re-export shared types and constants +export { + type TokenInfo, + type PoolInfo, + type UserLiquidityPosition, + type SwapQuote, + type AddLiquidityParams, + type RemoveLiquidityParams, + type SwapParams, + type PoolCreationParams, + TransactionStatus, +} from '../../../shared/types/tokens'; -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 = { - 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', -} +export { KNOWN_TOKENS, TOKEN_DISPLAY_SYMBOLS } from '../../../shared/constants';