feat: show token spend for rate limit

This commit is contained in:
Danish Arora 2025-07-14 17:20:36 +05:30
parent f7ccf81ba4
commit a7c1bbbfea
No known key found for this signature in database
GPG Key ID: 1C6EF37CDAE1426E
6 changed files with 9883 additions and 1062 deletions

8965
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@
"@radix-ui/react-toggle": "^1.1.2",
"@radix-ui/react-toggle-group": "^1.1.2",
"@radix-ui/react-tooltip": "^1.1.8",
"@waku/rln": "0.1.5-a824fff.0",
"@waku/rln": "0.1.7-987c6cd.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"framer-motion": "^12.6.3",

View File

@ -11,14 +11,13 @@ import { Button } from '../../ui/button';
import { membershipRegistration, type ContentSegment } from '../../../content/index';
import { toast } from 'sonner';
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '../../ui/tooltip';
interface MembershipRegistrationProps {
tabId?: string;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function MembershipRegistration({ tabId: _tabId }: MembershipRegistrationProps) {
const { registerMembership, isInitialized, isStarted, error, isLoading } = useRLN();
const { registerMembership, isInitialized, isStarted, error, isLoading, getPriceForRateLimit } = useRLN();
const { isConnected, chainId } = useWallet();
// Replace slider state with discrete options
@ -37,6 +36,33 @@ export function MembershipRegistration({ tabId: _tabId }: MembershipRegistration
const isLineaSepolia = chainId === 59141;
const [price, setPrice] = useState<string>('');
const [priceLoading, setPriceLoading] = useState(false);
const [priceError, setPriceError] = useState<string | null>(null);
useEffect(() => {
if (isLoading || !isInitialized || !isStarted ) return;
let cancelled = false;
setPrice('');
setPriceError(null);
setPriceLoading(true);
(async () => {
try {
const result = await getPriceForRateLimit(rateLimit);
if (!cancelled) {
setPrice(result.price.toString());
}
} catch {
if (!cancelled) {
setPriceError('Could not fetch price');
}
} finally {
if (!cancelled) setPriceLoading(false);
}
})();
return () => { cancelled = true; };
}, [rateLimit, getPriceForRateLimit, isLoading, isInitialized, isStarted]);
useEffect(() => {
if (error) {
toast.error(error);
@ -210,6 +236,16 @@ export function MembershipRegistration({ tabId: _tabId }: MembershipRegistration
</ToggleGroupItem>
</ToggleGroup>
</div>
{/* Show calculated token spend for selected rate limit */}
<div className="text-xs text-muted-foreground font-mono mt-1">
{priceLoading ? (
<>Token spend required: <span className="italic">Loading...</span></>
) : priceError ? (
<>Token spend required: <span className="text-destructive">{priceError}</span></>
) : (
<>Token spend required: <span>{price}</span> WTT</>
)}
</div>
</div>
<div className="space-y-2">

View File

@ -33,6 +33,7 @@ interface RLNContextType {
getRateLimitsBounds: () => Promise<{ success: boolean; rateMinLimit: number; rateMaxLimit: number; error?: string }>;
saveCredentialsToKeystore: (credentials: KeystoreEntity, password: string) => Promise<string>;
isLoading: boolean;
getPriceForRateLimit: (rateLimit: number) => Promise<{ price: string }>;
}
const RLNContext = createContext<RLNContextType | undefined>(undefined);
@ -465,6 +466,20 @@ export function RLNProvider({ children }: { children: ReactNode }) {
}
};
const getPriceForRateLimit = async (rateLimit: number): Promise<{ price: string }> => {
try {
if (!rln || !rln.contract || !isStarted) {
throw new Error('RLN not initialized or contract not available');
}
const result = await rln.contract.getPriceForRateLimit(rateLimit);
const formatted = ethers.utils.formatUnits(result.price, 18);
return { price: formatted };
} catch (err) {
console.error('Error getting price for rate limit:', err);
throw err;
}
};
return (
<RLNContext.Provider
value={{
@ -483,7 +498,8 @@ export function RLNProvider({ children }: { children: ReactNode }) {
getCurrentRateLimit,
getRateLimitsBounds,
saveCredentialsToKeystore: saveToKeystore,
isLoading
isLoading,
getPriceForRateLimit
}}
>
{children}

View File

@ -14,4 +14,4 @@ export function cn(...inputs: ClassValue[]) {
*/
export function hslToVar(hsl: string): string {
return `hsl(var(${hsl}))`;
}
}

1918
yarn.lock

File diff suppressed because it is too large Load Diff