diff --git a/backend/package-lock.json b/backend/package-lock.json index be3428d3..6d203047 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1005,18 +1005,18 @@ "license": "MIT" }, "node_modules/body-parser": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", - "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.4.0.tgz", + "integrity": "sha512-Ifk1KcLrxaGt1occQagQNFNNOqRt1LFuehEnHHzB8Z6cRgIxRU1TBaiIsUiCdA+gy5PL7Y1IX31DNKkRmxtXjQ==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", - "content-type": "^2.0.0", + "content-type": "^2.1.0", "debug": "^4.4.3", "http-errors": "^2.0.1", - "iconv-lite": "^0.7.2", + "iconv-lite": "^0.7.3", "on-finished": "^2.4.1", - "qs": "^6.15.2", + "qs": "^6.16.1", "raw-body": "^3.0.2", "type-is": "^2.1.0" }, @@ -2048,9 +2048,9 @@ } }, "node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -2135,9 +2135,9 @@ "license": "ISC" }, "node_modules/ip-address": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.3.tgz", - "integrity": "sha512-A1kdq/tSb5QjvKvAMgIoEvDBIgL7qaqVP/jkvSwYYRZ9iEzvPpopxp2wQfu3SuZRHtpHNxMn8Fs0bS+gf5Xmwg==", + "version": "10.7.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.5.tgz", + "integrity": "sha512-t2v0rkILYv9WXmSL7TpAaU3HXgaFYOPUcH3QHgwQ++gpJuH3bqyMy4Fvt/DJCTKwzH3Cf+bAp5W/mFL39KPLzA==", "license": "MIT", "optional": true, "engines": { @@ -2966,9 +2966,9 @@ } }, "node_modules/qs": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", - "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", + "version": "6.16.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.1.tgz", + "integrity": "sha512-5Px6J7rfHBAGUhNQ3es4YzcOdBBw0SDcVtThJml4RdnKw4tKs2epA0kPZ+K8X+WiHktT93RHVcQ/3ym5aTCgtg==", "license": "BSD-3-Clause", "dependencies": { "es-define-property": "^1.0.1", diff --git a/ops/typecheck-baseline.txt b/ops/typecheck-baseline.txt index 96a36dae..8db3ce5f 100644 --- a/ops/typecheck-baseline.txt +++ b/ops/typecheck-baseline.txt @@ -3,7 +3,7 @@ 3 ../shared/lib/perwerde.ts TS2339 6 ../shared/lib/presale.ts TS2339 1 ../shared/lib/referral.ts TS2339 -9 ../shared/lib/scores.ts TS2339 +5 ../shared/lib/scores.ts TS2339 3 ../shared/lib/staking.ts TS2339 10 ../shared/lib/validator-pool.ts TS2339 2 ../shared/lib/welati.ts TS2305 diff --git a/shared/lib/error-handler.ts b/shared/lib/error-handler.ts index 4ccd40fa..05b4978d 100644 --- a/shared/lib/error-handler.ts +++ b/shared/lib/error-handler.ts @@ -47,10 +47,6 @@ const ERROR_MESSAGES: Record = { en: 'You have already claimed your reward for this epoch.', kmr: 'We berê xelata xwe ji bo vê epoch-ê wergirtiye.', }, - 'pezRewards.NoTrustScoreForEpoch': { - en: 'No trust score recorded for this epoch. You must record your score before claiming.', - kmr: 'Ji bo vê epoch-ê skora emîniyê tomar nebûye. Pêşî divê skora xwe tomar bikî.', - }, 'pezRewards.NoRewardToClaim': { en: 'No reward available to claim for this epoch.', kmr: 'Ji bo vê epoch-ê xelateke ku were wergirtin tune ye.', @@ -453,10 +449,6 @@ export const SUCCESS_MESSAGES: Record = { }, // PEZ Rewards - 'pezRewards.recorded': { - en: 'Trust score recorded for this epoch. Your score will be used for reward calculation.', - kmr: 'Skora emîniyê ji bo vê epoch-ê tomar bû. Skora we dê ji bo hesabkirina xelatê were bikaranîn.', - }, 'pezRewards.claimed': { en: '{{amount}} PEZ reward claimed successfully!', kmr: '{{amount}} PEZ xelat bi serkeftî hate wergirtin!', diff --git a/shared/lib/scores.ts b/shared/lib/scores.ts index a76f0f1f..2cbd81f2 100644 --- a/shared/lib/scores.ts +++ b/shared/lib/scores.ts @@ -45,8 +45,6 @@ export interface EpochRewardPool { export interface PezRewardInfo { currentEpoch: number; epochStatus: EpochStatus; - hasRecordedThisEpoch: boolean; - userScoreCurrentEpoch: number; claimableRewards: { epoch: number; amount: string }[]; totalClaimable: string; hasPendingClaim: boolean; @@ -512,7 +510,6 @@ export async function getPerwerdeScore( * Uses correct storage query names from live People Chain metadata: * - epochInfo() → epoch info (ValueQuery) * - epochStatus(epoch) → Open | ClaimPeriod | Closed - * - userEpochScores(epoch, addr) → user's recorded score (OptionQuery) * - claimedRewards(epoch, addr) → claimed reward amount (OptionQuery) * - epochRewardPools(epoch) → reward pool info (OptionQuery) */ @@ -548,18 +545,27 @@ export async function getPezRewards( // Default to Open if query fails } - // Check if user has recorded their score this epoch - let hasRecordedThisEpoch = false; - let userScoreCurrentEpoch = 0; + // What a claim pays, worked out the way the chain does (`pezRewards::entitlement`). There + // is no score to record beforehand: the roll is held still from an epoch's finalisation + // to the end of its claim window, so the trust score now is the one the rate was set + // against, and a seat is paid if it is held now and was taken by the time of the roll. + const who = peopleApi.createType('AccountId', address).toString(); + const trustScore = BigInt((await peopleApi.query.trust.trustScores(address)).toString()); + let seatTakenAt: number | null = null; try { - const userScoreResult = await peopleApi.query.pezRewards.userEpochScores(currentEpoch, address); - if (userScoreResult.isSome) { - hasRecordedThisEpoch = true; - const scoreCodec = userScoreResult.unwrap() as { toString: () => string }; - userScoreCurrentEpoch = Number(scoreCodec.toString()); + const tikis = ((await peopleApi.query.tiki.userTikis(address)).toJSON() ?? []) as string[]; + if (tikis.includes('Parlementer')) { + const expiry = (await peopleApi.query.tiki.tikiExpiry(address, 'Parlementer')).toJSON() as number | null; + const now = (await peopleApi.rpc.chain.getHeader()).number.toNumber(); + if (expiry === null || now <= expiry) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const members = (await peopleApi.query.welati.parliamentMembers()).toJSON() as any[]; + const member = members.find((m) => peopleApi.createType('AccountId', m.account).toString() === who); + if (member) seatTakenAt = Number(member.electedAt ?? member.elected_at); + } } } catch { - // User hasn't recorded + // No seat } // Check for claimable rewards from completed epochs @@ -577,10 +583,6 @@ export async function getPezRewards( const claimedResult = await peopleApi.query.pezRewards.claimedRewards(i, address); if (claimedResult.isSome) continue; - // Check if user has a score for this epoch - const userScoreResult = await peopleApi.query.pezRewards.userEpochScores(i, address); - if (!userScoreResult.isSome) continue; - // Get epoch reward pool const epochPoolResult = await peopleApi.query.pezRewards.epochRewardPools(i); if (!epochPoolResult.isSome) continue; @@ -588,17 +590,16 @@ export async function getPezRewards( const epochPoolCodec = epochPoolResult.unwrap() as { toJSON: () => unknown }; // eslint-disable-next-line @typescript-eslint/no-explicit-any const epochPool = epochPoolCodec.toJSON() as any; - const userScoreCodec = userScoreResult.unwrap() as { toString: () => string }; - const userScore = BigInt(userScoreCodec.toString()); - const rewardPerPoint = BigInt(epochPool.rewardPerTrustPoint || epochPool.reward_per_trust_point || '0'); + const rewardPerPoint = BigInt(epochPool.rewardPerTrustPoint ?? epochPool.reward_per_trust_point ?? '0'); + const seatShare = BigInt(epochPool.seatShare ?? epochPool.seat_share ?? '0'); + const finalizedAt = Number(epochPool.finalizedAt ?? epochPool.finalized_at ?? 0); - const rewardAmount = userScore * rewardPerPoint; - const rewardFormatted = formatBalance(rewardAmount.toString()); + let rewardAmount = trustScore * rewardPerPoint; + if (seatTakenAt !== null && seatTakenAt <= finalizedAt) rewardAmount += seatShare; + if (rewardAmount === BigInt(0)) continue; - if (parseFloat(rewardFormatted) > 0) { - claimableRewards.push({ epoch: i, amount: rewardFormatted }); - totalClaimable += rewardAmount; - } + claimableRewards.push({ epoch: i, amount: formatBalance(rewardAmount.toString()) }); + totalClaimable += rewardAmount; } catch (err) { console.warn(`Error checking epoch ${i} rewards:`, err); } @@ -607,8 +608,6 @@ export async function getPezRewards( return { currentEpoch, epochStatus, - hasRecordedThisEpoch, - userScoreCurrentEpoch, claimableRewards, totalClaimable: formatBalance(totalClaimable.toString()), hasPendingClaim: claimableRewards.length > 0, @@ -619,44 +618,6 @@ export async function getPezRewards( } } -/** - * Record trust score for the current epoch - * Calls: pezRewards.recordTrustScore() - */ -export async function recordTrustScore( - peopleApi: ApiPromise, - address: string, - signer: any -): Promise<{ success: boolean; error?: string }> { - try { - if (!peopleApi?.tx?.pezRewards?.recordTrustScore) { - return { success: false, error: 'pezRewards pallet not available' }; - } - - const tx = peopleApi.tx.pezRewards.recordTrustScore(); - - return new Promise((resolve) => { - tx.signAndSend(address, { signer }, ({ status, dispatchError }: any) => { - if (status.isInBlock || status.isFinalized) { - if (dispatchError) { - if (dispatchError.isModule) { - const decoded = peopleApi.registry.findMetaError(dispatchError.asModule); - resolve({ success: false, error: `${decoded.section}.${decoded.name}` }); - } else { - resolve({ success: false, error: dispatchError.toString() }); - } - } else { - resolve({ success: true }); - } - } - }); - }); - } catch (error) { - console.error('Error recording trust score:', error); - return { success: false, error: error instanceof Error ? error.message : 'Unknown error' }; - } -} - /** * Claim PEZ reward for a specific epoch * Calls: pezRewards.claimReward(epochIndex) diff --git a/web/package-lock.json b/web/package-lock.json index dfcdc0e4..5ebeb0f5 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -55,7 +55,7 @@ "clsx": "^2.1.1", "cmdk": "^1.0.0", "date-fns": "^3.6.0", - "dompurify": "^3.4.16", + "dompurify": "^3.4.17", "embla-carousel-react": "^8.3.0", "highlight.js": "^11.9.0", "i18next": "^23.7.6", @@ -78,7 +78,7 @@ "tailwind-merge": "^2.5.2", "uuid": "^11.1.0", "vaul": "^0.9.3", - "zod": "^3.23.8" + "zod": "^4.6.7" }, "devDependencies": { "@eslint/js": "^9.9.0", @@ -7697,9 +7697,9 @@ } }, "node_modules/dompurify": { - "version": "3.4.16", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.16.tgz", - "integrity": "sha512-sqo+pNp3qRhCIpbgRi1y8Tgk27Bo2Ry7w0dC1NBeNTdZChWjz9Xb/KOoZbRP/R6pQZ80Qw8YhXw13hWWBbMRnQ==", + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.17.tgz", + "integrity": "sha512-B/pSlYVHQ58kqISD/yDjuJ1yfzI34m1gF4lAod2bwSRhiN4K5Cl3H8Af7hqB2PmTL911tdEudnnXn5FnhRoz0w==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -13914,9 +13914,9 @@ } }, "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.7.tgz", + "integrity": "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/web/package.json b/web/package.json index 70318e79..61d9e361 100644 --- a/web/package.json +++ b/web/package.json @@ -68,7 +68,7 @@ "clsx": "^2.1.1", "cmdk": "^1.0.0", "date-fns": "^3.6.0", - "dompurify": "^3.4.16", + "dompurify": "^3.4.17", "embla-carousel-react": "^8.3.0", "highlight.js": "^11.9.0", "i18next": "^23.7.6", @@ -91,7 +91,7 @@ "tailwind-merge": "^2.5.2", "uuid": "^11.1.0", "vaul": "^0.9.3", - "zod": "^3.23.8" + "zod": "^4.6.7" }, "overrides": { "@pezkuwi/api": "^16.5.39", diff --git a/web/src/components/staking/StakingDashboard.tsx b/web/src/components/staking/StakingDashboard.tsx index 8231b786..a1d79a80 100644 --- a/web/src/components/staking/StakingDashboard.tsx +++ b/web/src/components/staking/StakingDashboard.tsx @@ -22,7 +22,6 @@ import { type StakingInfo } from '@pezkuwi/lib/staking'; import { - recordTrustScore, claimPezReward, getPezRewards, type PezRewardInfo @@ -48,7 +47,6 @@ export const StakingDashboard: React.FC = () => { const [isLoading, setIsLoading] = useState(false); const [isLoadingData, setIsLoadingData] = useState(false); const [pezRewards, setPezRewards] = useState(null); - const [isRecordingScore, setIsRecordingScore] = useState(false); const [isClaimingReward, setIsClaimingReward] = useState(false); // Fetch staking data from Asset Hub @@ -111,34 +109,6 @@ export const StakingDashboard: React.FC = () => { return () => clearInterval(interval); }, [peopleApi, isPeopleReady, selectedAccount]); - const handleRecordTrustScore = async () => { - if (!peopleApi || !selectedAccount) return; - - setIsRecordingScore(true); - try { - const injector = await getSigner(selectedAccount.address, walletSource, peopleApi); - const result = await recordTrustScore(peopleApi, selectedAccount.address, injector.signer); - - if (result.success) { - handleBlockchainSuccess('pezRewards.recorded', toast); - // Refresh PEZ rewards data - setTimeout(async () => { - if (peopleApi && selectedAccount) { - const rewards = await getPezRewards(peopleApi, selectedAccount.address); - setPezRewards(rewards); - } - }, 3000); - } else { - toast.error(result.error || t('staking.recordFailed')); - } - } catch (error) { - if (import.meta.env.DEV) console.error('Record trust score failed:', error); - toast.error(error instanceof Error ? error.message : t('staking.recordFailed')); - } finally { - setIsRecordingScore(false); - } - }; - const handleClaimReward = async (epochIndex: number) => { if (!peopleApi || !selectedAccount) return; @@ -537,27 +507,6 @@ export const StakingDashboard: React.FC = () => {

{t('staking.epoch', { epoch: pezRewards.currentEpoch })}

- {/* Open epoch: Record score or show recorded score */} - {pezRewards.epochStatus === 'Open' && ( - pezRewards.hasRecordedThisEpoch ? ( -
-
- {t('staking.scoreLabel', { score: pezRewards.userScoreCurrentEpoch })} -
-

{t('staking.recordedForEpoch')}

-
- ) : ( - - ) - )} - {/* Claimable rewards */} {pezRewards.hasPendingClaim && ( <> diff --git a/web/src/i18n/locales/ar.ts b/web/src/i18n/locales/ar.ts index e154ddfb..0f792526 100644 --- a/web/src/i18n/locales/ar.ts +++ b/web/src/i18n/locales/ar.ts @@ -883,10 +883,6 @@ export default { 'staking.epochClaimPeriod': 'فترة المطالبة', 'staking.epochClosed': 'مغلق', 'staking.epoch': 'الحقبة {{epoch}}', - 'staking.scoreLabel': 'النقاط: {{score}}', - 'staking.recordedForEpoch': 'مسجّل لهذه الحقبة', - 'staking.recording': 'جاري التسجيل...', - 'staking.recordTrustScore': 'تسجيل نقاط الثقة', 'staking.epochReward': 'الحقبة {{epoch}}: {{amount}} PEZ', 'staking.claim': 'مطالبة', 'staking.description': 'خزّن HEZ لتأمين الشبكة واكسب المكافآت.', @@ -923,7 +919,6 @@ export default { 'staking.minBondError': 'الحد الأدنى للربط هو {{amount}} HEZ', 'staking.insufficientHez': 'رصيد HEZ غير كافٍ', 'staking.insufficientStaked': 'المبلغ المخزّن غير كافٍ', - 'staking.recordFailed': 'فشل في تسجيل نقاط الثقة', 'staking.claimFailed': 'فشل في المطالبة بالمكافأة', // ValidatorPoolDashboard @@ -1628,16 +1623,10 @@ export default { 'wallet.epochClaimPeriod': 'فترة المطالبة', 'wallet.epochClosed': 'مغلق', 'wallet.epoch': 'الحقبة {{epoch}} - {{status}}', - 'wallet.score': 'النقاط: {{score}}', - 'wallet.recordedForEpoch': 'تم التسجيل لهذه الحقبة', - 'wallet.recording': 'جاري التسجيل...', - 'wallet.recordTrustScore': 'تسجيل نقاط الثقة', 'wallet.epochsToClaim': '{{count}} حقبة للمطالبة', 'wallet.epochReward': 'الحقبة {{epoch}}: {{amount}} PEZ', 'wallet.claim': 'مطالبة', 'wallet.noClaimableRewards': 'لا توجد مكافآت للمطالبة', - 'wallet.trustScoreRecorded': 'تم تسجيل نقاط الثقة لهذه الحقبة', - 'wallet.failedToRecordScore': 'فشل في تسجيل نقاط الثقة', 'wallet.rewardClaimed': 'تمت المطالبة بمكافأة {{amount}} PEZ!', 'wallet.failedToClaimReward': 'فشل في المطالبة بالمكافأة', @@ -2314,9 +2303,6 @@ export default { 'dashboard.epochClosed': 'مغلق', 'dashboard.epoch': 'الحقبة {{number}}', 'dashboard.scoreLabel': 'النقاط: {{score}}', - 'dashboard.recorded': 'مسجل', - 'dashboard.recording': 'جاري التسجيل...', - 'dashboard.recordTrustScore': 'سجّل نقاط الثقة', 'dashboard.claim': 'المطالبة', 'dashboard.profileTab': 'الملف الشخصي', 'dashboard.rolesTab': 'الأدوار والتيكي', @@ -2380,8 +2366,6 @@ export default { 'dashboard.connectWalletError': 'يرجى توصيل محفظتك أولاً', 'dashboard.scoreTrackingStarted': 'بدأ تتبع النقاط! سيتم الآن حساب نقاط التكديس.', 'dashboard.scoreTrackingFailed': 'فشل بدء تتبع النقاط', - 'dashboard.trustScoreRecorded': 'تم تسجيل نقاط الثقة لهذه الحقبة.', - 'dashboard.trustScoreRecordFailed': 'فشل تسجيل نقاط الثقة', 'dashboard.rewardClaimed': 'تم المطالبة بـ {{amount}} PEZ مكافأة!', 'dashboard.rewardClaimFailed': 'فشل المطالبة بالمكافأة', 'dashboard.noEmailFound': 'لم يتم العثور على عنوان بريد إلكتروني', diff --git a/web/src/i18n/locales/ckb.ts b/web/src/i18n/locales/ckb.ts index e8c88131..4642a724 100644 --- a/web/src/i18n/locales/ckb.ts +++ b/web/src/i18n/locales/ckb.ts @@ -872,10 +872,6 @@ export default { 'staking.epochClaimPeriod': 'ماوەی داواکردن', 'staking.epochClosed': 'داخراوە', 'staking.epoch': 'سەردەم {{epoch}}', - 'staking.scoreLabel': 'خاڵ: {{score}}', - 'staking.recordedForEpoch': 'بۆ ئەم سەردەمە تۆمارکراوە', - 'staking.recording': 'تۆمارکردن...', - 'staking.recordTrustScore': 'تۆمارکردنی خاڵی متمانە', 'staking.epochReward': 'سەردەم {{epoch}}: {{amount}} PEZ', 'staking.claim': 'داواکردن', 'staking.title': 'ستەیکینگ', @@ -913,7 +909,6 @@ export default { 'staking.minBondError': 'کەمترین بەند {{amount}} HEZ', 'staking.insufficientHez': 'باڵانسی HEZ پێ ناگات', 'staking.insufficientStaked': 'بڕی ستەیککراو پێ ناگات', - 'staking.recordFailed': 'تۆمارکردنی خاڵی متمانە سەرکەوتوو نەبوو', 'staking.claimFailed': 'داواکردنی پاداشت سەرکەوتوو نەبوو', // ValidatorPoolDashboard @@ -1618,16 +1613,10 @@ export default { 'wallet.epochClaimPeriod': 'ماوەی داواکاری', 'wallet.epochClosed': 'داخراوە', 'wallet.epoch': 'سەردەم {{epoch}} - {{status}}', - 'wallet.score': 'نمرە: {{score}}', - 'wallet.recordedForEpoch': 'بۆ ئەم سەردەمە تۆمارکرا', - 'wallet.recording': 'تۆمارکردن...', - 'wallet.recordTrustScore': 'نمرەی متمانە تۆمار بکە', 'wallet.epochsToClaim': '{{count}} سەردەم بۆ داواکاری', 'wallet.epochReward': 'سەردەم {{epoch}}: {{amount}} PEZ', 'wallet.claim': 'داواکاری', 'wallet.noClaimableRewards': 'خەڵاتی داواکراو نییە', - 'wallet.trustScoreRecorded': 'نمرەی متمانە بۆ ئەم سەردەمە تۆمارکرا', - 'wallet.failedToRecordScore': 'تۆمارکردنی نمرەی متمانە سەرکەوتوو نەبوو', 'wallet.rewardClaimed': '{{amount}} PEZ خەڵات داواکرا!', 'wallet.failedToClaimReward': 'داواکردنی خەڵات سەرکەوتوو نەبوو', @@ -2304,9 +2293,6 @@ export default { 'dashboard.epochClosed': 'داخراوە', 'dashboard.epoch': 'سەردەم {{number}}', 'dashboard.scoreLabel': 'پلە: {{score}}', - 'dashboard.recorded': 'تۆمارکرا', - 'dashboard.recording': 'تۆماردەکرێت...', - 'dashboard.recordTrustScore': 'پلەی متمانە تۆمار بکە', 'dashboard.claim': 'داواکردن', 'dashboard.profileTab': 'پرۆفایل', 'dashboard.rolesTab': 'ڕۆڵ و تیکیەکان', @@ -2370,8 +2356,6 @@ export default { 'dashboard.connectWalletError': 'تکایە سەرەتا جزدانەکەت پەیوەست بکە', 'dashboard.scoreTrackingStarted': 'شوێنکەوتنی پلە دەستیپێکرد! پلەی ستەیکینگت ئێستا ئەژماردەکرێت.', 'dashboard.scoreTrackingFailed': 'دەستپێکردنی شوێنکەوتنی پلە سەرنەکەوت', - 'dashboard.trustScoreRecorded': 'پلەی متمانە بۆ ئەم سەردەمە تۆمارکرا.', - 'dashboard.trustScoreRecordFailed': 'تۆمارکردنی پلەی متمانە سەرنەکەوت', 'dashboard.rewardClaimed': '{{amount}} PEZ پاداشت داواکرا!', 'dashboard.rewardClaimFailed': 'داواکردنی پاداشت سەرنەکەوت', 'dashboard.noEmailFound': 'هیچ ناونیشانی ئیمەیڵ نەدۆزرایەوە', diff --git a/web/src/i18n/locales/en.ts b/web/src/i18n/locales/en.ts index 680901a4..f7f5c25c 100644 --- a/web/src/i18n/locales/en.ts +++ b/web/src/i18n/locales/en.ts @@ -1216,10 +1216,6 @@ export default { 'staking.epochClaimPeriod': 'Claim Period', 'staking.epochClosed': 'Closed', 'staking.epoch': 'Epoch {{epoch}}', - 'staking.scoreLabel': 'Score: {{score}}', - 'staking.recordedForEpoch': 'Recorded for this epoch', - 'staking.recording': 'Recording...', - 'staking.recordTrustScore': 'Record Trust Score', 'staking.epochReward': 'Epoch {{epoch}}: {{amount}} PEZ', 'staking.claim': 'Claim', 'staking.title': 'Staking', @@ -1257,7 +1253,6 @@ export default { 'staking.minBondError': 'Minimum bond is {{amount}} HEZ', 'staking.insufficientHez': 'Insufficient HEZ balance', 'staking.insufficientStaked': 'Insufficient staked amount', - 'staking.recordFailed': 'Failed to record trust score', 'staking.claimFailed': 'Failed to claim reward', // ValidatorPoolDashboard @@ -1987,16 +1982,10 @@ export default { 'wallet.epochClaimPeriod': 'Claim Period', 'wallet.epochClosed': 'Closed', 'wallet.epoch': 'Epoch {{epoch}} - {{status}}', - 'wallet.score': 'Score: {{score}}', - 'wallet.recordedForEpoch': 'Recorded for this epoch', - 'wallet.recording': 'Recording...', - 'wallet.recordTrustScore': 'Record Trust Score', 'wallet.epochsToClaim': '{{count}} epoch(s) to claim', 'wallet.epochReward': 'Epoch {{epoch}}: {{amount}} PEZ', 'wallet.claim': 'Claim', 'wallet.noClaimableRewards': 'No claimable rewards', - 'wallet.trustScoreRecorded': 'Trust score recorded for this epoch', - 'wallet.failedToRecordScore': 'Failed to record trust score', 'wallet.rewardClaimed': '{{amount}} PEZ reward claimed!', 'wallet.failedToClaimReward': 'Failed to claim reward', @@ -2693,9 +2682,6 @@ export default { 'dashboard.epochClosed': 'Closed', 'dashboard.epoch': 'Epoch {{number}}', 'dashboard.scoreLabel': 'Score: {{score}}', - 'dashboard.recorded': 'Recorded', - 'dashboard.recording': 'Recording...', - 'dashboard.recordTrustScore': 'Record Trust Score', 'dashboard.claim': 'Claim', 'dashboard.profileTab': 'Profile', 'dashboard.rolesTab': 'Roles & Tikis', @@ -2759,8 +2745,6 @@ export default { 'dashboard.connectWalletError': 'Please connect your wallet first', 'dashboard.scoreTrackingStarted': 'Score tracking started! Your staking score will now be calculated.', 'dashboard.scoreTrackingFailed': 'Failed to start score tracking', - 'dashboard.trustScoreRecorded': 'Trust score recorded for this epoch.', - 'dashboard.trustScoreRecordFailed': 'Failed to record trust score', 'dashboard.rewardClaimed': '{{amount}} PEZ reward claimed!', 'dashboard.rewardClaimFailed': 'Failed to claim reward', 'dashboard.noEmailFound': 'No email address found', diff --git a/web/src/i18n/locales/fa.ts b/web/src/i18n/locales/fa.ts index eb1e680a..54508a33 100644 --- a/web/src/i18n/locales/fa.ts +++ b/web/src/i18n/locales/fa.ts @@ -886,10 +886,6 @@ export default { 'staking.epochClaimPeriod': 'دوره دریافت', 'staking.epochClosed': 'بسته', 'staking.epoch': 'دوره {{epoch}}', - 'staking.scoreLabel': 'امتیاز: {{score}}', - 'staking.recordedForEpoch': 'برای این دوره ثبت شده', - 'staking.recording': 'در حال ثبت...', - 'staking.recordTrustScore': 'ثبت امتیاز اعتماد', 'staking.epochReward': 'دوره {{epoch}}: {{amount}} PEZ', 'staking.claim': 'دریافت', 'staking.title': 'سهام‌گذاری', @@ -927,7 +923,6 @@ export default { 'staking.minBondError': 'حداقل قفل {{amount}} HEZ است', 'staking.insufficientHez': 'موجودی HEZ کافی نیست', 'staking.insufficientStaked': 'مقدار سهام‌گذاری شده کافی نیست', - 'staking.recordFailed': 'ثبت امتیاز اعتماد ناموفق بود', 'staking.claimFailed': 'دریافت پاداش ناموفق بود', // ValidatorPoolDashboard @@ -1850,16 +1845,10 @@ export default { 'wallet.epochClaimPeriod': 'دوره مطالبه', 'wallet.epochClosed': 'بسته', 'wallet.epoch': 'دوره {{epoch}} - {{status}}', - 'wallet.score': 'امتیاز: {{score}}', - 'wallet.recordedForEpoch': 'برای این دوره ثبت شد', - 'wallet.recording': 'در حال ثبت...', - 'wallet.recordTrustScore': 'ثبت امتیاز اعتماد', 'wallet.epochsToClaim': '{{count}} دوره برای مطالبه', 'wallet.epochReward': 'دوره {{epoch}}: {{amount}} PEZ', 'wallet.claim': 'مطالبه', 'wallet.noClaimableRewards': 'پاداش قابل مطالبه‌ای وجود ندارد', - 'wallet.trustScoreRecorded': 'امتیاز اعتماد برای این دوره ثبت شد', - 'wallet.failedToRecordScore': 'ثبت امتیاز اعتماد ناموفق بود', 'wallet.rewardClaimed': 'پاداش {{amount}} PEZ مطالبه شد!', 'wallet.failedToClaimReward': 'مطالبه پاداش ناموفق بود', @@ -2348,9 +2337,6 @@ export default { 'dashboard.epochClosed': 'بسته', 'dashboard.epoch': 'دوره {{number}}', 'dashboard.scoreLabel': 'امتیاز: {{score}}', - 'dashboard.recorded': 'ثبت شده', - 'dashboard.recording': 'در حال ثبت...', - 'dashboard.recordTrustScore': 'ثبت امتیاز اعتماد', 'dashboard.claim': 'مطالبه', 'dashboard.profileTab': 'پروفایل', 'dashboard.rolesTab': 'نقش‌ها و تیکی‌ها', @@ -2414,8 +2400,6 @@ export default { 'dashboard.connectWalletError': 'لطفاً ابتدا کیف پول خود را متصل کنید', 'dashboard.scoreTrackingStarted': 'ردیابی امتیاز شروع شد! امتیاز استیکینگ شما اکنون محاسبه خواهد شد.', 'dashboard.scoreTrackingFailed': 'شروع ردیابی امتیاز ناموفق بود', - 'dashboard.trustScoreRecorded': 'امتیاز اعتماد برای این دوره ثبت شد.', - 'dashboard.trustScoreRecordFailed': 'ثبت امتیاز اعتماد ناموفق بود', 'dashboard.rewardClaimed': '{{amount}} PEZ پاداش مطالبه شد!', 'dashboard.rewardClaimFailed': 'مطالبه پاداش ناموفق بود', 'dashboard.noEmailFound': 'آدرس ایمیلی یافت نشد', diff --git a/web/src/i18n/locales/kmr.ts b/web/src/i18n/locales/kmr.ts index 493dd0c0..ab5698b7 100644 --- a/web/src/i18n/locales/kmr.ts +++ b/web/src/i18n/locales/kmr.ts @@ -880,10 +880,6 @@ export default { 'staking.epochClaimPeriod': 'Serdema Daxwazkirinê', 'staking.epochClosed': 'Girtî', 'staking.epoch': 'Serdem {{epoch}}', - 'staking.scoreLabel': 'Pûan: {{score}}', - 'staking.recordedForEpoch': 'Ji bo vê serdemê hat tomarkirin', - 'staking.recording': 'Tê tomarkirin...', - 'staking.recordTrustScore': 'Pûanê Ewlehiyê Tomar Bike', 'staking.epochReward': 'Serdem {{epoch}}: {{amount}} PEZ', 'staking.claim': 'Daxwaz Bike', 'staking.title': 'Staking', @@ -921,7 +917,6 @@ export default { 'staking.minBondError': 'Girêdana herî kêm {{amount}} HEZ e', 'staking.insufficientHez': 'Hevsengi HEZ bes nîne', 'staking.insufficientStaked': 'Miqdarê stake kirî bes nîne', - 'staking.recordFailed': 'Tomarkirina pûanê ewlehiyê bi ser neket', 'staking.claimFailed': 'Daxwazkirina xelatê bi ser neket', // ValidatorPoolDashboard @@ -1645,16 +1640,10 @@ export default { 'wallet.epochClaimPeriod': 'Dema Daxwazê', 'wallet.epochClosed': 'Girtî', 'wallet.epoch': 'Serdem {{epoch}} - {{status}}', - 'wallet.score': 'Pûan: {{score}}', - 'wallet.recordedForEpoch': 'Ji bo vê serdemê hat tomarkirin', - 'wallet.recording': 'Tê tomarkirin...', - 'wallet.recordTrustScore': 'Pûana Pêbaweriyê Tomar Bike', 'wallet.epochsToClaim': '{{count}} serdem ji bo daxwazê', 'wallet.epochReward': 'Serdem {{epoch}}: {{amount}} PEZ', 'wallet.claim': 'Daxwaz Bike', 'wallet.noClaimableRewards': 'Xelata daxwazkirî tune', - 'wallet.trustScoreRecorded': 'Pûana pêbaweriyê ji bo vê serdemê hat tomarkirin', - 'wallet.failedToRecordScore': 'Tomarkirina pûana pêbaweriyê bi ser neket', 'wallet.rewardClaimed': '{{amount}} PEZ xelat hat daxwazkirin!', 'wallet.failedToClaimReward': 'Daxwazkirina xelatê bi ser neket', @@ -2331,9 +2320,6 @@ export default { 'dashboard.epochClosed': 'Girtî', 'dashboard.epoch': 'Serdem {{number}}', 'dashboard.scoreLabel': 'Puan: {{score}}', - 'dashboard.recorded': 'Hat tomarkirin', - 'dashboard.recording': 'Tê tomarkirin...', - 'dashboard.recordTrustScore': 'Puana Pêbaweriyê Tomar Bike', 'dashboard.claim': 'Daxwaz Bike', 'dashboard.profileTab': 'Profîl', 'dashboard.rolesTab': 'Rol û Tikî', @@ -2397,8 +2383,6 @@ export default { 'dashboard.connectWalletError': 'Ji kerema xwe pêşî wallet-ê xwe girêbidin', 'dashboard.scoreTrackingStarted': 'Şopandina puanê dest pê kir! Puana staking a we niha tê hesibandin.', 'dashboard.scoreTrackingFailed': 'Destpêkirina şopandina puanê biserneket', - 'dashboard.trustScoreRecorded': 'Puana pêbaweriyê ji bo vê serdemê hat tomarkirin.', - 'dashboard.trustScoreRecordFailed': 'Tomarkirina puana pêbaweriyê biserneket', 'dashboard.rewardClaimed': '{{amount}} PEZ xelat hat daxwaz kirin!', 'dashboard.rewardClaimFailed': 'Daxwazkirina xelatê biserneket', 'dashboard.noEmailFound': 'Tu navnîşana e-mailê nehat dîtin', diff --git a/web/src/i18n/locales/tr.ts b/web/src/i18n/locales/tr.ts index 61692e96..d76bf904 100644 --- a/web/src/i18n/locales/tr.ts +++ b/web/src/i18n/locales/tr.ts @@ -874,10 +874,6 @@ export default { 'staking.epochClaimPeriod': 'Talep Dönemi', 'staking.epochClosed': 'Kapalı', 'staking.epoch': 'Epoch {{epoch}}', - 'staking.scoreLabel': 'Puan: {{score}}', - 'staking.recordedForEpoch': 'Bu epoch için kaydedildi', - 'staking.recording': 'Kaydediliyor...', - 'staking.recordTrustScore': 'Güven Puanını Kaydet', 'staking.epochReward': 'Epoch {{epoch}}: {{amount}} PEZ', 'staking.claim': 'Talep Et', 'staking.title': 'Stake Etme', @@ -915,7 +911,6 @@ export default { 'staking.minBondError': 'Minimum bağlama miktarı {{amount}} HEZ', 'staking.insufficientHez': 'Yetersiz HEZ bakiyesi', 'staking.insufficientStaked': 'Yetersiz stake miktarı', - 'staking.recordFailed': 'Güven puanı kaydedilemedi', 'staking.claimFailed': 'Ödül talep edilemedi', // ValidatorPoolDashboard @@ -1639,16 +1634,10 @@ export default { 'wallet.epochClaimPeriod': 'Talep Dönemi', 'wallet.epochClosed': 'Kapalı', 'wallet.epoch': 'Dönem {{epoch}} - {{status}}', - 'wallet.score': 'Skor: {{score}}', - 'wallet.recordedForEpoch': 'Bu dönem için kaydedildi', - 'wallet.recording': 'Kaydediliyor...', - 'wallet.recordTrustScore': 'Güven Skorunu Kaydet', 'wallet.epochsToClaim': '{{count}} dönem talep edilecek', 'wallet.epochReward': 'Dönem {{epoch}}: {{amount}} PEZ', 'wallet.claim': 'Talep Et', 'wallet.noClaimableRewards': 'Talep edilecek ödül yok', - 'wallet.trustScoreRecorded': 'Güven skoru bu dönem için kaydedildi', - 'wallet.failedToRecordScore': 'Güven skoru kaydedilemedi', 'wallet.rewardClaimed': '{{amount}} PEZ ödülü talep edildi!', 'wallet.failedToClaimReward': 'Ödül talep edilemedi', @@ -2332,9 +2321,6 @@ export default { 'dashboard.epochClosed': 'Kapalı', 'dashboard.epoch': 'Dönem {{number}}', 'dashboard.scoreLabel': 'Puan: {{score}}', - 'dashboard.recorded': 'Kaydedildi', - 'dashboard.recording': 'Kaydediliyor...', - 'dashboard.recordTrustScore': 'Güven Puanını Kaydet', 'dashboard.claim': 'Talep Et', 'dashboard.profileTab': 'Profil', 'dashboard.rolesTab': 'Roller ve Tikiler', @@ -2398,8 +2384,6 @@ export default { 'dashboard.connectWalletError': 'Lütfen önce cüzdanınızı bağlayın', 'dashboard.scoreTrackingStarted': 'Puan takibi başlatıldı! Stake puanınız artık hesaplanacak.', 'dashboard.scoreTrackingFailed': 'Puan takibi başlatılamadı', - 'dashboard.trustScoreRecorded': 'Bu dönem için güven puanı kaydedildi.', - 'dashboard.trustScoreRecordFailed': 'Güven puanı kaydedilemedi', 'dashboard.rewardClaimed': '{{amount}} PEZ ödül talep edildi!', 'dashboard.rewardClaimFailed': 'Ödül talep edilemedi', 'dashboard.noEmailFound': 'E-posta adresi bulunamadı', diff --git a/web/src/pages/Dashboard.tsx b/web/src/pages/Dashboard.tsx index ac765562..8f1d544f 100644 --- a/web/src/pages/Dashboard.tsx +++ b/web/src/pages/Dashboard.tsx @@ -11,7 +11,7 @@ import { supabase } from '@/lib/supabase'; import { User, Mail, Phone, Globe, MapPin, Calendar, Shield, AlertCircle, ArrowLeft, Award, Users, TrendingUp, UserMinus, Play, Loader2, Coins } from 'lucide-react'; import { useToast } from '@/hooks/use-toast'; import { fetchUserTikis, getPrimaryRole, getTikiDisplayName, getTikiColor, getTikiEmoji, getUserRoleCategories, getAllTikiNFTDetails, generateCitizenNumber, type TikiNFTDetails } from '@pezkuwi/lib/tiki'; -import { getAllScores, getStakingScoreStatus, startScoreTracking, getPezRewards, recordTrustScore, claimPezReward, type UserScores, type StakingScoreStatus, type PezRewardInfo, formatDuration } from '@pezkuwi/lib/scores'; +import { getAllScores, getStakingScoreStatus, startScoreTracking, getPezRewards, claimPezReward, type UserScores, type StakingScoreStatus, type PezRewardInfo, formatDuration } from '@pezkuwi/lib/scores'; import { getSigner } from '@/lib/get-signer'; import { getKycStatus } from '@pezkuwi/lib/kyc'; import { ReferralDashboard } from '@/components/referral/ReferralDashboard'; @@ -41,7 +41,6 @@ export default function Dashboard() { const [kycStatus, setKycStatus] = useState('NotStarted'); const [renouncingCitizenship, setRenouncingCitizenship] = useState(false); const [pezRewards, setPezRewards] = useState(null); - const [isRecordingScore, setIsRecordingScore] = useState(false); const [isClaimingReward, setIsClaimingReward] = useState(false); const [nftDetails, setNftDetails] = useState<{ citizenNFT: TikiNFTDetails | null; roleNFTs: TikiNFTDetails[]; totalNFTs: number }>({ citizenNFT: null, @@ -188,27 +187,6 @@ export default function Dashboard() { } }; - const handleRecordTrustScore = async () => { - if (!peopleApi || !selectedAccount) return; - - setIsRecordingScore(true); - try { - const injector = await getSigner(selectedAccount.address, walletSource, peopleApi); - const result = await recordTrustScore(peopleApi, selectedAccount.address, injector.signer); - - if (result.success) { - toast({ title: t('common.success'), description: t('dashboard.trustScoreRecorded') }); - fetchScoresAndTikis(); - } else { - toast({ title: t('common.error'), description: result.error || t('dashboard.trustScoreRecordFailed'), variant: "destructive" }); - } - } catch (error) { - toast({ title: t('common.error'), description: error instanceof Error ? error.message : t('dashboard.trustScoreRecordFailed'), variant: "destructive" }); - } finally { - setIsRecordingScore(false); - } - }; - const handleClaimReward = async (epochIndex: number) => { if (!peopleApi || !selectedAccount) return; @@ -655,35 +633,6 @@ export default function Dashboard() {

{t('dashboard.epoch', { number: pezRewards.currentEpoch })}

- {/* Open epoch: Record score or show recorded score */} - {pezRewards.epochStatus === 'Open' && ( - pezRewards.hasRecordedThisEpoch ? ( -
-
Score: {pezRewards.userScoreCurrentEpoch}
- {t('dashboard.recorded')} -
- ) : ( - - ) - )} - {/* Claimable rewards */} {pezRewards.hasPendingClaim ? (
@@ -706,9 +655,7 @@ export default function Dashboard() { ))}
) : ( - !pezRewards.hasRecordedThisEpoch && pezRewards.epochStatus !== 'Open' && ( -
0 PEZ
- ) +
0 PEZ
)}
diff --git a/web/src/pages/WalletDashboard.tsx b/web/src/pages/WalletDashboard.tsx index c45fa270..900b4b2f 100644 --- a/web/src/pages/WalletDashboard.tsx +++ b/web/src/pages/WalletDashboard.tsx @@ -8,10 +8,10 @@ import { ReceiveModal } from '@/components/ReceiveModal'; import { TransactionHistory } from '@/components/TransactionHistory'; import { NftList } from '@/components/NftList'; import { Button } from '@/components/ui/button'; -import { ArrowUpRight, ArrowDownRight, History, ArrowLeft, RefreshCw, Coins, Loader2 } from 'lucide-react'; +import { ArrowUpRight, ArrowDownRight, History, ArrowLeft, RefreshCw, Coins } from 'lucide-react'; import { toast } from 'sonner'; import { getSigner } from '@/lib/get-signer'; -import { getPezRewards, recordTrustScore, claimPezReward, type PezRewardInfo } from '@pezkuwi/lib/scores'; +import { getPezRewards, claimPezReward, type PezRewardInfo } from '@pezkuwi/lib/scores'; import { isMultisigMember, BRIDGE_MULTISIG_SPECIFIC_ADDRESSES } from '@pezkuwi/lib/multisig'; import { ShieldCheck } from 'lucide-react'; @@ -38,7 +38,6 @@ const WalletDashboard: React.FC = () => { const [recentTransactions, setRecentTransactions] = useState([]); const [isLoadingRecent, setIsLoadingRecent] = useState(false); const [pezRewards, setPezRewards] = useState(null); - const [isRecordingScore, setIsRecordingScore] = useState(false); const [isClaimingReward, setIsClaimingReward] = useState(false); const [isMultisigSigner, setIsMultisigSigner] = useState(false); @@ -258,26 +257,6 @@ const WalletDashboard: React.FC = () => { return () => clearInterval(interval); }, [peopleApi, isPeopleReady, selectedAccount]); - const handleRecordTrustScore = async () => { - if (!peopleApi || !selectedAccount) return; - setIsRecordingScore(true); - try { - const injector = await getSigner(selectedAccount.address, walletSource, peopleApi); - const result = await recordTrustScore(peopleApi, selectedAccount.address, injector.signer); - if (result.success) { - toast.success(t('wallet.trustScoreRecorded')); - const rewards = await getPezRewards(peopleApi, selectedAccount.address); - setPezRewards(rewards); - } else { - toast.error(result.error || t('wallet.failedToRecordScore')); - } - } catch (error) { - toast.error(error instanceof Error ? error.message : t('wallet.failedToRecordScore')); - } finally { - setIsRecordingScore(false); - } - }; - const handleClaimReward = async (epochIndex: number) => { if (!peopleApi || !selectedAccount) return; setIsClaimingReward(true); @@ -478,30 +457,6 @@ const WalletDashboard: React.FC = () => {
- {/* Open epoch: Record score */} - {pezRewards.epochStatus === 'Open' && ( - pezRewards.hasRecordedThisEpoch ? ( -
- {t('wallet.score', { score: pezRewards.userScoreCurrentEpoch })} - {t('wallet.recordedForEpoch')} -
- ) : ( - - ) - )} - {/* Claimable rewards */} {pezRewards.hasPendingClaim ? (
@@ -524,9 +479,7 @@ const WalletDashboard: React.FC = () => { ))}
) : ( - !pezRewards.hasRecordedThisEpoch && pezRewards.epochStatus !== 'Open' && ( -
{t('wallet.noClaimableRewards')}
- ) +
{t('wallet.noClaimableRewards')}
)} )}