fix: universal getSigner helper for WalletConnect + extension signing

Replace all web3FromAddress calls with getSigner() that auto-detects
walletSource and uses WC signer or extension signer accordingly.
This fixes all signing operations when connected via WalletConnect.
This commit is contained in:
2026-02-23 07:01:18 +03:00
parent bcee7c2a7d
commit 80d8bbbcb1
21 changed files with 139 additions and 142 deletions
+19 -25
View File
@@ -4,11 +4,13 @@
// Handles citizenship verification, status checks, and workflow logic // Handles citizenship verification, status checks, and workflow logic
import type { ApiPromise } from '@pezkuwi/api'; import type { ApiPromise } from '@pezkuwi/api';
import { web3Enable, web3FromAddress as web3FromAddressOriginal } from '@pezkuwi/extension-dapp'; import { getSigner } from '@/lib/get-signer';
import type { InjectedAccountWithMeta } from '@pezkuwi/extension-inject/types'; import type { InjectedAccountWithMeta } from '@pezkuwi/extension-inject/types';
import type { Signer } from '@pezkuwi/api/types'; import type { Signer } from '@pezkuwi/api/types';
type WalletSource = 'extension' | 'walletconnect' | 'native' | null;
interface SignRawPayload { interface SignRawPayload {
address: string; address: string;
data: string; data: string;
@@ -23,20 +25,6 @@ interface InjectedSigner {
signRaw?: (payload: SignRawPayload) => Promise<SignRawResult>; signRaw?: (payload: SignRawPayload) => Promise<SignRawResult>;
} }
interface InjectedExtension {
signer: Signer & InjectedSigner;
}
// Use real extension in browser, throw error in unsupported environments
const web3FromAddress = async (address: string): Promise<InjectedExtension> => {
// Check if we're in a browser environment with extension support
if (typeof window !== 'undefined') {
await web3Enable('PezkuwiChain');
return web3FromAddressOriginal(address) as Promise<InjectedExtension>;
}
throw new Error('Pezkuwi Wallet extension not available. Please install the extension.');
};
// ======================================== // ========================================
// TYPE DEFINITIONS // TYPE DEFINITIONS
// ======================================== // ========================================
@@ -477,7 +465,8 @@ export async function submitKycApplication(
api: ApiPromise, api: ApiPromise,
account: InjectedAccountWithMeta, account: InjectedAccountWithMeta,
identityHash: string, identityHash: string,
referrerAddress?: string referrerAddress?: string,
walletSource?: WalletSource
): Promise<{ success: boolean; error?: string; blockHash?: string }> { ): Promise<{ success: boolean; error?: string; blockHash?: string }> {
try { try {
if (!api?.tx?.identityKyc?.applyForCitizenship) { if (!api?.tx?.identityKyc?.applyForCitizenship) {
@@ -502,7 +491,7 @@ export async function submitKycApplication(
}; };
} }
const injector = await web3FromAddress(account.address); const injector = await getSigner(account.address, walletSource ?? 'extension', api);
if (import.meta.env.DEV) { if (import.meta.env.DEV) {
console.log('=== submitKycApplication Debug ==='); console.log('=== submitKycApplication Debug ===');
@@ -629,14 +618,15 @@ export function subscribeToKycApproval(
export async function approveReferral( export async function approveReferral(
api: ApiPromise, api: ApiPromise,
account: InjectedAccountWithMeta, account: InjectedAccountWithMeta,
applicantAddress: string applicantAddress: string,
walletSource?: WalletSource
): Promise<{ success: boolean; error?: string; blockHash?: string }> { ): Promise<{ success: boolean; error?: string; blockHash?: string }> {
try { try {
if (!api?.tx?.identityKyc?.approveReferral) { if (!api?.tx?.identityKyc?.approveReferral) {
return { success: false, error: 'Identity KYC pallet not available' }; return { success: false, error: 'Identity KYC pallet not available' };
} }
const injector = await web3FromAddress(account.address); const injector = await getSigner(account.address, walletSource ?? 'extension', api);
const result = await new Promise<{ success: boolean; error?: string; blockHash?: string }>((resolve, reject) => { const result = await new Promise<{ success: boolean; error?: string; blockHash?: string }>((resolve, reject) => {
api.tx.identityKyc api.tx.identityKyc
@@ -679,14 +669,15 @@ export async function approveReferral(
*/ */
export async function cancelApplication( export async function cancelApplication(
api: ApiPromise, api: ApiPromise,
account: InjectedAccountWithMeta account: InjectedAccountWithMeta,
walletSource?: WalletSource
): Promise<{ success: boolean; error?: string }> { ): Promise<{ success: boolean; error?: string }> {
try { try {
if (!api?.tx?.identityKyc?.cancelApplication) { if (!api?.tx?.identityKyc?.cancelApplication) {
return { success: false, error: 'Identity KYC pallet not available' }; return { success: false, error: 'Identity KYC pallet not available' };
} }
const injector = await web3FromAddress(account.address); const injector = await getSigner(account.address, walletSource ?? 'extension', api);
const result = await new Promise<{ success: boolean; error?: string }>((resolve, reject) => { const result = await new Promise<{ success: boolean; error?: string }>((resolve, reject) => {
api.tx.identityKyc api.tx.identityKyc
@@ -723,14 +714,15 @@ export async function cancelApplication(
*/ */
export async function confirmCitizenship( export async function confirmCitizenship(
api: ApiPromise, api: ApiPromise,
account: InjectedAccountWithMeta account: InjectedAccountWithMeta,
walletSource?: WalletSource
): Promise<{ success: boolean; error?: string; blockHash?: string }> { ): Promise<{ success: boolean; error?: string; blockHash?: string }> {
try { try {
if (!api?.tx?.identityKyc?.confirmCitizenship) { if (!api?.tx?.identityKyc?.confirmCitizenship) {
return { success: false, error: 'Identity KYC pallet not available' }; return { success: false, error: 'Identity KYC pallet not available' };
} }
const injector = await web3FromAddress(account.address); const injector = await getSigner(account.address, walletSource ?? 'extension', api);
const result = await new Promise<{ success: boolean; error?: string; blockHash?: string }>((resolve, reject) => { const result = await new Promise<{ success: boolean; error?: string; blockHash?: string }>((resolve, reject) => {
api.tx.identityKyc api.tx.identityKyc
@@ -850,10 +842,12 @@ export function generateAuthChallenge(tikiNumber: string): AuthChallenge {
*/ */
export async function signChallenge( export async function signChallenge(
account: InjectedAccountWithMeta, account: InjectedAccountWithMeta,
challenge: AuthChallenge challenge: AuthChallenge,
walletSource?: WalletSource,
api?: ApiPromise | null
): Promise<string> { ): Promise<string> {
try { try {
const injector = await web3FromAddress(account.address); const injector = await getSigner(account.address, walletSource ?? 'extension', api);
if (!injector?.signer?.signRaw) { if (!injector?.signer?.signRaw) {
throw new Error('Signer not available'); throw new Error('Signer not available');
+4 -5
View File
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { X, Plus, Info, AlertCircle } from 'lucide-react'; import { X, Plus, Info, AlertCircle } from 'lucide-react';
import { web3Enable, web3FromAddress } from '@pezkuwi/extension-dapp'; import { getSigner } from '@/lib/get-signer';
import { usePezkuwi } from '@/contexts/PezkuwiContext'; import { usePezkuwi } from '@/contexts/PezkuwiContext';
import { useWallet } from '@/contexts/WalletContext'; import { useWallet } from '@/contexts/WalletContext';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
@@ -62,7 +62,7 @@ export const AddLiquidityModal: React.FC<AddLiquidityModalProps> = ({
asset1 = 1 // Default to PEZ asset1 = 1 // Default to PEZ
}) => { }) => {
// Use Asset Hub API for DEX operations (assetConversion pallet is on Asset Hub) // Use Asset Hub API for DEX operations (assetConversion pallet is on Asset Hub)
const { assetHubApi, selectedAccount, isAssetHubReady } = usePezkuwi(); const { assetHubApi, selectedAccount, isAssetHubReady, walletSource } = usePezkuwi();
const { balances, refreshBalances } = useWallet(); const { balances, refreshBalances } = useWallet();
const [amount0, setAmount0] = useState(''); const [amount0, setAmount0] = useState('');
@@ -357,9 +357,8 @@ export const AddLiquidityModal: React.FC<AddLiquidityModalProps> = ({
return; return;
} }
// Get the signer from the extension // Get the signer (extension or WalletConnect)
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, assetHubApi);
const injector = await web3FromAddress(selectedAccount.address);
// Convert amounts to proper decimals // Convert amounts to proper decimals
const amount0BN = BigInt(Math.floor(parseFloat(amount0) * Math.pow(10, asset0Decimals))); const amount0BN = BigInt(Math.floor(parseFloat(amount0) * Math.pow(10, asset0Decimals)));
+3 -4
View File
@@ -1,7 +1,7 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { X, Lock, AlertCircle, Loader2, Clock } from 'lucide-react'; import { X, Lock, AlertCircle, Loader2, Clock } from 'lucide-react';
import { web3Enable, web3FromAddress } from '@pezkuwi/extension-dapp'; import { getSigner } from '@/lib/get-signer';
import { usePezkuwi } from '@/contexts/PezkuwiContext'; import { usePezkuwi } from '@/contexts/PezkuwiContext';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Alert, AlertDescription } from '@/components/ui/alert'; import { Alert, AlertDescription } from '@/components/ui/alert';
@@ -50,7 +50,7 @@ export const LPStakeModal: React.FC<LPStakeModalProps> = ({
onStakeSuccess, onStakeSuccess,
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { assetHubApi, selectedAccount, isAssetHubReady } = usePezkuwi(); const { assetHubApi, selectedAccount, isAssetHubReady, walletSource } = usePezkuwi();
const [isProcessing, setIsProcessing] = useState(false); const [isProcessing, setIsProcessing] = useState(false);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const [success, setSuccess] = useState<string | null>(null); const [success, setSuccess] = useState<string | null>(null);
@@ -85,8 +85,7 @@ export const LPStakeModal: React.FC<LPStakeModalProps> = ({
try { try {
const amountBN = BigInt(Math.floor(amount * 1e12)); const amountBN = BigInt(Math.floor(amount * 1e12));
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, assetHubApi);
const injector = await web3FromAddress(selectedAccount.address);
const tx = assetHubApi.tx.assetRewards.stake(poolId, amountBN.toString()); const tx = assetHubApi.tx.assetRewards.stake(poolId, amountBN.toString());
+5 -8
View File
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { X, Lock, Unlock, Gift, AlertCircle, Loader2, Info } from 'lucide-react'; import { X, Lock, Unlock, Gift, AlertCircle, Loader2, Info } from 'lucide-react';
import { web3Enable, web3FromAddress } from '@pezkuwi/extension-dapp'; import { getSigner } from '@/lib/get-signer';
import { usePezkuwi } from '@/contexts/PezkuwiContext'; import { usePezkuwi } from '@/contexts/PezkuwiContext';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Alert, AlertDescription } from '@/components/ui/alert'; import { Alert, AlertDescription } from '@/components/ui/alert';
@@ -31,7 +31,7 @@ const LP_TOKEN_NAMES: Record<number, string> = {
}; };
export const LPStakingModal: React.FC<LPStakingModalProps> = ({ isOpen, onClose }) => { export const LPStakingModal: React.FC<LPStakingModalProps> = ({ isOpen, onClose }) => {
const { assetHubApi, selectedAccount, isAssetHubReady } = usePezkuwi(); const { assetHubApi, selectedAccount, isAssetHubReady, walletSource } = usePezkuwi();
const { t } = useTranslation(); const { t } = useTranslation();
const [pools, setPools] = useState<StakingPool[]>([]); const [pools, setPools] = useState<StakingPool[]>([]);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
@@ -143,8 +143,7 @@ export const LPStakingModal: React.FC<LPStakingModalProps> = ({ isOpen, onClose
if (!pool) throw new Error('Pool not found'); if (!pool) throw new Error('Pool not found');
const amountBN = BigInt(Math.floor(parseFloat(stakeAmount) * 1e12)); const amountBN = BigInt(Math.floor(parseFloat(stakeAmount) * 1e12));
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, assetHubApi);
const injector = await web3FromAddress(selectedAccount.address);
const tx = assetHubApi.tx.assetRewards.stake(selectedPool, amountBN.toString()); const tx = assetHubApi.tx.assetRewards.stake(selectedPool, amountBN.toString());
@@ -190,8 +189,7 @@ export const LPStakingModal: React.FC<LPStakingModalProps> = ({ isOpen, onClose
if (!pool) throw new Error('Pool not found'); if (!pool) throw new Error('Pool not found');
const amountBN = BigInt(Math.floor(parseFloat(unstakeAmount) * 1e12)); const amountBN = BigInt(Math.floor(parseFloat(unstakeAmount) * 1e12));
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, assetHubApi);
const injector = await web3FromAddress(selectedAccount.address);
const tx = assetHubApi.tx.assetRewards.unstake(selectedPool, amountBN.toString()); const tx = assetHubApi.tx.assetRewards.unstake(selectedPool, amountBN.toString());
@@ -233,8 +231,7 @@ export const LPStakingModal: React.FC<LPStakingModalProps> = ({ isOpen, onClose
setSuccess(null); setSuccess(null);
try { try {
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, assetHubApi);
const injector = await web3FromAddress(selectedAccount.address);
const tx = assetHubApi.tx.assetRewards.harvestRewards(selectedPool); const tx = assetHubApi.tx.assetRewards.harvestRewards(selectedPool);
await new Promise<void>((resolve, reject) => { await new Promise<void>((resolve, reject) => {
+4 -5
View File
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { X, Minus, AlertCircle, Info } from 'lucide-react'; import { X, Minus, AlertCircle, Info } from 'lucide-react';
import { web3Enable, web3FromAddress } from '@pezkuwi/extension-dapp'; import { getSigner } from '@/lib/get-signer';
import { usePezkuwi } from '@/contexts/PezkuwiContext'; import { usePezkuwi } from '@/contexts/PezkuwiContext';
import { useWallet } from '@/contexts/WalletContext'; import { useWallet } from '@/contexts/WalletContext';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
@@ -63,7 +63,7 @@ export const RemoveLiquidityModal: React.FC<RemoveLiquidityModalProps> = ({
asset1, asset1,
}) => { }) => {
// Use Asset Hub API for DEX operations (assetConversion pallet is on Asset Hub) // Use Asset Hub API for DEX operations (assetConversion pallet is on Asset Hub)
const { assetHubApi, selectedAccount } = usePezkuwi(); const { assetHubApi, selectedAccount, walletSource } = usePezkuwi();
const { refreshBalances } = useWallet(); const { refreshBalances } = useWallet();
const [percentage, setPercentage] = useState(100); const [percentage, setPercentage] = useState(100);
@@ -159,9 +159,8 @@ export const RemoveLiquidityModal: React.FC<RemoveLiquidityModalProps> = ({
setError(null); setError(null);
try { try {
// Get the signer from the extension // Get the signer (extension or WalletConnect)
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, assetHubApi);
const injector = await web3FromAddress(selectedAccount.address);
// Get decimals for each asset // Get decimals for each asset
const asset0Decimals = getAssetDecimals(asset0); const asset0Decimals = getAssetDecimals(asset0);
+4 -5
View File
@@ -25,7 +25,7 @@ const AVAILABLE_TOKENS = [
const TokenSwap = () => { const TokenSwap = () => {
// Use Asset Hub API for DEX operations (assetConversion pallet is on Asset Hub) // Use Asset Hub API for DEX operations (assetConversion pallet is on Asset Hub)
const { assetHubApi, isAssetHubReady, selectedAccount } = usePezkuwi(); const { assetHubApi, isAssetHubReady, selectedAccount, walletSource } = usePezkuwi();
const { balances, refreshBalances } = useWallet(); const { balances, refreshBalances } = useWallet();
const { toast } = useToast(); const { toast } = useToast();
const { t } = useTranslation(); const { t } = useTranslation();
@@ -583,10 +583,9 @@ const TokenSwap = () => {
minAmountOut: minAmountOut.toString() minAmountOut: minAmountOut.toString()
}); });
// Get signer from extension // Get signer (extension or WalletConnect)
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const { getSigner } = await import('@/lib/get-signer');
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, assetHubApi);
const injector = await web3FromAddress(selectedAccount.address);
// Build transaction based on token types // Build transaction based on token types
let tx; let tx;
+4 -5
View File
@@ -67,7 +67,7 @@ const TOKENS: Token[] = [
]; ];
export const TransferModal: React.FC<TransferModalProps> = ({ isOpen, onClose, selectedAsset }) => { export const TransferModal: React.FC<TransferModalProps> = ({ isOpen, onClose, selectedAsset }) => {
const { api, assetHubApi, isApiReady, isAssetHubReady, selectedAccount } = usePezkuwi(); const { api, assetHubApi, isApiReady, isAssetHubReady, selectedAccount, walletSource } = usePezkuwi();
const { toast } = useToast(); const { toast } = useToast();
const { t } = useTranslation(); const { t } = useTranslation();
@@ -129,10 +129,9 @@ export const TransferModal: React.FC<TransferModalProps> = ({ isOpen, onClose, s
setTxStatus('signing'); setTxStatus('signing');
try { try {
// Import web3FromAddress to get the injector // Get signer (extension or WalletConnect)
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const { getSigner } = await import('@/lib/get-signer');
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, isAssetHubTransfer ? assetHubApi : api);
const injector = await web3FromAddress(selectedAccount.address);
// Convert amount to smallest unit // Convert amount to smallest unit
const amountInSmallestUnit = BigInt(parseFloat(amount) * Math.pow(10, currentToken.decimals)); const amountInSmallestUnit = BigInt(parseFloat(amount) * Math.pow(10, currentToken.decimals));
+3 -4
View File
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { X, ArrowDown, ArrowUp, AlertCircle, Info, Clock, CheckCircle2 } from 'lucide-react'; import { X, ArrowDown, ArrowUp, AlertCircle, Info, Clock, CheckCircle2 } from 'lucide-react';
import { web3Enable, web3FromAddress } from '@pezkuwi/extension-dapp'; import { getSigner } from '@/lib/get-signer';
import { usePezkuwi } from '@/contexts/PezkuwiContext'; import { usePezkuwi } from '@/contexts/PezkuwiContext';
import { useWallet } from '@/contexts/WalletContext'; import { useWallet } from '@/contexts/WalletContext';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
@@ -30,7 +30,7 @@ export const USDTBridge: React.FC<USDTBridgeProps> = ({
specificAddresses = {}, specificAddresses = {},
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { api, selectedAccount, isApiReady } = usePezkuwi(); const { api, selectedAccount, isApiReady, walletSource } = usePezkuwi();
const { refreshBalances } = useWallet(); const { refreshBalances } = useWallet();
const [depositAmount, setDepositAmount] = useState(''); const [depositAmount, setDepositAmount] = useState('');
@@ -114,8 +114,7 @@ export const USDTBridge: React.FC<USDTBridgeProps> = ({
setSuccess(null); setSuccess(null);
try { try {
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, api);
const injector = await web3FromAddress(selectedAccount.address);
// Burn wUSDT // Burn wUSDT
const amountBN = BigInt(Math.floor(amount * 1e6)); // 6 decimals const amountBN = BigInt(Math.floor(amount * 1e6)); // 6 decimals
+3 -4
View File
@@ -54,7 +54,7 @@ interface XCMTeleportModalProps {
} }
export const XCMTeleportModal: React.FC<XCMTeleportModalProps> = ({ isOpen, onClose }) => { export const XCMTeleportModal: React.FC<XCMTeleportModalProps> = ({ isOpen, onClose }) => {
const { api, assetHubApi, peopleApi, isApiReady, isAssetHubReady, isPeopleReady, selectedAccount } = usePezkuwi(); const { api, assetHubApi, peopleApi, isApiReady, isAssetHubReady, isPeopleReady, selectedAccount, walletSource } = usePezkuwi();
const { toast } = useToast(); const { toast } = useToast();
const { t } = useTranslation(); const { t } = useTranslation();
@@ -157,9 +157,8 @@ export const XCMTeleportModal: React.FC<XCMTeleportModalProps> = ({ isOpen, onCl
setTxStatus('signing'); setTxStatus('signing');
try { try {
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const { getSigner } = await import('@/lib/get-signer');
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, api);
const injector = await web3FromAddress(selectedAccount.address);
// Convert to smallest unit (12 decimals) // Convert to smallest unit (12 decimals)
const amountInSmallestUnit = BigInt(Math.floor(parseFloat(amount) * 1e12)); const amountInSmallestUnit = BigInt(Math.floor(parseFloat(amount) * 1e12));
@@ -11,7 +11,7 @@ import { Alert, AlertDescription } from '@/components/ui/alert';
export function CommissionSetupTab() { export function CommissionSetupTab() {
const { t } = useTranslation(); const { t } = useTranslation();
const { api, isApiReady, selectedAccount } = usePezkuwi(); const { api, isApiReady, selectedAccount, walletSource } = usePezkuwi();
const { toast } = useToast(); const { toast } = useToast();
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
@@ -70,9 +70,8 @@ export function CommissionSetupTab() {
setProcessing(true); setProcessing(true);
try { try {
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const { getSigner } = await import('@/lib/get-signer');
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, api);
const injector = await web3FromAddress(selectedAccount.address);
// Parse addresses (one per line, trim whitespace) // Parse addresses (one per line, trim whitespace)
const newAddresses = newMemberAddress const newAddresses = newMemberAddress
@@ -175,9 +174,8 @@ export function CommissionSetupTab() {
setProcessing(true); setProcessing(true);
try { try {
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const { getSigner } = await import('@/lib/get-signer');
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, api);
const injector = await web3FromAddress(selectedAccount.address);
if (import.meta.env.DEV) console.log('Initializing KYC Commission...'); if (import.meta.env.DEV) console.log('Initializing KYC Commission...');
if (import.meta.env.DEV) console.log('Proxy account:', COMMISSIONS.KYC.proxyAccount); if (import.meta.env.DEV) console.log('Proxy account:', COMMISSIONS.KYC.proxyAccount);
@@ -28,7 +28,7 @@ interface Proposal {
export function CommissionVotingTab() { export function CommissionVotingTab() {
const { t } = useTranslation(); const { t } = useTranslation();
const { api, isApiReady, selectedAccount } = usePezkuwi(); const { api, isApiReady, selectedAccount, walletSource } = usePezkuwi();
const { toast } = useToast(); const { toast } = useToast();
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
@@ -150,9 +150,8 @@ export function CommissionVotingTab() {
setVoting(proposal.hash); setVoting(proposal.hash);
try { try {
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const { getSigner } = await import('@/lib/get-signer');
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, api);
const injector = await web3FromAddress(selectedAccount.address);
if (import.meta.env.DEV) console.log(`Voting ${approve ? 'AYE' : 'NAY'} on proposal:`, proposal.hash); if (import.meta.env.DEV) console.log(`Voting ${approve ? 'AYE' : 'NAY'} on proposal:`, proposal.hash);
@@ -258,9 +257,8 @@ export function CommissionVotingTab() {
setVoting(proposal.hash); setVoting(proposal.hash);
try { try {
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const { getSigner } = await import('@/lib/get-signer');
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, api);
const injector = await web3FromAddress(selectedAccount.address);
if (import.meta.env.DEV) console.log('Executing proposal:', proposal.hash); if (import.meta.env.DEV) console.log('Executing proposal:', proposal.hash);
@@ -433,9 +431,8 @@ export function CommissionVotingTab() {
if (!api || !selectedAccount) return; if (!api || !selectedAccount) return;
try { try {
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const { getSigner } = await import('@/lib/get-signer');
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, api);
const injector = await web3FromAddress(selectedAccount.address);
// Get current members // Get current members
const currentMembers = await api.query.dynamicCommissionCollective.members(); const currentMembers = await api.query.dynamicCommissionCollective.members();
+2 -2
View File
@@ -21,7 +21,7 @@ import type { PendingApproval } from '@pezkuwi/lib/citizenship-workflow';
export function KycApprovalTab() { export function KycApprovalTab() {
const { t } = useTranslation(); const { t } = useTranslation();
// identityKyc pallet is on People Chain - use peopleApi // identityKyc pallet is on People Chain - use peopleApi
const { peopleApi, isPeopleReady, selectedAccount, connectWallet } = usePezkuwi(); const { peopleApi, isPeopleReady, selectedAccount, connectWallet, walletSource } = usePezkuwi();
const { toast } = useToast(); const { toast } = useToast();
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
@@ -75,7 +75,7 @@ export function KycApprovalTab() {
setProcessingAddress(applicantAddress); setProcessingAddress(applicantAddress);
try { try {
const result = await approveReferral(peopleApi, selectedAccount, applicantAddress); const result = await approveReferral(peopleApi, selectedAccount, applicantAddress, walletSource);
if (!result.success) { if (!result.success) {
toast({ toast({
@@ -17,7 +17,7 @@ interface ExistingCitizenAuthProps {
export const ExistingCitizenAuth: React.FC<ExistingCitizenAuthProps> = ({ onClose }) => { export const ExistingCitizenAuth: React.FC<ExistingCitizenAuthProps> = ({ onClose }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { peopleApi, isPeopleReady, selectedAccount, connectWallet } = usePezkuwi(); const { peopleApi, isPeopleReady, selectedAccount, connectWallet, walletSource } = usePezkuwi();
const [citizenNumber, setCitizenNumber] = useState(''); const [citizenNumber, setCitizenNumber] = useState('');
const [step, setStep] = useState<'input' | 'verifying' | 'signing' | 'success' | 'error'>('input'); const [step, setStep] = useState<'input' | 'verifying' | 'signing' | 'success' | 'error'>('input');
@@ -69,7 +69,7 @@ export const ExistingCitizenAuth: React.FC<ExistingCitizenAuthProps> = ({ onClos
try { try {
// Sign the challenge // Sign the challenge
const signature = await signChallenge(selectedAccount, challenge); const signature = await signChallenge(selectedAccount, challenge, walletSource, peopleApi);
// Verify signature (self-verification for demonstration) // Verify signature (self-verification for demonstration)
const isValid = await verifySignature(signature, challenge, selectedAccount.address); const isValid = await verifySignature(signature, challenge, selectedAccount.address);
@@ -25,7 +25,7 @@ type FormData = Omit<CitizenshipData, 'walletAddress' | 'timestamp'>;
export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ onClose, referrerAddress }) => { export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ onClose, referrerAddress }) => {
// identityKyc pallet is on People Chain // identityKyc pallet is on People Chain
const { peopleApi, isPeopleReady, selectedAccount, connectWallet } = usePezkuwi(); const { peopleApi, isPeopleReady, selectedAccount, connectWallet, walletSource } = usePezkuwi();
const { t } = useTranslation(); const { t } = useTranslation();
const { register, handleSubmit, watch, setValue, formState: { errors } } = useForm<FormData>(); const { register, handleSubmit, watch, setValue, formState: { errors } } = useForm<FormData>();
@@ -51,7 +51,7 @@ export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ on
setConfirming(true); setConfirming(true);
setError(null); setError(null);
try { try {
const result = await confirmCitizenship(peopleApi, selectedAccount); const result = await confirmCitizenship(peopleApi, selectedAccount, walletSource);
if (!result.success) { if (!result.success) {
setError(result.error || t('newCitizen.failedToConfirm')); setError(result.error || t('newCitizen.failedToConfirm'));
@@ -83,7 +83,7 @@ export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ on
setCanceling(true); setCanceling(true);
setError(null); setError(null);
try { try {
const result = await cancelApplication(peopleApi, selectedAccount); const result = await cancelApplication(peopleApi, selectedAccount, walletSource);
if (!result.success) { if (!result.success) {
setError(result.error || t('newCitizen.failedToCancel')); setError(result.error || t('newCitizen.failedToCancel'));
@@ -243,7 +243,8 @@ export const NewCitizenApplication: React.FC<NewCitizenApplicationProps> = ({ on
peopleApi, peopleApi,
selectedAccount, selectedAccount,
identityHash, identityHash,
effectiveReferrer effectiveReferrer,
walletSource
); );
if (!result.success) { if (!result.success) {
@@ -19,7 +19,7 @@ interface Proposal {
export function CommissionProposalsCard() { export function CommissionProposalsCard() {
const { t } = useTranslation(); const { t } = useTranslation();
const { api, isApiReady, selectedAccount } = usePezkuwi(); const { api, isApiReady, selectedAccount, walletSource } = usePezkuwi();
const { toast } = useToast(); const { toast } = useToast();
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
@@ -109,9 +109,8 @@ export function CommissionProposalsCard() {
setVoting(proposal.hash); setVoting(proposal.hash);
try { try {
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const { getSigner } = await import('@/lib/get-signer');
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, api);
const injector = await web3FromAddress(selectedAccount.address);
const tx = api.tx.dynamicCommissionCollective.vote( const tx = api.tx.dynamicCommissionCollective.vote(
proposal.hash, proposal.hash,
@@ -200,9 +199,8 @@ export function CommissionProposalsCard() {
setVoting(proposal.hash); setVoting(proposal.hash);
try { try {
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const { getSigner } = await import('@/lib/get-signer');
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, api);
const injector = await web3FromAddress(selectedAccount.address);
// Get proposal length bound // Get proposal length bound
const proposalOption = await api.query.dynamicCommissionCollective.proposalOf(proposal.hash); const proposalOption = await api.query.dynamicCommissionCollective.proposalOf(proposal.hash);
@@ -23,7 +23,7 @@ interface InviteUserModalProps {
export const InviteUserModal: React.FC<InviteUserModalProps> = ({ isOpen, onClose }) => { export const InviteUserModal: React.FC<InviteUserModalProps> = ({ isOpen, onClose }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { peopleApi, isPeopleReady, selectedAccount } = usePezkuwi(); const { peopleApi, isPeopleReady, selectedAccount, walletSource } = usePezkuwi();
const [copied, setCopied] = useState(false); const [copied, setCopied] = useState(false);
const [inviteeAddress, setInviteeAddress] = useState(''); const [inviteeAddress, setInviteeAddress] = useState('');
const [initiating, setInitiating] = useState(false); const [initiating, setInitiating] = useState(false);
@@ -81,9 +81,8 @@ export const InviteUserModal: React.FC<InviteUserModalProps> = ({ isOpen, onClos
setInitiateSuccess(false); setInitiateSuccess(false);
try { try {
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const { getSigner } = await import('@/lib/get-signer');
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, peopleApi);
const injector = await web3FromAddress(selectedAccount.address);
if (import.meta.env.DEV) console.log(`Initiating referral from ${selectedAccount.address} to ${inviteeAddress}...`); if (import.meta.env.DEV) console.log(`Initiating referral from ${selectedAccount.address} to ${inviteeAddress}...`);
@@ -14,7 +14,7 @@ import type { PendingApproval } from '@pezkuwi/lib/citizenship-workflow';
export const ReferralDashboard: React.FC = () => { export const ReferralDashboard: React.FC = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { stats, myReferrals, loading } = useReferral(); const { stats, myReferrals, loading } = useReferral();
const { peopleApi, isPeopleReady, selectedAccount } = usePezkuwi(); const { peopleApi, isPeopleReady, selectedAccount, walletSource } = usePezkuwi();
const { toast } = useToast(); const { toast } = useToast();
const [showInviteModal, setShowInviteModal] = useState(false); const [showInviteModal, setShowInviteModal] = useState(false);
const [pendingApprovals, setPendingApprovals] = useState<PendingApproval[]>([]); const [pendingApprovals, setPendingApprovals] = useState<PendingApproval[]>([]);
@@ -45,7 +45,7 @@ export const ReferralDashboard: React.FC = () => {
setProcessingAddress(applicantAddress); setProcessingAddress(applicantAddress);
try { try {
const result = await approveReferral(peopleApi, selectedAccount, applicantAddress); const result = await approveReferral(peopleApi, selectedAccount, applicantAddress, walletSource);
if (result.success) { if (result.success) {
toast({ toast({
title: 'Referral Approved', title: 'Referral Approved',
@@ -11,7 +11,7 @@ import { usePezkuwi } from '@/contexts/PezkuwiContext';
import { useWallet } from '@/contexts/WalletContext'; import { useWallet } from '@/contexts/WalletContext';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { web3FromAddress, web3Enable } from '@pezkuwi/extension-dapp'; import { getSigner } from '@/lib/get-signer';
import { import {
getStakingInfo, getStakingInfo,
getActiveValidators, getActiveValidators,
@@ -31,21 +31,8 @@ import { LoadingState } from '@pezkuwi/components/AsyncComponent';
import { ValidatorPoolDashboard } from './ValidatorPoolDashboard'; import { ValidatorPoolDashboard } from './ValidatorPoolDashboard';
import { handleBlockchainError, handleBlockchainSuccess } from '@pezkuwi/lib/error-handler'; import { handleBlockchainError, handleBlockchainSuccess } from '@pezkuwi/lib/error-handler';
// Get signer with auto-reconnect if extension session expired
async function getInjectorSigner(address: string) {
let injector = await web3FromAddress(address);
if (!injector?.signer) {
await web3Enable('PezkuwiChain');
injector = await web3FromAddress(address);
if (!injector?.signer) {
throw new Error('Wallet signer not available. Please reconnect your wallet.');
}
}
return injector;
}
export const StakingDashboard: React.FC = () => { export const StakingDashboard: React.FC = () => {
const { assetHubApi, peopleApi, selectedAccount, isAssetHubReady, isPeopleReady } = usePezkuwi(); const { assetHubApi, peopleApi, selectedAccount, isAssetHubReady, isPeopleReady, walletSource } = usePezkuwi();
const { balances, refreshBalances } = useWallet(); const { balances, refreshBalances } = useWallet();
const { t } = useTranslation(); const { t } = useTranslation();
@@ -129,7 +116,7 @@ export const StakingDashboard: React.FC = () => {
setIsRecordingScore(true); setIsRecordingScore(true);
try { try {
const injector = await getInjectorSigner(selectedAccount.address); const injector = await getSigner(selectedAccount.address, walletSource, peopleApi);
const result = await recordTrustScore(peopleApi, selectedAccount.address, injector.signer); const result = await recordTrustScore(peopleApi, selectedAccount.address, injector.signer);
if (result.success) { if (result.success) {
@@ -157,7 +144,7 @@ export const StakingDashboard: React.FC = () => {
setIsClaimingReward(true); setIsClaimingReward(true);
try { try {
const injector = await getInjectorSigner(selectedAccount.address); const injector = await getSigner(selectedAccount.address, walletSource, peopleApi);
const result = await claimPezReward(peopleApi, selectedAccount.address, epochIndex, injector.signer); const result = await claimPezReward(peopleApi, selectedAccount.address, epochIndex, injector.signer);
if (result.success) { if (result.success) {
@@ -198,7 +185,7 @@ export const StakingDashboard: React.FC = () => {
throw new Error(t('staking.insufficientHez')); throw new Error(t('staking.insufficientHez'));
} }
const injector = await getInjectorSigner(selectedAccount.address); const injector = await getSigner(selectedAccount.address, walletSource, assetHubApi);
// If already bonded, use bondExtra, otherwise use bond // If already bonded, use bondExtra, otherwise use bond
let tx; let tx;
@@ -251,7 +238,7 @@ export const StakingDashboard: React.FC = () => {
setIsLoading(true); setIsLoading(true);
try { try {
const injector = await getInjectorSigner(selectedAccount.address); const injector = await getSigner(selectedAccount.address, walletSource, assetHubApi);
const tx = assetHubApi.tx.staking.nominate(selectedValidators); const tx = assetHubApi.tx.staking.nominate(selectedValidators);
@@ -294,7 +281,7 @@ export const StakingDashboard: React.FC = () => {
throw new Error(t('staking.insufficientStaked')); throw new Error(t('staking.insufficientStaked'));
} }
const injector = await getInjectorSigner(selectedAccount.address); const injector = await getSigner(selectedAccount.address, walletSource, assetHubApi);
const tx = assetHubApi.tx.staking.unbond(amount); const tx = assetHubApi.tx.staking.unbond(amount);
await tx.signAndSend( await tx.signAndSend(
@@ -338,7 +325,7 @@ export const StakingDashboard: React.FC = () => {
setIsLoading(true); setIsLoading(true);
try { try {
const injector = await getInjectorSigner(selectedAccount.address); const injector = await getSigner(selectedAccount.address, walletSource, assetHubApi);
// Number of slashing spans (usually 0) // Number of slashing spans (usually 0)
const tx = assetHubApi.tx.staking.withdrawUnbonded(0); const tx = assetHubApi.tx.staking.withdrawUnbonded(0);
@@ -381,7 +368,7 @@ export const StakingDashboard: React.FC = () => {
setIsLoading(true); setIsLoading(true);
try { try {
const injector = await getInjectorSigner(selectedAccount.address); const injector = await getSigner(selectedAccount.address, walletSource, peopleApi);
// stakingScore pallet is on People Chain - uses cached staking data from Asset Hub // stakingScore pallet is on People Chain - uses cached staking data from Asset Hub
const tx = peopleApi.tx.stakingScore.startScoreTracking(); const tx = peopleApi.tx.stakingScore.startScoreTracking();
+40
View File
@@ -0,0 +1,40 @@
/**
* Universal signer helper - works with both browser extension and WalletConnect
*
* Usage:
* const injector = await getSigner(selectedAccount.address, walletSource, api);
* // injector.signer works for signAndSend, signRaw, etc.
*/
import { web3Enable, web3FromAddress } from '@pezkuwi/extension-dapp';
import { createWCSigner, isWCConnected, validateSession } from '@/lib/walletconnect-service';
import type { ApiPromise } from '@pezkuwi/api';
type WalletSource = 'extension' | 'walletconnect' | 'native' | null;
interface SignerResult {
signer: any; // Compatible with @pezkuwi/api Signer
}
export async function getSigner(
address: string,
walletSource: WalletSource,
api?: ApiPromise | null
): Promise<SignerResult> {
if (walletSource === 'walletconnect') {
if (!isWCConnected() || !validateSession()) {
throw new Error('WalletConnect session expired. Please reconnect your wallet.');
}
if (!api) {
throw new Error('API not ready');
}
const genesisHash = api.genesisHash.toHex();
const wcSigner = createWCSigner(genesisHash, address);
return { signer: wcSigner };
}
// Extension or native: use web3FromAddress
await web3Enable('PezkuwiChain');
const injector = await web3FromAddress(address);
return injector;
}
+6 -11
View File
@@ -12,7 +12,7 @@ import { User, Mail, Phone, Globe, MapPin, Calendar, Shield, AlertCircle, ArrowL
import { useToast } from '@/hooks/use-toast'; import { useToast } from '@/hooks/use-toast';
import { fetchUserTikis, getPrimaryRole, getTikiDisplayName, getTikiColor, getTikiEmoji, getUserRoleCategories, getAllTikiNFTDetails, generateCitizenNumber, type TikiNFTDetails } from '@pezkuwi/lib/tiki'; 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, recordTrustScore, claimPezReward, type UserScores, type StakingScoreStatus, type PezRewardInfo, formatDuration } from '@pezkuwi/lib/scores';
import { web3Enable, web3FromAddress } from '@pezkuwi/extension-dapp'; import { getSigner } from '@/lib/get-signer';
import { getKycStatus } from '@pezkuwi/lib/kyc'; import { getKycStatus } from '@pezkuwi/lib/kyc';
import { ReferralDashboard } from '@/components/referral/ReferralDashboard'; import { ReferralDashboard } from '@/components/referral/ReferralDashboard';
// Commission proposals card removed - no longer using notary system for KYC approval // Commission proposals card removed - no longer using notary system for KYC approval
@@ -21,7 +21,7 @@ import { ReferralDashboard } from '@/components/referral/ReferralDashboard';
export default function Dashboard() { export default function Dashboard() {
const { t } = useTranslation(); const { t } = useTranslation();
const { user } = useAuth(); const { user } = useAuth();
const { api, isApiReady, peopleApi, isPeopleReady, selectedAccount } = usePezkuwi(); const { api, isApiReady, peopleApi, isPeopleReady, selectedAccount, walletSource } = usePezkuwi();
const navigate = useNavigate(); const navigate = useNavigate();
const { toast } = useToast(); const { toast } = useToast();
const [profile, setProfile] = useState<Record<string, unknown> | null>(null); const [profile, setProfile] = useState<Record<string, unknown> | null>(null);
@@ -157,8 +157,7 @@ export default function Dashboard() {
setStartingScoreTracking(true); setStartingScoreTracking(true);
try { try {
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, peopleApi);
const injector = await web3FromAddress(selectedAccount.address);
// startScoreTracking on People Chain - staking data comes from Asset Hub via XCM // startScoreTracking on People Chain - staking data comes from Asset Hub via XCM
const result = await startScoreTracking(peopleApi, selectedAccount.address, injector.signer); const result = await startScoreTracking(peopleApi, selectedAccount.address, injector.signer);
@@ -193,8 +192,7 @@ export default function Dashboard() {
setIsRecordingScore(true); setIsRecordingScore(true);
try { try {
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, peopleApi);
const injector = await web3FromAddress(selectedAccount.address);
const result = await recordTrustScore(peopleApi, selectedAccount.address, injector.signer); const result = await recordTrustScore(peopleApi, selectedAccount.address, injector.signer);
if (result.success) { if (result.success) {
@@ -215,8 +213,7 @@ export default function Dashboard() {
setIsClaimingReward(true); setIsClaimingReward(true);
try { try {
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, peopleApi);
const injector = await web3FromAddress(selectedAccount.address);
const result = await claimPezReward(peopleApi, selectedAccount.address, epochIndex, injector.signer); const result = await claimPezReward(peopleApi, selectedAccount.address, epochIndex, injector.signer);
if (result.success) { if (result.success) {
@@ -332,9 +329,7 @@ export default function Dashboard() {
setRenouncingCitizenship(true); setRenouncingCitizenship(true);
try { try {
const { web3Enable, web3FromAddress } = await import('@pezkuwi/extension-dapp'); const injector = await getSigner(selectedAccount.address, walletSource, peopleApi);
await web3Enable('PezkuwiChain');
const injector = await web3FromAddress(selectedAccount.address);
if (import.meta.env.DEV) console.log('Renouncing citizenship...'); if (import.meta.env.DEV) console.log('Renouncing citizenship...');
+4 -6
View File
@@ -10,7 +10,7 @@ import { NftList } from '@/components/NftList';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { ArrowUpRight, ArrowDownRight, History, ArrowLeft, RefreshCw, Coins, Loader2 } from 'lucide-react'; import { ArrowUpRight, ArrowDownRight, History, ArrowLeft, RefreshCw, Coins, Loader2 } from 'lucide-react';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { web3Enable, web3FromAddress } from '@pezkuwi/extension-dapp'; import { getSigner } from '@/lib/get-signer';
import { getPezRewards, recordTrustScore, claimPezReward, type PezRewardInfo } from '@pezkuwi/lib/scores'; import { getPezRewards, recordTrustScore, claimPezReward, type PezRewardInfo } from '@pezkuwi/lib/scores';
interface Transaction { interface Transaction {
@@ -29,7 +29,7 @@ interface Transaction {
const WalletDashboard: React.FC = () => { const WalletDashboard: React.FC = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const navigate = useNavigate(); const navigate = useNavigate();
const { api, isApiReady, peopleApi, isPeopleReady, selectedAccount } = usePezkuwi(); const { api, isApiReady, peopleApi, isPeopleReady, selectedAccount, walletSource } = usePezkuwi();
const [isTransferModalOpen, setIsTransferModalOpen] = useState(false); const [isTransferModalOpen, setIsTransferModalOpen] = useState(false);
const [isReceiveModalOpen, setIsReceiveModalOpen] = useState(false); const [isReceiveModalOpen, setIsReceiveModalOpen] = useState(false);
const [isHistoryModalOpen, setIsHistoryModalOpen] = useState(false); const [isHistoryModalOpen, setIsHistoryModalOpen] = useState(false);
@@ -239,8 +239,7 @@ const WalletDashboard: React.FC = () => {
if (!peopleApi || !selectedAccount) return; if (!peopleApi || !selectedAccount) return;
setIsRecordingScore(true); setIsRecordingScore(true);
try { try {
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, peopleApi);
const injector = await web3FromAddress(selectedAccount.address);
const result = await recordTrustScore(peopleApi, selectedAccount.address, injector.signer); const result = await recordTrustScore(peopleApi, selectedAccount.address, injector.signer);
if (result.success) { if (result.success) {
toast.success(t('wallet.trustScoreRecorded')); toast.success(t('wallet.trustScoreRecorded'));
@@ -260,8 +259,7 @@ const WalletDashboard: React.FC = () => {
if (!peopleApi || !selectedAccount) return; if (!peopleApi || !selectedAccount) return;
setIsClaimingReward(true); setIsClaimingReward(true);
try { try {
await web3Enable('PezkuwiChain'); const injector = await getSigner(selectedAccount.address, walletSource, peopleApi);
const injector = await web3FromAddress(selectedAccount.address);
const result = await claimPezReward(peopleApi, selectedAccount.address, epochIndex, injector.signer); const result = await claimPezReward(peopleApi, selectedAccount.address, epochIndex, injector.signer);
if (result.success) { if (result.success) {
const rewardInfo = pezRewards?.claimableRewards.find(r => r.epoch === epochIndex); const rewardInfo = pezRewards?.claimableRewards.find(r => r.epoch === epochIndex);