chore: add desc, link resources

This commit is contained in:
Danish Arora 2025-04-04 02:33:36 +05:30
parent 4f7735e6cb
commit c6fe4d65e7
No known key found for this signature in database
GPG Key ID: 1C6EF37CDAE1426E
4 changed files with 201 additions and 34 deletions

View File

@ -43,4 +43,5 @@ If you encounter an "ERC20: insufficient allowance" error, it means the token ap
- [ ] update descriptions, and link specs/resources
- [ ] footer for discord help
- [ ] add info about exporting/using keystore/credential and using with nwaku/nwaku-compose/waku-simulator
- [ x ] exporting entire keystore
- [ x ] exporting entire keystore
- [ ] clean comments

View File

@ -2,13 +2,14 @@
import React, { useState } from 'react';
import { useKeystore } from '../../../contexts/keystore';
import { readKeystoreFromFile, saveKeystoreCredentialToFile } from '../../../utils/keystore';
import { readKeystoreFromFile, saveKeystoreCredentialToFile } from '../../../utils/keystore';
import { DecryptedCredentials } from '@waku/rln';
import { useAppState } from '../../../contexts/AppStateContext';
import { TerminalWindow } from '../../ui/terminal-window';
import { Button } from '../../ui/button';
import { Copy, Eye, Download, Trash2, ArrowDownToLine } from 'lucide-react';
import { KeystoreExporter } from '../../KeystoreExporter';
import { keystoreManagement, type ContentSegment } from '../../../content/index';
export function KeystoreManagement() {
const {
@ -116,7 +117,7 @@ export function KeystoreManagement() {
<div className="space-y-6">
<TerminalWindow className="w-full">
<h2 className="text-lg font-mono font-medium text-primary mb-4 cursor-blink">
Keystore Management
{keystoreManagement.title}
</h2>
<div className="space-y-6">
<div className="flex flex-wrap gap-3">
@ -127,7 +128,7 @@ export function KeystoreManagement() {
>
<span className="relative z-10 flex items-center">
<ArrowDownToLine className="w-4 h-4 mr-2" />
Import Keystore
{keystoreManagement.buttons.import}
</span>
<span className="absolute inset-0 bg-primary/10 transform translate-y-full group-hover:translate-y-0 transition-transform duration-200"></span>
</Button>
@ -140,15 +141,67 @@ export function KeystoreManagement() {
<div className="my-4 p-3 border border-warning-DEFAULT/20 bg-warning-DEFAULT/5 rounded">
<p className="text-sm text-warning-DEFAULT font-mono flex items-center">
<span className="mr-2"></span>
Please initialize RLN before managing credentials
{keystoreManagement.noCredentialsWarning}
</p>
</div>
)}
{/* About Section */}
<div className="border-t border-terminal-border pt-4 mt-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">
{keystoreManagement.infoHeader}
</h3>
</div>
<div className="space-y-3">
{keystoreManagement.about.map((paragraph: ContentSegment[], i: number) => (
<p key={i} className="text-sm text-foreground mb-2 opacity-90">
{paragraph.map((segment: ContentSegment, j: number) => (
segment.type === 'link' ? (
<a
key={j}
href={segment.url}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
{segment.content}
</a>
) : (
<span key={j}>{segment.content}</span>
)
))}
</p>
))}
</div>
</div>
{/* Resources Section */}
<div className="border-t border-terminal-border pt-4">
<h3 className="text-md font-mono font-semibold text-primary mb-3">
{keystoreManagement.resources.title}
</h3>
<div className="flex flex-wrap gap-3">
{keystoreManagement.resources.links.map((link: { name: string; url: string }, i: number) => (
<a
key={i}
href={link.url}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline text-sm"
>
{link.name}
</a>
))}
</div>
</div>
{/* Stored Credentials */}
<div className="border-t border-terminal-border pt-6">
<h3 className="text-sm font-mono font-medium text-muted-foreground mb-4">
Stored Credentials
{keystoreManagement.storedCredentialsTitle}
</h3>
{hasStoredCredentials ? (
@ -189,7 +242,7 @@ export function KeystoreManagement() {
className="text-accent hover:text-accent hover:border-accent flex items-center gap-1 py-1"
>
<Eye className="w-3 h-3" />
<span>View</span>
<span>{keystoreManagement.buttons.view}</span>
</Button>
<Button
onClick={() => {

View File

@ -10,6 +10,7 @@ import { RLNInitButton } from '../../RLNinitButton';
import { TerminalWindow } from '../../ui/terminal-window';
import { Slider } from '../../ui/slider';
import { Button } from '../../ui/button';
import { membershipRegistration, type ContentSegment } from '../../../content/index';
export function MembershipRegistration() {
const { setGlobalError } = useAppState();
@ -101,7 +102,7 @@ export function MembershipRegistration() {
<div className="space-y-6 max-w-full">
<TerminalWindow className="w-full">
<h2 className="text-lg font-mono font-medium text-primary mb-4 cursor-blink">
RLN Membership Registration
{membershipRegistration.title}
</h2>
<div className="space-y-6">
<div className="border-b border-terminal-border pb-6">
@ -113,35 +114,43 @@ export function MembershipRegistration() {
<div className="mb-4 p-3 border border-destructive/20 bg-destructive/5 rounded">
<p className="text-sm text-destructive font-mono flex items-center">
<span className="mr-2"></span>
<span>You are not connected to Linea Sepolia network. Please switch networks to register.</span>
<span>{membershipRegistration.networkWarning}</span>
</p>
</div>
)}
{/* Informational Box - Now part of main terminal */}
{/* Informational Box */}
<div className="border-t border-terminal-border pt-4 mt-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">
RLN Membership Info
{membershipRegistration.infoHeader}
</h3>
</div>
<div className="space-y-3">
<h4 className="text-md font-mono font-semibold text-primary cursor-blink">
About RLN Membership on Linea Sepolia
{membershipRegistration.aboutTitle}
</h4>
<p className="text-sm text-foreground mb-2 opacity-90">
RLN (Rate Limiting Nullifier) membership allows you to participate in Waku RLN Relay with rate limiting protection,
without exposing your private keys on your node.
</p>
<p className="text-sm text-foreground mb-2 opacity-90">
This application is configured to use the <span className="text-primary">Linea Sepolia</span> testnet for RLN registrations.
</p>
<p className="text-sm text-foreground opacity-90">
When you register, your wallet will sign a message that will be used to generate a cryptographic identity
for your membership. This allows your node to prove it has permission to send messages without revealing your identity.
</p>
{membershipRegistration.about.map((paragraph: ContentSegment[], i: number) => (
<p key={i} className="text-sm text-foreground mb-2 opacity-90">
{paragraph.map((segment: ContentSegment, j: number) => (
segment.type === 'link' ? (
<a
key={j}
href={segment.url}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
{segment.content}
</a>
) : (
<span key={j}>{segment.content}</span>
)
))}
</p>
))}
</div>
</div>
@ -153,12 +162,12 @@ export function MembershipRegistration() {
{!isConnected ? (
<div className="text-warning-DEFAULT font-mono text-sm mt-4 flex items-center">
<span className="mr-2"></span>
Please connect your wallet to register a membership
{membershipRegistration.connectWalletPrompt}
</div>
) : !isInitialized || !isStarted ? (
<div className="text-warning-DEFAULT font-mono text-sm mt-4 flex items-center">
<span className="mr-2"></span>
Please initialize RLN before registering a membership
{membershipRegistration.initializePrompt}
</div>
) : (
<form onSubmit={handleSubmit} className="space-y-4 mt-4">
@ -167,7 +176,7 @@ export function MembershipRegistration() {
htmlFor="rateLimit"
className="block text-sm font-mono text-muted-foreground mb-2"
>
Rate Limit (messages per epoch)
{membershipRegistration.form.rateLimitLabel}
</label>
<div className="flex items-center space-x-4 py-2">
<Slider
@ -197,24 +206,25 @@ export function MembershipRegistration() {
htmlFor="saveToKeystore"
className="ml-2 text-sm font-mono text-foreground"
>
Save credentials to keystore
{membershipRegistration.form.saveToKeystoreLabel}
</label>
</div>
{saveToKeystore && (
<div>
<label
htmlFor="keystorePassword"
className="block text-sm font-mono text-muted-foreground mb-1"
className="block text-sm font-mono text-muted-foreground mb-2"
>
Keystore Password (min 8 characters)
{membershipRegistration.form.passwordLabel}
</label>
<input
type="password"
id="keystorePassword"
value={keystorePassword}
onChange={(e) => setKeystorePassword(e.target.value)}
className="w-full px-3 py-2 border border-terminal-border rounded-md bg-terminal-background text-foreground font-mono focus:ring-1 focus:ring-primary focus:border-primary text-sm"
placeholder="Enter password to encrypt credentials"
placeholder={membershipRegistration.form.passwordPlaceholder}
className="w-full px-3 py-2 bg-terminal-background border border-terminal-border rounded-md text-sm font-mono focus:outline-none focus:ring-2 focus:ring-primary"
/>
</div>
)}
@ -222,11 +232,10 @@ export function MembershipRegistration() {
<Button
type="submit"
disabled={isRegistering || !isLineaSepolia || (saveToKeystore && !keystorePassword)}
variant={isRegistering ? "outline" : "default"}
disabled={isRegistering}
className="w-full"
>
{isRegistering ? 'Registering...' : 'Register Membership'}
{isRegistering ? membershipRegistration.form.registeringButton : membershipRegistration.form.registerButton}
</Button>
</form>
)}

View File

@ -0,0 +1,104 @@
// Types for content structure
type Link = {
text: string;
url: string;
};
export type ContentSegment = {
type: 'text' | 'link';
content: string;
url?: string;
};
export type Paragraph = ContentSegment[];
// Content for RLN Membership Registration
export const membershipRegistration = {
title: "RLN Membership Registration",
aboutTitle: "About RLN Membership on Linea Sepolia",
about: [
[
{ type: 'text', content: 'RLN (' },
{ type: 'link', content: 'Rate Limiting Nullifier', url: 'https://github.com/Rate-Limiting-Nullifier' },
{ type: 'text', content: ') membership allows you to participate in ' },
{ type: 'link', content: 'Waku RLN Relay', url: 'https://blog.waku.org/explanation-series-rln-relay/' },
{ type: 'text', content: ' with rate limiting protection, without exposing your private keys on your node.' }
],
[
{ type: 'text', content: 'This application is configured to use the ' },
{ type: 'link', content: 'Linea Sepolia', url: 'https://sepolia.lineascan.build/address/0xb9cd878c90e49f797b4431fbf4fb333108cb90e6' },
{ type: 'text', content: ' testnet for RLN registrations.' }
],
[
{ type: 'text', content: 'When you register, your wallet will sign a message that will be used to generate a ' },
{ type: 'link', content: 'cryptographic identity', url: 'https://github.com/waku-org/specs/blob/master/standards/application/rln-keystore.md' },
{ type: 'text', content: ' for your membership. This allows your node to prove it has permission to send messages without revealing your identity.' }
]
] as Paragraph[],
infoHeader: "RLN Membership Info",
connectWalletPrompt: "Please connect your wallet to register a membership",
initializePrompt: "Please initialize RLN before registering a membership",
networkWarning: "You are not connected to Linea Sepolia network. Please switch networks to register.",
form: {
rateLimitLabel: "Rate Limit (messages per epoch)",
saveToKeystoreLabel: "Save credentials to keystore",
passwordLabel: "Keystore Password (min 8 characters)",
passwordPlaceholder: "Enter password to encrypt credentials",
registerButton: "Register Membership",
registeringButton: "Registering..."
}
};
// Content for Keystore Management
export const keystoreManagement = {
title: "Keystore Management",
buttons: {
import: "Import Keystore",
export: "Export Keystore",
view: "View",
decrypt: "Decrypt",
decrypting: "Decrypting...",
remove: "Remove"
},
about: [
[
{ type: 'text', content: 'Keystore management allows you to securely store, import, export and manage your ' },
{ type: 'link', content: 'RLN membership credentials', url: 'https://github.com/waku-org/specs/blob/master/standards/application/rln-keystore.md' },
{ type: 'text', content: '.' }
],
[
{ type: 'text', content: 'Credentials are encrypted with your password and can be used across different devices or applications. Learn more about ' },
{ type: 'link', content: 'keystore security', url: 'https://github.com/waku-org/specs/blob/master/standards/application/rln-keystore.md#security-considerations' },
{ type: 'text', content: '.' }
],
[
{ type: 'text', content: 'You can export your credentials as a file and import them on another device to use the same membership.' }
]
] as Paragraph[],
infoHeader: "About Keystore Management",
noCredentialsWarning: "Please initialize RLN before managing credentials",
storedCredentialsTitle: "Stored Credentials",
passwordPlaceholder: "Enter credential password",
credentialDetailsTitle: "Credential Details",
resources: {
title: "Resources",
links: [
{
name: "RLN Specs",
url: "https://specs.status.im/spec/waku/rln-v1"
},
{
name: "Waku GitHub",
url: "https://github.com/waku-org/waku-rln-contract"
},
{
name: "Keystore Documentation",
url: "https://github.com/waku-org/specs/blob/master/standards/application/rln-keystore.md"
}
]
}
};