chore: remove zerokit and use light by default

This commit is contained in:
Danish Arora 2025-04-16 21:22:18 +05:30
parent c8e0bb696b
commit d473ddb823
No known key found for this signature in database
GPG Key ID: 1C6EF37CDAE1426E
13 changed files with 41 additions and 389 deletions

View File

@ -7,7 +7,7 @@ import { Toaster } from "../components/ui/toaster";
import "@fontsource-variable/inter";
import "@fontsource-variable/jetbrains-mono";
import { WalletProvider, RLNImplementationProvider, KeystoreProvider, RLNProvider } from "../contexts/index";
import { WalletProvider, KeystoreProvider, RLNProvider } from "../contexts/index";
import { Header } from "../components/Header";
import { AppStateProvider } from "../contexts/AppStateContext";
import { Footer } from "@/components/Footer";
@ -51,20 +51,18 @@ export default function RootLayout({ children }: RootLayoutProps) {
>
<AppStateProvider>
<WalletProvider>
<RLNImplementationProvider>
<KeystoreProvider>
<RLNProvider>
<div className="relative flex min-h-screen flex-col">
<Header />
<main className="flex-1 container mx-auto py-8">
{children}
</main>
<Footer />
</div>
<Toaster />
</RLNProvider>
</KeystoreProvider>
</RLNImplementationProvider>
<KeystoreProvider>
<RLNProvider>
<div className="relative flex min-h-screen flex-col">
<Header />
<main className="flex-1 container mx-auto py-8">
{children}
</main>
<Footer />
</div>
<Toaster />
</RLNProvider>
</KeystoreProvider>
</WalletProvider>
</AppStateProvider>
</ThemeProvider>

View File

@ -1,40 +0,0 @@
"use client";
import { useRLNImplementation } from '../contexts';
import React from 'react';
import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group";
export function RLNImplementationToggle() {
const { implementation, setImplementation } = useRLNImplementation();
return (
<div className="flex flex-col space-y-3">
<label className="text-sm font-mono text-muted-foreground">
RLN Implementation
</label>
<ToggleGroup
type="single"
value={implementation}
onValueChange={(value) => {
if (value) setImplementation(value as 'light' | 'standard');
}}
className="w-full max-w-md"
>
<ToggleGroupItem value="light" className="flex-1">
Light
</ToggleGroupItem>
<ToggleGroupItem value="standard" className="flex-1">
Standard
</ToggleGroupItem>
</ToggleGroup>
<p className="text-xs font-mono text-muted-foreground opacity-80">
{implementation === 'light'
? 'Light implementation, without Zerokit. Instant initialisation.'
: 'Standard implementation, with Zerokit. Initialisation takes 10-15 seconds for WASM module.'
}
</p>
</div>
);
}

View File

@ -2,12 +2,10 @@
import React from 'react';
import { useRLN } from '../contexts';
import { useRLNImplementation } from '../contexts';
import { useWallet } from '../contexts';
export function RLNStatusIndicator() {
const { isInitialized, isStarted, isLoading, error } = useRLN();
const { implementation } = useRLNImplementation();
const { isConnected, chainId } = useWallet();
// Debug logging
@ -17,8 +15,7 @@ export function RLNStatusIndicator() {
isInitialized,
isStarted,
isLoading,
error,
implementation
error
});
const getStatusColor = () => {
@ -37,10 +34,10 @@ export function RLNStatusIndicator() {
const getStatusText = () => {
if (error) return 'Error';
if (isLoading) return `Initializing ${implementation} RLN...`;
if (isLoading) return 'Initializing RLN...';
if (!isConnected) return 'Connect Wallet';
if (chainId !== 59141) return 'Switch to Linea Sepolia';
if (isInitialized && isStarted) return `RLN Active`;
if (isInitialized && isStarted) return 'RLN Active';
return 'RLN Inactive';
};

View File

@ -1,13 +1,10 @@
"use client";
import React, { useState, useEffect } from 'react';
import { RLNImplementationToggle } from '../../RLNImplementationToggle';
import { RLNStatusIndicator } from '../../RLNStatusIndicator';
import { KeystoreEntity } from '@waku/rln';
import { useRLN } from '../../../contexts/rln/RLNContext';
import { useWallet } from '../../../contexts/wallet';
import { useRLNImplementation } from '../../../contexts';
import { RLNInitButton } from '../../RLNinitButton';
import { TerminalWindow } from '../../ui/terminal-window';
import { Slider } from '../../ui/slider';
import { Button } from '../../ui/button';
@ -17,7 +14,6 @@ import { toast } from 'sonner';
export function MembershipRegistration() {
const { registerMembership, isInitialized, isStarted, rateMinLimit, rateMaxLimit, error, isLoading } = useRLN();
const { isConnected, chainId } = useWallet();
const { implementation } = useRLNImplementation();
const [rateLimit, setRateLimit] = useState<number>(rateMinLimit);
const [isRegistering, setIsRegistering] = useState(false);
@ -110,10 +106,6 @@ export function MembershipRegistration() {
<RLNStatusIndicator />
</div>
<div className="space-y-6">
<div className="border-b border-terminal-border pb-6">
<RLNImplementationToggle />
</div>
{/* Network Warning */}
{isConnected && !isLineaSepolia && (
<div className="mb-4 p-3 border border-destructive/20 bg-destructive/5 rounded">
@ -125,7 +117,7 @@ export function MembershipRegistration() {
)}
{/* Informational Box */}
<div className="border-t border-terminal-border pt-4 mt-4">
<div className="pt-4">
<div className="flex items-center mb-3">
<span className="text-primary font-mono font-medium mr-2">{">"}</span>
<h3 className="text-md font-mono font-semibold text-primary">
@ -160,12 +152,6 @@ export function MembershipRegistration() {
</div>
<div className="border-t border-terminal-border pt-6 mt-4">
{implementation === 'standard' && !isInitialized && !isStarted && (
<div className="flex items-center space-x-2">
<RLNInitButton />
</div>
)}
{!isConnected ? (
<div className="text-warning-DEFAULT font-mono text-sm mt-4 flex items-center">
<span className="mr-2"></span>
@ -174,7 +160,7 @@ export function MembershipRegistration() {
) : !isInitialized || !isStarted ? (
<div className="text-warning-DEFAULT font-mono text-sm mt-4 flex items-center">
<span className="mr-2"></span>
{implementation === 'light' && isLoading ? 'Initializing Light RLN...' : membershipRegistration.initializePrompt}
{isLoading ? 'Initializing RLN...' : membershipRegistration.initializePrompt}
</div>
) : (
<form onSubmit={handleSubmit} className="space-y-4 mt-4">

View File

@ -1,3 +1,3 @@
export { WalletProvider, useWallet } from './wallet';
export { KeystoreProvider, useKeystore } from './keystore';
export { RLNImplementationProvider, useRLNImplementation, type RLNImplementationType, RLNProvider, useRLN } from './rln';
export { RLNProvider, useRLN } from './rln';

View File

@ -2,8 +2,6 @@
import { createContext, useContext, useState, useEffect, ReactNode, useCallback } from 'react';
import { KeystoreEntity, MembershipInfo, RLNCredentialsManager } from '@waku/rln';
import { createRLNImplementation } from './implementations';
import { useRLNImplementation } from './RLNImplementationContext';
import { ethers } from 'ethers';
import { useKeystore } from '../keystore';
import { ERC20_ABI, LINEA_SEPOLIA_CONFIG, ensureLineaSepoliaNetwork } from '../../utils/network';
@ -40,7 +38,6 @@ interface RLNContextType {
const RLNContext = createContext<RLNContextType | undefined>(undefined);
export function RLNProvider({ children }: { children: ReactNode }) {
const { implementation } = useRLNImplementation();
const [rln, setRln] = useState<RLNCredentialsManager | null>(null);
const [isInitialized, setIsInitialized] = useState(false);
const [isStarted, setIsStarted] = useState(false);
@ -96,20 +93,6 @@ export function RLNProvider({ children }: { children: ReactNode }) {
};
}, []);
// Reset RLN state when implementation changes
useEffect(() => {
console.log('Implementation changed, resetting state:', {
oldRln: !!rln,
oldIsInitialized: isInitialized,
oldIsStarted: isStarted,
newImplementation: implementation
});
setRln(null);
setIsInitialized(false);
setIsStarted(false);
setError(null);
}, [implementation]);
const initializeRLN = useCallback(async () => {
console.log("InitializeRLN called. Connected:", isConnected, "Signer available:", !!signer);
@ -117,19 +100,16 @@ export function RLNProvider({ children }: { children: ReactNode }) {
setError(null);
setIsLoading(true);
let rlnInstance = rln;
const rlnInstance = rln;
if (!rlnInstance) {
console.log(`Creating RLN ${implementation} instance...`);
console.log("Creating RLN light instance...");
try {
rlnInstance = await createRLNImplementation(implementation);
console.log("RLN instance created successfully:", !!rlnInstance);
setRln(rlnInstance);
setIsInitialized(true);
console.log("isInitialized set to true");
setIsStarted(true);
console.log("isInitialized and isStarted set to true");
} catch (createErr) {
console.error("Error creating RLN instance:", createErr);
throw createErr;
@ -137,39 +117,22 @@ export function RLNProvider({ children }: { children: ReactNode }) {
} else {
console.log("RLN instance already exists, skipping creation");
}
if (isConnected && signer && rlnInstance && !isStarted) {
console.log("Starting RLN with signer...");
try {
await rlnInstance.start({ signer });
setIsStarted(true);
console.log("RLN started successfully, isStarted set to true");
try {
const minLimit = await rlnInstance.contract?.getMinRateLimit();
const maxLimit = await rlnInstance.contract?.getMaxRateLimit();
if (minLimit !== undefined && maxLimit !== undefined) {
setRateMinLimit(minLimit);
setRateMaxLimit(maxLimit);
console.log("Rate limits fetched:", { min: minLimit, max: maxLimit });
} else {
throw new Error("Rate limits not available");
}
} catch (limitErr) {
console.warn("Could not fetch rate limits:", limitErr);
// Fetch rate limits if available
if (rlnInstance && rlnInstance.contract) {
try {
const minLimit = await rlnInstance.contract.getMinRateLimit();
const maxLimit = await rlnInstance.contract.getMaxRateLimit();
if (minLimit !== undefined && maxLimit !== undefined) {
setRateMinLimit(minLimit);
setRateMaxLimit(maxLimit);
console.log("Rate limits fetched:", { min: minLimit, max: maxLimit });
} else {
throw new Error("Rate limits not available");
}
} catch (startErr) {
console.error("Error starting RLN:", startErr);
throw startErr;
} catch (limitErr) {
console.warn("Could not fetch rate limits:", limitErr);
}
} else {
console.log("Skipping RLN start because:", {
isConnected,
hasSigner: !!signer,
hasRln: !!rlnInstance,
isAlreadyStarted: isStarted
});
}
} catch (err) {
console.error('Error in initializeRLN:', err);
@ -177,23 +140,22 @@ export function RLNProvider({ children }: { children: ReactNode }) {
} finally {
setIsLoading(false);
}
}, [isConnected, signer, implementation, rln, isStarted]);
}, [isConnected, signer, rln, isStarted]);
// Auto-initialize effect for Light implementation
useEffect(() => {
console.log('Auto-init check:', {
implementation,
isConnected,
hasSigner: !!signer,
isInitialized,
isStarted,
isLoading
});
if (implementation === 'light' && isConnected && signer && !isInitialized && !isStarted && !isLoading) {
if (isConnected && signer && !isInitialized && !isStarted && !isLoading) {
console.log('Auto-initializing Light RLN implementation...');
initializeRLN();
}
}, [implementation, isConnected, signer, isInitialized, isStarted, isLoading, initializeRLN]);
}, [isConnected, signer, isInitialized, isStarted, isLoading, initializeRLN]);
const getCurrentRateLimit = async (): Promise<number | null> => {
try {

View File

@ -1,30 +0,0 @@
"use client";
import { createContext, useContext, useState, ReactNode } from 'react';
export type RLNImplementationType = 'standard' | 'light';
interface RLNImplementationContextType {
implementation: RLNImplementationType;
setImplementation: (implementation: RLNImplementationType) => void;
}
const RLNImplementationContext = createContext<RLNImplementationContextType | undefined>(undefined);
export function RLNImplementationProvider({ children }: { children: ReactNode }) {
const [implementation, setImplementation] = useState<RLNImplementationType>('light');
return (
<RLNImplementationContext.Provider value={{ implementation, setImplementation }}>
{children}
</RLNImplementationContext.Provider>
);
}
export function useRLNImplementation() {
const context = useContext(RLNImplementationContext);
if (context === undefined) {
throw new Error('useRLNImplementation must be used within a RLNImplementationProvider');
}
return context;
}

View File

@ -1,11 +0,0 @@
"use client";
import { createRLN, RLNCredentialsManager } from '@waku/rln';
export async function createRLNImplementation(type: 'standard' | 'light' = 'light') {
if (type === 'standard') {
return await createRLN();
} else {
return new RLNCredentialsManager;
}
}

View File

@ -1,3 +0,0 @@
export { RLNProvider as StandardRLNProvider, useRLN as useStandardRLN } from './standard';
export { RLNProvider as LightRLNProvider, useRLN as useLightRLN } from './light';
export { createRLNImplementation } from './factory';

View File

@ -1,206 +0,0 @@
"use client";
import { createContext, useContext, useState, ReactNode } from 'react';
import { createRLN, LINEA_CONTRACT, RLNInstance } from '@waku/rln';
import { ethers } from 'ethers';
import { ensureLineaSepoliaNetwork, ERC20_ABI, SIGNATURE_MESSAGE } from '../../../utils/network';
import { RLNContextType } from './types';
import { useWallet } from '@/contexts';
const RLNContext = createContext<RLNContextType | undefined>(undefined);
export function RLNProvider({ children }: { children: ReactNode }) {
const { isConnected, signer } = useWallet();
const [rln, setRln] = useState<RLNInstance | 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 = async () => {
console.log("InitializeRLN called. Connected:", isConnected, "Signer available:", !!signer);
try {
setError(null);
if (!rln) {
console.log("Creating RLN instance...");
try {
const rlnInstance = await createRLN();
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");
}
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();
setRateMinLimit(minRate || 0);
setRateMaxLimit(maxRate || 0);
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');
}
};
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}`
};
}
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 = LINEA_CONTRACT.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 };
}
};
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;
}

View File

@ -1,2 +1 @@
export { RLNProvider, useRLN } from './RLNContext';
export { RLNImplementationProvider, useRLNImplementation, type RLNImplementationType } from './RLNImplementationContext';
export { RLNProvider, useRLN } from './RLNContext';

View File

@ -3,7 +3,7 @@
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 { ensureLineaSepoliaNetwork, ERC20_ABI, SIGNATURE_MESSAGE } from '../../utils/network';
import { useWallet } from '@/contexts';
import { RLNContextType } from './types';