mirror of
https://github.com/logos-messaging/rln.waku.org.git
synced 2026-01-07 16:43:05 +00:00
fix: correctly initialise credentialsmanager/RLN
This commit is contained in:
parent
046b7427ed
commit
d8cbc3f586
@ -5,7 +5,7 @@ import { useRLN } from '../contexts';
|
|||||||
import { useWallet } from '../contexts';
|
import { useWallet } from '../contexts';
|
||||||
|
|
||||||
export function RLNStatusIndicator() {
|
export function RLNStatusIndicator() {
|
||||||
const { isInitialized, isStarted, isLoading, error } = useRLN();
|
const { isInitialized, isStarted, isLoading, error, rln } = useRLN();
|
||||||
const { isConnected, chainId } = useWallet();
|
const { isConnected, chainId } = useWallet();
|
||||||
|
|
||||||
// Debug logging
|
// Debug logging
|
||||||
@ -15,7 +15,8 @@ export function RLNStatusIndicator() {
|
|||||||
isInitialized,
|
isInitialized,
|
||||||
isStarted,
|
isStarted,
|
||||||
isLoading,
|
isLoading,
|
||||||
error
|
error,
|
||||||
|
rln
|
||||||
});
|
});
|
||||||
|
|
||||||
const getStatusColor = () => {
|
const getStatusColor = () => {
|
||||||
|
|||||||
@ -95,52 +95,79 @@ export function RLNProvider({ children }: { children: ReactNode }) {
|
|||||||
|
|
||||||
const initializeRLN = useCallback(async () => {
|
const initializeRLN = useCallback(async () => {
|
||||||
console.log("InitializeRLN called. Connected:", isConnected, "Signer available:", !!signer);
|
console.log("InitializeRLN called. Connected:", isConnected, "Signer available:", !!signer);
|
||||||
|
|
||||||
|
if (!isConnected || !signer) {
|
||||||
|
console.log("Cannot initialize RLN: Wallet not connected or signer not available.");
|
||||||
|
setError("Wallet not connected. Please connect your wallet.");
|
||||||
|
setIsLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
setError(null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setError(null);
|
let currentRln = rln;
|
||||||
setIsLoading(true);
|
|
||||||
|
if (!currentRln) {
|
||||||
const rlnInstance = rln;
|
console.log("Creating RLN instance...");
|
||||||
|
|
||||||
if (!rlnInstance) {
|
|
||||||
console.log("Creating RLN light instance...");
|
|
||||||
try {
|
try {
|
||||||
console.log("RLN instance created successfully:", !!rlnInstance);
|
currentRln = new RLNCredentialsManager();
|
||||||
setRln(rlnInstance);
|
setRln(currentRln);
|
||||||
setIsInitialized(true);
|
setIsInitialized(true);
|
||||||
setIsStarted(true);
|
console.log("RLN instance created successfully.");
|
||||||
console.log("isInitialized and isStarted set to true");
|
|
||||||
} catch (createErr) {
|
} catch (createErr) {
|
||||||
console.error("Error creating RLN instance:", createErr);
|
console.error("Error creating RLN instance:", createErr);
|
||||||
throw createErr;
|
setError(createErr instanceof Error ? createErr.message : 'Failed to create RLN instance');
|
||||||
|
setIsLoading(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("RLN instance already exists, skipping creation");
|
console.log("RLN instance already exists, skipping creation.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch rate limits if available
|
if (currentRln && !isStarted) {
|
||||||
if (rlnInstance && rlnInstance.contract) {
|
console.log("Starting RLN with signer...");
|
||||||
try {
|
try {
|
||||||
const minLimit = await rlnInstance.contract.getMinRateLimit();
|
await currentRln.start({ signer });
|
||||||
const maxLimit = await rlnInstance.contract.getMaxRateLimit();
|
setIsStarted(true);
|
||||||
if (minLimit !== undefined && maxLimit !== undefined) {
|
console.log("RLN started successfully.");
|
||||||
setRateMinLimit(minLimit);
|
|
||||||
setRateMaxLimit(maxLimit);
|
if (currentRln.contract) {
|
||||||
console.log("Rate limits fetched:", { min: minLimit, max: maxLimit });
|
try {
|
||||||
|
const minLimit = await currentRln.contract.getMinRateLimit();
|
||||||
|
const maxLimit = await currentRln.contract.getMaxRateLimit();
|
||||||
|
if (minLimit !== undefined && maxLimit !== undefined) {
|
||||||
|
setRateMinLimit(minLimit);
|
||||||
|
setRateMaxLimit(maxLimit);
|
||||||
|
console.log("Rate limits fetched:", { min: minLimit, max: maxLimit });
|
||||||
|
} else {
|
||||||
|
console.warn("Could not fetch rate limits: undefined values returned.");
|
||||||
|
}
|
||||||
|
} catch (limitErr) {
|
||||||
|
console.warn("Could not fetch rate limits after start:", limitErr);
|
||||||
|
// Don't fail initialization for this, but log it.
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Rate limits not available");
|
console.warn("RLN contract not available after start, cannot fetch rate limits.");
|
||||||
}
|
}
|
||||||
} catch (limitErr) {
|
|
||||||
console.warn("Could not fetch rate limits:", limitErr);
|
} catch (startErr) {
|
||||||
|
console.error("Error starting RLN:", startErr);
|
||||||
|
setError(startErr instanceof Error ? startErr.message : 'Failed to start RLN');
|
||||||
|
setIsStarted(false);
|
||||||
}
|
}
|
||||||
|
} else if (isStarted) {
|
||||||
|
console.log("RLN already started.");
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error in initializeRLN:', err);
|
console.error('Error in initializeRLN:', err);
|
||||||
setError(err instanceof Error ? err.message : 'Failed to initialize RLN');
|
setError(err instanceof Error ? err.message : 'Failed to initialize RLN');
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
}, [isConnected, signer, rln, isStarted]);
|
}, [isConnected, signer, rln, isStarted]);
|
||||||
|
|
||||||
// Auto-initialize effect for Light implementation
|
// Auto-initialize effect for Light implementation
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -1,218 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { createContext, useContext, useState, useEffect, ReactNode, useCallback } from 'react';
|
|
||||||
import { RLNCredentialsManager } from '@waku/rln';
|
|
||||||
import { ethers } from 'ethers';
|
|
||||||
import { ensureLineaSepoliaNetwork, ERC20_ABI, SIGNATURE_MESSAGE } from '../../utils/network';
|
|
||||||
import { useWallet } from '@/contexts';
|
|
||||||
import { RLNContextType } from './types';
|
|
||||||
|
|
||||||
const RLNContext = createContext<RLNContextType | undefined>(undefined);
|
|
||||||
|
|
||||||
export function RLNProvider({ children }: { children: ReactNode }) {
|
|
||||||
const { isConnected, signer } = useWallet();
|
|
||||||
const [rln, setRln] = useState<RLNCredentialsManager | null>(null);
|
|
||||||
const [isInitialized, setIsInitialized] = useState(false);
|
|
||||||
const [isStarted, setIsStarted] = useState(false);
|
|
||||||
const [error, setError] = useState<string | null>(null);
|
|
||||||
const [rateMinLimit, setRateMinLimit] = useState(0);
|
|
||||||
const [rateMaxLimit, setRateMaxLimit] = useState(0);
|
|
||||||
|
|
||||||
const initializeRLN = useCallback(async () => {
|
|
||||||
console.log("InitializeRLN called. Connected:", isConnected, "Signer available:", !!signer);
|
|
||||||
|
|
||||||
try {
|
|
||||||
setError(null);
|
|
||||||
|
|
||||||
if (!rln) {
|
|
||||||
console.log("Creating RLN instance...");
|
|
||||||
|
|
||||||
try {
|
|
||||||
const rlnInstance = new RLNCredentialsManager();
|
|
||||||
|
|
||||||
console.log("RLN instance created successfully:", !!rlnInstance);
|
|
||||||
setRln(rlnInstance);
|
|
||||||
|
|
||||||
setIsInitialized(true);
|
|
||||||
console.log("isInitialized set to true");
|
|
||||||
} catch (createErr) {
|
|
||||||
console.error("Error creating RLN instance:", createErr);
|
|
||||||
throw createErr;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("RLN instance already exists, skipping creation");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start RLN if wallet is connected
|
|
||||||
if (isConnected && signer && rln && !isStarted) {
|
|
||||||
console.log("Starting RLN with signer...");
|
|
||||||
try {
|
|
||||||
await rln.start({ signer });
|
|
||||||
|
|
||||||
setIsStarted(true);
|
|
||||||
console.log("RLN started successfully, isStarted set to true");
|
|
||||||
|
|
||||||
const minRate = await rln.contract?.getMinRateLimit();
|
|
||||||
const maxRate = await rln.contract?.getMaxRateLimit();
|
|
||||||
if (!minRate || !maxRate) {
|
|
||||||
throw new Error("Failed to get rate limits from contract");
|
|
||||||
}
|
|
||||||
|
|
||||||
setRateMinLimit(minRate);
|
|
||||||
setRateMaxLimit(maxRate);
|
|
||||||
console.log("Min rate:", minRate);
|
|
||||||
console.log("Max rate:", maxRate);
|
|
||||||
} catch (startErr) {
|
|
||||||
console.error("Error starting RLN:", startErr);
|
|
||||||
throw startErr;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("Skipping RLN start because:", {
|
|
||||||
isConnected,
|
|
||||||
hasSigner: !!signer,
|
|
||||||
hasRln: !!rln,
|
|
||||||
isAlreadyStarted: isStarted
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error in initializeRLN:', err);
|
|
||||||
setError(err instanceof Error ? err.message : 'Failed to initialize RLN');
|
|
||||||
}
|
|
||||||
}, [isConnected, signer, rln, isStarted]);
|
|
||||||
|
|
||||||
const registerMembership = async (rateLimit: number) => {
|
|
||||||
console.log("registerMembership called with rate limit:", rateLimit);
|
|
||||||
|
|
||||||
if (!rln || !isStarted) {
|
|
||||||
return { success: false, error: 'RLN not initialized or not started' };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!signer) {
|
|
||||||
return { success: false, error: 'No signer available' };
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Validate rate limit
|
|
||||||
if (rateLimit < rateMinLimit || rateLimit > rateMaxLimit) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: `Rate limit must be between ${rateMinLimit} and ${rateMaxLimit}`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
await rln.contract?.setRateLimit(rateLimit);
|
|
||||||
|
|
||||||
// Ensure we're on the correct network
|
|
||||||
const isOnLineaSepolia = await ensureLineaSepoliaNetwork(signer);
|
|
||||||
if (!isOnLineaSepolia) {
|
|
||||||
console.warn("Could not switch to Linea Sepolia network. Registration may fail.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get user address and contract address
|
|
||||||
const userAddress = await signer.getAddress();
|
|
||||||
|
|
||||||
if (!rln.contract || !rln.contract.address) {
|
|
||||||
return { success: false, error: "RLN contract address not available. Cannot proceed with registration." };
|
|
||||||
}
|
|
||||||
|
|
||||||
const contractAddress = rln.contract.address;
|
|
||||||
const tokenAddress = '0x185A0015aC462a0aECb81beCc0497b649a64B9ea'; // Linea Sepolia token address
|
|
||||||
|
|
||||||
// Create token contract instance
|
|
||||||
const tokenContract = new ethers.Contract(
|
|
||||||
tokenAddress,
|
|
||||||
ERC20_ABI,
|
|
||||||
signer
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check token balance
|
|
||||||
const tokenBalance = await tokenContract.balanceOf(userAddress);
|
|
||||||
if (tokenBalance.isZero()) {
|
|
||||||
return { success: false, error: "You need tokens to register a membership. Your token balance is zero." };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check and approve token allowance if needed
|
|
||||||
const currentAllowance = await tokenContract.allowance(userAddress, contractAddress);
|
|
||||||
if (currentAllowance.eq(0)) {
|
|
||||||
console.log("Requesting token approval...");
|
|
||||||
|
|
||||||
// Approve a large amount (max uint256)
|
|
||||||
const maxUint256 = ethers.constants.MaxUint256;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const approveTx = await tokenContract.approve(contractAddress, maxUint256);
|
|
||||||
console.log("Approval transaction submitted:", approveTx.hash);
|
|
||||||
|
|
||||||
// Wait for the transaction to be mined
|
|
||||||
await approveTx.wait(1);
|
|
||||||
console.log("Token approval confirmed");
|
|
||||||
} catch (approvalErr) {
|
|
||||||
console.error("Error during token approval:", approvalErr);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: `Failed to approve token: ${approvalErr instanceof Error ? approvalErr.message : String(approvalErr)}`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("Token allowance already sufficient");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate signature for identity
|
|
||||||
const message = `${SIGNATURE_MESSAGE} ${Date.now()}`;
|
|
||||||
const signature = await signer.signMessage(message);
|
|
||||||
|
|
||||||
const _credentials = await rln.registerMembership({signature: signature});
|
|
||||||
if (!_credentials) {
|
|
||||||
throw new Error("Failed to register membership: No credentials returned");
|
|
||||||
}
|
|
||||||
if (!_credentials.identity) {
|
|
||||||
throw new Error("Failed to register membership: Missing identity information");
|
|
||||||
}
|
|
||||||
if (!_credentials.membership) {
|
|
||||||
throw new Error("Failed to register membership: Missing membership information");
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, credentials: _credentials };
|
|
||||||
} catch (err) {
|
|
||||||
let errorMsg = "Failed to register membership";
|
|
||||||
if (err instanceof Error) {
|
|
||||||
errorMsg = err.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: false, error: errorMsg };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initialize RLN when wallet connects
|
|
||||||
useEffect(() => {
|
|
||||||
console.log("Wallet connection state changed:", { isConnected, hasSigner: !!signer });
|
|
||||||
if (isConnected && signer) {
|
|
||||||
console.log("Wallet connected, attempting to initialize RLN");
|
|
||||||
initializeRLN();
|
|
||||||
}
|
|
||||||
}, [isConnected, signer, initializeRLN]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<RLNContext.Provider
|
|
||||||
value={{
|
|
||||||
rln,
|
|
||||||
isInitialized,
|
|
||||||
isStarted,
|
|
||||||
error,
|
|
||||||
initializeRLN,
|
|
||||||
registerMembership,
|
|
||||||
rateMinLimit,
|
|
||||||
rateMaxLimit
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</RLNContext.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useRLN() {
|
|
||||||
const context = useContext(RLNContext);
|
|
||||||
if (context === undefined) {
|
|
||||||
throw new Error('useRLN must be used within a RLNProvider');
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user