From 82a6a51b2234de19a3d4646881949e52271a4e66 Mon Sep 17 00:00:00 2001 From: Kurdistan Tech Ministry Date: Tue, 10 Feb 2026 18:09:26 +0300 Subject: [PATCH] fix: use People Chain API for tiki and identityKyc pallets - DashboardContext: query tiki/kyc from peopleApi instead of relay api - KycApprovalTab: use peopleApi for identityKyc.pendingKycApplications - NewCitizenApplication: all KYC operations now use People Chain These pallets are on People Chain, not Relay Chain. This fixes the "mafe te tuneye" error when accessing Citizens portal. --- web/src/components/admin/KycApprovalTab.tsx | 20 ++++--- .../citizenship/NewCitizenApplication.tsx | 56 ++++++++++--------- web/src/contexts/DashboardContext.tsx | 18 +++--- 3 files changed, 50 insertions(+), 44 deletions(-) diff --git a/web/src/components/admin/KycApprovalTab.tsx b/web/src/components/admin/KycApprovalTab.tsx index a8fa8954..21e2db7f 100644 --- a/web/src/components/admin/KycApprovalTab.tsx +++ b/web/src/components/admin/KycApprovalTab.tsx @@ -37,7 +37,8 @@ interface IdentityInfo { } export function KycApprovalTab() { - const { api, isApiReady, selectedAccount, connectWallet } = usePezkuwi(); + // identityKyc pallet is on People Chain, dynamicCommissionCollective is on Relay Chain + const { api, isApiReady, peopleApi, isPeopleReady, selectedAccount, connectWallet } = usePezkuwi(); const { toast } = useToast(); const [loading, setLoading] = useState(true); @@ -47,27 +48,28 @@ export function KycApprovalTab() { const [processing, setProcessing] = useState(false); const [showDetailsModal, setShowDetailsModal] = useState(false); - // Load pending KYC applications + // Load pending KYC applications from People Chain useEffect(() => { - if (!api || !isApiReady) { + if (!peopleApi || !isPeopleReady) { return; } loadPendingApplications(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [api, isApiReady]); + }, [peopleApi, isPeopleReady]); const loadPendingApplications = async () => { - if (!api || !isApiReady) { + // identityKyc pallet is on People Chain + if (!peopleApi || !isPeopleReady) { setLoading(false); return; } setLoading(true); try { - // Get all pending applications - const entries = await api.query.identityKyc.pendingKycApplications.entries(); + // Get all pending applications from People Chain + const entries = await peopleApi.query.identityKyc.pendingKycApplications.entries(); const apps: PendingApplication[] = []; const identityMap = new Map(); @@ -76,9 +78,9 @@ export function KycApprovalTab() { const address = key.args[0].toString(); const application = value.toJSON() as Record; - // Get identity info for this address + // Get identity info for this address from People Chain try { - const identity = await api.query.identityKyc.identities(address); + const identity = await peopleApi.query.identityKyc.identities(address); if (!identity.isEmpty) { const identityData = identity.toJSON() as Record; identityMap.set(address, { diff --git a/web/src/components/citizenship/NewCitizenApplication.tsx b/web/src/components/citizenship/NewCitizenApplication.tsx index efc9bbb7..8f517c14 100644 --- a/web/src/components/citizenship/NewCitizenApplication.tsx +++ b/web/src/components/citizenship/NewCitizenApplication.tsx @@ -22,7 +22,8 @@ interface NewCitizenApplicationProps { type FormData = Omit; export const NewCitizenApplication: React.FC = ({ onClose, referrerAddress }) => { - const { api, isApiReady, selectedAccount, connectWallet } = usePezkuwi(); + // identityKyc pallet is on People Chain + const { api, isApiReady, peopleApi, isPeopleReady, selectedAccount, connectWallet } = usePezkuwi(); const { register, handleSubmit, watch, setValue, formState: { errors } } = useForm(); const [submitting, setSubmitting] = useState(false); @@ -33,13 +34,15 @@ export const NewCitizenApplication: React.FC = ({ on const [agreed, setAgreed] = useState(false); const [confirming, setConfirming] = useState(false); const [applicationHash, setApplicationHash] = useState(''); + const [checkingStatus, setCheckingStatus] = useState(false); const maritalStatus = watch('maritalStatus'); const childrenCount = watch('childrenCount'); const handleApprove = async () => { - if (!api || !selectedAccount) { - setError('Please connect your wallet first'); + // identityKyc pallet is on People Chain + if (!peopleApi || !isPeopleReady || !selectedAccount) { + setError('Please connect your wallet and wait for People Chain connection'); return; } @@ -48,15 +51,15 @@ export const NewCitizenApplication: React.FC = ({ on const { web3FromAddress } = await import('@pezkuwi/extension-dapp'); const injector = await web3FromAddress(selectedAccount.address); - if (import.meta.env.DEV) console.log('Confirming citizenship application (self-confirmation)...'); + if (import.meta.env.DEV) console.log('Confirming citizenship application on People Chain (self-confirmation)...'); - // Call confirm_citizenship() extrinsic - self-confirmation for Welati Tiki - const tx = api.tx.identityKyc.confirmCitizenship(); + // Call confirm_citizenship() extrinsic on People Chain - self-confirmation for Welati Tiki + const tx = peopleApi.tx.identityKyc.confirmCitizenship(); await tx.signAndSend(selectedAccount.address, { signer: injector.signer }, ({ status, events, dispatchError }) => { if (dispatchError) { if (dispatchError.isModule) { - const decoded = api.registry.findMetaError(dispatchError.asModule); + const decoded = peopleApi.registry.findMetaError(dispatchError.asModule); if (import.meta.env.DEV) console.error(`${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`); setError(`${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`); } else { @@ -68,7 +71,7 @@ export const NewCitizenApplication: React.FC = ({ on } if (status.isInBlock || status.isFinalized) { - if (import.meta.env.DEV) console.log('✅ Citizenship confirmed successfully!'); + if (import.meta.env.DEV) console.log('✅ Citizenship confirmed successfully on People Chain!'); if (import.meta.env.DEV) console.log('Block hash:', status.asInBlock || status.asFinalized); // Check for CitizenshipConfirmed event @@ -105,17 +108,17 @@ export const NewCitizenApplication: React.FC = ({ on window.location.href = '/'; }; - // Check KYC status on mount + // Check KYC status on mount (identityKyc pallet is on People Chain) useEffect(() => { const checkKycStatus = async () => { - if (!api || !isApiReady || !selectedAccount) { + if (!peopleApi || !isPeopleReady || !selectedAccount) { return; } setCheckingStatus(true); try { - const status = await getKycStatus(api, selectedAccount.address); - if (import.meta.env.DEV) console.log('Current KYC Status:', status); + const status = await getKycStatus(peopleApi, selectedAccount.address); + if (import.meta.env.DEV) console.log('Current KYC Status from People Chain:', status); if (status === 'Approved') { if (import.meta.env.DEV) console.log('KYC already approved! Redirecting to dashboard...'); @@ -138,21 +141,21 @@ export const NewCitizenApplication: React.FC = ({ on }; checkKycStatus(); - }, [api, isApiReady, selectedAccount, onClose]); + }, [peopleApi, isPeopleReady, selectedAccount, onClose]); - // Subscribe to KYC approval events + // Subscribe to KYC approval events on People Chain useEffect(() => { - if (!api || !isApiReady || !selectedAccount || !waitingForApproval) { + if (!peopleApi || !isPeopleReady || !selectedAccount || !waitingForApproval) { return; } - if (import.meta.env.DEV) console.log('Setting up KYC approval listener for:', selectedAccount.address); + if (import.meta.env.DEV) console.log('Setting up KYC approval listener on People Chain for:', selectedAccount.address); const unsubscribe = subscribeToKycApproval( - api, + peopleApi, selectedAccount.address, () => { - if (import.meta.env.DEV) console.log('KYC Approved! Redirecting to dashboard...'); + if (import.meta.env.DEV) console.log('KYC Approved on People Chain! Redirecting to dashboard...'); setKycApproved(true); setWaitingForApproval(false); @@ -173,11 +176,12 @@ export const NewCitizenApplication: React.FC = ({ on unsubscribe(); } }; - }, [api, isApiReady, selectedAccount, waitingForApproval, onClose]); + }, [peopleApi, isPeopleReady, selectedAccount, waitingForApproval, onClose]); const onSubmit = async (data: FormData) => { - if (!api || !isApiReady || !selectedAccount) { - setError('Please connect your wallet first'); + // identityKyc pallet is on People Chain + if (!peopleApi || !isPeopleReady || !selectedAccount) { + setError('Please connect your wallet and wait for People Chain connection'); return; } @@ -190,8 +194,8 @@ export const NewCitizenApplication: React.FC = ({ on setSubmitting(true); try { - // Check KYC status before submitting - const currentStatus = await getKycStatus(api, selectedAccount.address); + // Check KYC status before submitting (from People Chain) + const currentStatus = await getKycStatus(peopleApi, selectedAccount.address); if (currentStatus === 'Approved') { setError('Your KYC has already been approved! Redirecting to dashboard...'); @@ -250,10 +254,10 @@ export const NewCitizenApplication: React.FC = ({ on throw new Error(`Invalid IPFS CID: ${cidString}`); } - // Submit to blockchain - if (import.meta.env.DEV) console.log('Submitting KYC application to blockchain...'); + // Submit to blockchain (identityKyc pallet is on People Chain) + if (import.meta.env.DEV) console.log('Submitting KYC application to People Chain...'); const result = await submitKycApplication( - api, + peopleApi, selectedAccount, citizenshipData.fullName, citizenshipData.email, diff --git a/web/src/contexts/DashboardContext.tsx b/web/src/contexts/DashboardContext.tsx index 8ae46b23..f27d551f 100644 --- a/web/src/contexts/DashboardContext.tsx +++ b/web/src/contexts/DashboardContext.tsx @@ -17,7 +17,7 @@ const DashboardContext = createContext(undefined); export function DashboardProvider({ children }: { children: ReactNode }) { const { user } = useAuth(); - const { api, isApiReady, selectedAccount } = usePezkuwi(); + const { peopleApi, isPeopleReady, selectedAccount } = usePezkuwi(); const [profile, setProfile] = useState | null>(null); const [nftDetails, setNftDetails] = useState<{ citizenNFT: TikiNFTDetails | null; roleNFTs: TikiNFTDetails[]; totalNFTs: number }>({ citizenNFT: null, @@ -54,29 +54,29 @@ export function DashboardProvider({ children }: { children: ReactNode }) { }, [user]); const fetchScoresAndTikis = useCallback(async () => { - if (!selectedAccount || !api) return; + // tiki and identityKyc pallets are on People Chain, not Relay Chain + if (!selectedAccount || !peopleApi || !isPeopleReady) return; setLoading(true); try { - const status = await getKycStatus(api, selectedAccount.address); + const status = await getKycStatus(peopleApi, selectedAccount.address); setKycStatus(status); - const details = await getAllTikiNFTDetails(api, selectedAccount.address); + const details = await getAllTikiNFTDetails(peopleApi, selectedAccount.address); setNftDetails(details); } catch (error) { - if (import.meta.env.DEV) console.error('Error fetching data:', error); + if (import.meta.env.DEV) console.error('Error fetching tiki/kyc data from People Chain:', error); } finally { setLoading(false); } - }, [selectedAccount, api]); + }, [selectedAccount, peopleApi, isPeopleReady]); useEffect(() => { fetchProfile(); - if (selectedAccount && api && isApiReady) { + if (selectedAccount && peopleApi && isPeopleReady) { fetchScoresAndTikis(); - } - }, [user, selectedAccount, api, isApiReady, fetchProfile, fetchScoresAndTikis]); + }, [user, selectedAccount, peopleApi, isPeopleReady, fetchProfile, fetchScoresAndTikis]); const citizenNumber = nftDetails.citizenNFT ? generateCitizenNumber(nftDetails.citizenNFT.owner, nftDetails.citizenNFT.collectionId, nftDetails.citizenNFT.itemId)