mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-10-28 21:39:49 +00:00
rewards: claim what the chain pays, without recording a score first (#61)
* rewards: claim what the chain pays, without recording a score first The People chain has no pezRewards.recordTrustScore and no userEpochScores since the payroll started holding the roll still through each claim window: a claim pays the trust score at claim time times the epoch's rate, plus the seat share for a Parlementer seat taken by the time of the roll. The app still asked for the recorded score, so the claimable list was always empty, and three screens offered a Record Trust Score button that signed a call that does not exist. The buttons, their handlers and texts, and the messages for an error and a success that can no longer happen are removed; the claimable amount is worked out as the chain's entitlement does, and the empty state shows in every epoch status. Past recordTrustScore extrinsics in the transaction history keep their label. * backend: body-parser 2.4.0 and ip-address 10.7.5 npm audit on the production dependencies: body-parser 2.0.0-2.3.0 (GHSA-27r3-jxmh-p828, high, denial of service by trailing bytes after a compressed body) and ip-address <=10.7.3 (GHSA-rxp7-6hxx-x8q5, moderate). Lockfile only; npm audit --omit=dev finds nothing after. * ops: lower the typecheck baseline to 335 Four TS2339 errors in shared/lib/scores.ts went with the userEpochScores code. * web: dompurify 3.4.17 and zod 4.6.7 npm audit on the production dependencies: dompurify <=3.4.16 (critical: GHSA-cg2g-xh64-v4q7, GHSA-mrv2-3pqr-j5jr, GHSA-c6gr-qvv4-5v3f) and zod <4.6.6 (high, GHSA-mrhx-c7xc-m3w5, fixed only in 4.x). No code imports zod; it is here for abitype, whose peer range is ^3.22.0 || ^4.0.0. Typecheck ratchet, lint and the build are unchanged.
This commit is contained in:
1 parent
ac730481d9
commit
03e6db8461
15 files changed
+57
-351
No files matched your search
Generated
+8
-8
@@ -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"
|
||||
|
||||
+2
-2
@@ -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",
|
||||
|
||||
@@ -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<PezRewardInfo | null>(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 = () => {
|
||||
<div className="space-y-2">
|
||||
<p className="text-xs text-gray-500">{t('staking.epoch', { epoch: pezRewards.currentEpoch })}</p>
|
||||
|
||||
{/* Open epoch: Record score or show recorded score */}
|
||||
{pezRewards.epochStatus === 'Open' && (
|
||||
pezRewards.hasRecordedThisEpoch ? (
|
||||
<div>
|
||||
<div className="text-lg font-bold text-green-400">
|
||||
{t('staking.scoreLabel', { score: pezRewards.userScoreCurrentEpoch })}
|
||||
</div>
|
||||
<p className="text-xs text-gray-500">{t('staking.recordedForEpoch')}</p>
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={handleRecordTrustScore}
|
||||
disabled={isRecordingScore}
|
||||
className="w-full bg-green-600 hover:bg-green-700"
|
||||
>
|
||||
{isRecordingScore ? t('staking.recording') : t('staking.recordTrustScore')}
|
||||
</Button>
|
||||
)
|
||||
)}
|
||||
|
||||
{/* Claimable rewards */}
|
||||
{pezRewards.hasPendingClaim && (
|
||||
<>
|
||||
|
||||
@@ -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': 'لم يتم العثور على عنوان بريد إلكتروني',
|
||||
|
||||
@@ -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': 'هیچ ناونیشانی ئیمەیڵ نەدۆزرایەوە',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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': 'آدرس ایمیلی یافت نشد',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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ı',
|
||||
|
||||
@@ -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<string>('NotStarted');
|
||||
const [renouncingCitizenship, setRenouncingCitizenship] = useState(false);
|
||||
const [pezRewards, setPezRewards] = useState<PezRewardInfo | null>(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() {
|
||||
<div className="space-y-3">
|
||||
<p className="text-xs text-muted-foreground">{t('dashboard.epoch', { number: pezRewards.currentEpoch })}</p>
|
||||
|
||||
{/* Open epoch: Record score or show recorded score */}
|
||||
{pezRewards.epochStatus === 'Open' && (
|
||||
pezRewards.hasRecordedThisEpoch ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="text-lg font-bold text-green-600">Score: {pezRewards.userScoreCurrentEpoch}</div>
|
||||
<Badge variant="outline" className="text-green-600 border-green-300">{t('dashboard.recorded')}</Badge>
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
size="sm"
|
||||
className="w-full bg-green-600 hover:bg-green-700"
|
||||
onClick={handleRecordTrustScore}
|
||||
disabled={isRecordingScore || loadingScores}
|
||||
>
|
||||
{isRecordingScore ? (
|
||||
<>
|
||||
<Loader2 className="h-3 w-3 mr-1 animate-spin" />
|
||||
{t('dashboard.recording')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Play className="h-3 w-3 mr-1" />
|
||||
{t('dashboard.recordTrustScore')}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
)
|
||||
)}
|
||||
|
||||
{/* Claimable rewards */}
|
||||
{pezRewards.hasPendingClaim ? (
|
||||
<div className="space-y-2">
|
||||
@@ -706,9 +655,7 @@ export default function Dashboard() {
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
!pezRewards.hasRecordedThisEpoch && pezRewards.epochStatus !== 'Open' && (
|
||||
<div className="text-2xl font-bold text-muted-foreground">0 PEZ</div>
|
||||
)
|
||||
<div className="text-2xl font-bold text-muted-foreground">0 PEZ</div>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
@@ -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<Transaction[]>([]);
|
||||
const [isLoadingRecent, setIsLoadingRecent] = useState(false);
|
||||
const [pezRewards, setPezRewards] = useState<PezRewardInfo | null>(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 = () => {
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Open epoch: Record score */}
|
||||
{pezRewards.epochStatus === 'Open' && (
|
||||
pezRewards.hasRecordedThisEpoch ? (
|
||||
<div className="flex items-center gap-2 mb-3">
|
||||
<span className="text-green-400 font-semibold">{t('wallet.score', { score: pezRewards.userScoreCurrentEpoch })}</span>
|
||||
<span className="text-xs text-gray-500">{t('wallet.recordedForEpoch')}</span>
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={handleRecordTrustScore}
|
||||
disabled={isRecordingScore}
|
||||
className="w-full mb-3 bg-green-600 hover:bg-green-700"
|
||||
>
|
||||
{isRecordingScore ? (
|
||||
<>
|
||||
<Loader2 className="w-3 h-3 mr-1 animate-spin" />
|
||||
{t('wallet.recording')}
|
||||
</>
|
||||
) : t('wallet.recordTrustScore')}
|
||||
</Button>
|
||||
)
|
||||
)}
|
||||
|
||||
{/* Claimable rewards */}
|
||||
{pezRewards.hasPendingClaim ? (
|
||||
<div className="space-y-2">
|
||||
@@ -524,9 +479,7 @@ const WalletDashboard: React.FC = () => {
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
!pezRewards.hasRecordedThisEpoch && pezRewards.epochStatus !== 'Open' && (
|
||||
<div className="text-gray-500 text-sm">{t('wallet.noClaimableRewards')}</div>
|
||||
)
|
||||
<div className="text-gray-500 text-sm">{t('wallet.noClaimableRewards')}</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in new issue
Block a user