mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-06-13 03:11:02 +00:00
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.
This commit is contained in:
@@ -37,7 +37,8 @@ interface IdentityInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function KycApprovalTab() {
|
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 { toast } = useToast();
|
||||||
|
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
@@ -47,27 +48,28 @@ export function KycApprovalTab() {
|
|||||||
const [processing, setProcessing] = useState(false);
|
const [processing, setProcessing] = useState(false);
|
||||||
const [showDetailsModal, setShowDetailsModal] = useState(false);
|
const [showDetailsModal, setShowDetailsModal] = useState(false);
|
||||||
|
|
||||||
// Load pending KYC applications
|
// Load pending KYC applications from People Chain
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!api || !isApiReady) {
|
if (!peopleApi || !isPeopleReady) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPendingApplications();
|
loadPendingApplications();
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [api, isApiReady]);
|
}, [peopleApi, isPeopleReady]);
|
||||||
|
|
||||||
|
|
||||||
const loadPendingApplications = async () => {
|
const loadPendingApplications = async () => {
|
||||||
if (!api || !isApiReady) {
|
// identityKyc pallet is on People Chain
|
||||||
|
if (!peopleApi || !isPeopleReady) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
// Get all pending applications
|
// Get all pending applications from People Chain
|
||||||
const entries = await api.query.identityKyc.pendingKycApplications.entries();
|
const entries = await peopleApi.query.identityKyc.pendingKycApplications.entries();
|
||||||
|
|
||||||
const apps: PendingApplication[] = [];
|
const apps: PendingApplication[] = [];
|
||||||
const identityMap = new Map<string, IdentityInfo>();
|
const identityMap = new Map<string, IdentityInfo>();
|
||||||
@@ -76,9 +78,9 @@ export function KycApprovalTab() {
|
|||||||
const address = key.args[0].toString();
|
const address = key.args[0].toString();
|
||||||
const application = value.toJSON() as Record<string, unknown>;
|
const application = value.toJSON() as Record<string, unknown>;
|
||||||
|
|
||||||
// Get identity info for this address
|
// Get identity info for this address from People Chain
|
||||||
try {
|
try {
|
||||||
const identity = await api.query.identityKyc.identities(address);
|
const identity = await peopleApi.query.identityKyc.identities(address);
|
||||||
if (!identity.isEmpty) {
|
if (!identity.isEmpty) {
|
||||||
const identityData = identity.toJSON() as Record<string, unknown>;
|
const identityData = identity.toJSON() as Record<string, unknown>;
|
||||||
identityMap.set(address, {
|
identityMap.set(address, {
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ interface NewCitizenApplicationProps {
|
|||||||
type FormData = Omit<CitizenshipData, 'walletAddress' | 'timestamp'>;
|
type FormData = Omit<CitizenshipData, 'walletAddress' | 'timestamp'>;
|
||||||
|
|
||||||
export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ onClose, referrerAddress }) => {
|
export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ 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<FormData>();
|
const { register, handleSubmit, watch, setValue, formState: { errors } } = useForm<FormData>();
|
||||||
|
|
||||||
const [submitting, setSubmitting] = useState(false);
|
const [submitting, setSubmitting] = useState(false);
|
||||||
@@ -33,13 +34,15 @@ export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ on
|
|||||||
const [agreed, setAgreed] = useState(false);
|
const [agreed, setAgreed] = useState(false);
|
||||||
const [confirming, setConfirming] = useState(false);
|
const [confirming, setConfirming] = useState(false);
|
||||||
const [applicationHash, setApplicationHash] = useState<string>('');
|
const [applicationHash, setApplicationHash] = useState<string>('');
|
||||||
|
const [checkingStatus, setCheckingStatus] = useState(false);
|
||||||
|
|
||||||
const maritalStatus = watch('maritalStatus');
|
const maritalStatus = watch('maritalStatus');
|
||||||
const childrenCount = watch('childrenCount');
|
const childrenCount = watch('childrenCount');
|
||||||
|
|
||||||
const handleApprove = async () => {
|
const handleApprove = async () => {
|
||||||
if (!api || !selectedAccount) {
|
// identityKyc pallet is on People Chain
|
||||||
setError('Please connect your wallet first');
|
if (!peopleApi || !isPeopleReady || !selectedAccount) {
|
||||||
|
setError('Please connect your wallet and wait for People Chain connection');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,15 +51,15 @@ export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ on
|
|||||||
const { web3FromAddress } = await import('@pezkuwi/extension-dapp');
|
const { web3FromAddress } = await import('@pezkuwi/extension-dapp');
|
||||||
const injector = await web3FromAddress(selectedAccount.address);
|
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
|
// Call confirm_citizenship() extrinsic on People Chain - self-confirmation for Welati Tiki
|
||||||
const tx = api.tx.identityKyc.confirmCitizenship();
|
const tx = peopleApi.tx.identityKyc.confirmCitizenship();
|
||||||
|
|
||||||
await tx.signAndSend(selectedAccount.address, { signer: injector.signer }, ({ status, events, dispatchError }) => {
|
await tx.signAndSend(selectedAccount.address, { signer: injector.signer }, ({ status, events, dispatchError }) => {
|
||||||
if (dispatchError) {
|
if (dispatchError) {
|
||||||
if (dispatchError.isModule) {
|
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(' ')}`);
|
if (import.meta.env.DEV) console.error(`${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`);
|
||||||
setError(`${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`);
|
setError(`${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`);
|
||||||
} else {
|
} else {
|
||||||
@@ -68,7 +71,7 @@ export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ on
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status.isInBlock || status.isFinalized) {
|
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);
|
if (import.meta.env.DEV) console.log('Block hash:', status.asInBlock || status.asFinalized);
|
||||||
|
|
||||||
// Check for CitizenshipConfirmed event
|
// Check for CitizenshipConfirmed event
|
||||||
@@ -105,17 +108,17 @@ export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ on
|
|||||||
window.location.href = '/';
|
window.location.href = '/';
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check KYC status on mount
|
// Check KYC status on mount (identityKyc pallet is on People Chain)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkKycStatus = async () => {
|
const checkKycStatus = async () => {
|
||||||
if (!api || !isApiReady || !selectedAccount) {
|
if (!peopleApi || !isPeopleReady || !selectedAccount) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setCheckingStatus(true);
|
setCheckingStatus(true);
|
||||||
try {
|
try {
|
||||||
const status = await getKycStatus(api, selectedAccount.address);
|
const status = await getKycStatus(peopleApi, selectedAccount.address);
|
||||||
if (import.meta.env.DEV) console.log('Current KYC Status:', status);
|
if (import.meta.env.DEV) console.log('Current KYC Status from People Chain:', status);
|
||||||
|
|
||||||
if (status === 'Approved') {
|
if (status === 'Approved') {
|
||||||
if (import.meta.env.DEV) console.log('KYC already approved! Redirecting to dashboard...');
|
if (import.meta.env.DEV) console.log('KYC already approved! Redirecting to dashboard...');
|
||||||
@@ -138,21 +141,21 @@ export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ on
|
|||||||
};
|
};
|
||||||
|
|
||||||
checkKycStatus();
|
checkKycStatus();
|
||||||
}, [api, isApiReady, selectedAccount, onClose]);
|
}, [peopleApi, isPeopleReady, selectedAccount, onClose]);
|
||||||
|
|
||||||
// Subscribe to KYC approval events
|
// Subscribe to KYC approval events on People Chain
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!api || !isApiReady || !selectedAccount || !waitingForApproval) {
|
if (!peopleApi || !isPeopleReady || !selectedAccount || !waitingForApproval) {
|
||||||
return;
|
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(
|
const unsubscribe = subscribeToKycApproval(
|
||||||
api,
|
peopleApi,
|
||||||
selectedAccount.address,
|
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);
|
setKycApproved(true);
|
||||||
setWaitingForApproval(false);
|
setWaitingForApproval(false);
|
||||||
|
|
||||||
@@ -173,11 +176,12 @@ export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ on
|
|||||||
unsubscribe();
|
unsubscribe();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [api, isApiReady, selectedAccount, waitingForApproval, onClose]);
|
}, [peopleApi, isPeopleReady, selectedAccount, waitingForApproval, onClose]);
|
||||||
|
|
||||||
const onSubmit = async (data: FormData) => {
|
const onSubmit = async (data: FormData) => {
|
||||||
if (!api || !isApiReady || !selectedAccount) {
|
// identityKyc pallet is on People Chain
|
||||||
setError('Please connect your wallet first');
|
if (!peopleApi || !isPeopleReady || !selectedAccount) {
|
||||||
|
setError('Please connect your wallet and wait for People Chain connection');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,8 +194,8 @@ export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ on
|
|||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Check KYC status before submitting
|
// Check KYC status before submitting (from People Chain)
|
||||||
const currentStatus = await getKycStatus(api, selectedAccount.address);
|
const currentStatus = await getKycStatus(peopleApi, selectedAccount.address);
|
||||||
|
|
||||||
if (currentStatus === 'Approved') {
|
if (currentStatus === 'Approved') {
|
||||||
setError('Your KYC has already been approved! Redirecting to dashboard...');
|
setError('Your KYC has already been approved! Redirecting to dashboard...');
|
||||||
@@ -250,10 +254,10 @@ export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ on
|
|||||||
throw new Error(`Invalid IPFS CID: ${cidString}`);
|
throw new Error(`Invalid IPFS CID: ${cidString}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Submit to blockchain
|
// Submit to blockchain (identityKyc pallet is on People Chain)
|
||||||
if (import.meta.env.DEV) console.log('Submitting KYC application to blockchain...');
|
if (import.meta.env.DEV) console.log('Submitting KYC application to People Chain...');
|
||||||
const result = await submitKycApplication(
|
const result = await submitKycApplication(
|
||||||
api,
|
peopleApi,
|
||||||
selectedAccount,
|
selectedAccount,
|
||||||
citizenshipData.fullName,
|
citizenshipData.fullName,
|
||||||
citizenshipData.email,
|
citizenshipData.email,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const DashboardContext = createContext<DashboardData | undefined>(undefined);
|
|||||||
|
|
||||||
export function DashboardProvider({ children }: { children: ReactNode }) {
|
export function DashboardProvider({ children }: { children: ReactNode }) {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const { api, isApiReady, selectedAccount } = usePezkuwi();
|
const { peopleApi, isPeopleReady, selectedAccount } = usePezkuwi();
|
||||||
const [profile, setProfile] = useState<Record<string, unknown> | null>(null);
|
const [profile, setProfile] = useState<Record<string, unknown> | null>(null);
|
||||||
const [nftDetails, setNftDetails] = useState<{ citizenNFT: TikiNFTDetails | null; roleNFTs: TikiNFTDetails[]; totalNFTs: number }>({
|
const [nftDetails, setNftDetails] = useState<{ citizenNFT: TikiNFTDetails | null; roleNFTs: TikiNFTDetails[]; totalNFTs: number }>({
|
||||||
citizenNFT: null,
|
citizenNFT: null,
|
||||||
@@ -54,29 +54,29 @@ export function DashboardProvider({ children }: { children: ReactNode }) {
|
|||||||
}, [user]);
|
}, [user]);
|
||||||
|
|
||||||
const fetchScoresAndTikis = useCallback(async () => {
|
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);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const status = await getKycStatus(api, selectedAccount.address);
|
const status = await getKycStatus(peopleApi, selectedAccount.address);
|
||||||
setKycStatus(status);
|
setKycStatus(status);
|
||||||
|
|
||||||
const details = await getAllTikiNFTDetails(api, selectedAccount.address);
|
const details = await getAllTikiNFTDetails(peopleApi, selectedAccount.address);
|
||||||
setNftDetails(details);
|
setNftDetails(details);
|
||||||
} catch (error) {
|
} 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 {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}, [selectedAccount, api]);
|
}, [selectedAccount, peopleApi, isPeopleReady]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchProfile();
|
fetchProfile();
|
||||||
if (selectedAccount && api && isApiReady) {
|
if (selectedAccount && peopleApi && isPeopleReady) {
|
||||||
fetchScoresAndTikis();
|
fetchScoresAndTikis();
|
||||||
|
|
||||||
}
|
}
|
||||||
}, [user, selectedAccount, api, isApiReady, fetchProfile, fetchScoresAndTikis]);
|
}, [user, selectedAccount, peopleApi, isPeopleReady, fetchProfile, fetchScoresAndTikis]);
|
||||||
|
|
||||||
const citizenNumber = nftDetails.citizenNFT
|
const citizenNumber = nftDetails.citizenNFT
|
||||||
? generateCitizenNumber(nftDetails.citizenNFT.owner, nftDetails.citizenNFT.collectionId, nftDetails.citizenNFT.itemId)
|
? generateCitizenNumber(nftDetails.citizenNFT.owner, nftDetails.citizenNFT.collectionId, nftDetails.citizenNFT.itemId)
|
||||||
|
|||||||
Reference in New Issue
Block a user