import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import SecondaryPageLayout from '@/layouts/SecondaryPageLayout' import { createProfileDraftEvent } from '@/lib/draft-event' import { isEmail } from '@/lib/utils' import { useNostr } from '@/providers/NostrProvider' import { useZap } from '@/providers/ZapProvider' import { connectNWC, WebLNProviders } from '@getalby/bitcoin-connect' import { Check, CheckCircle2, Copy, ExternalLink, Loader2 } from 'lucide-react' import { forwardRef, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { toast } from 'sonner' const RIZFUL_URL = 'https://rizful.com' const RIZFUL_SIGNUP_URL = `${RIZFUL_URL}/create-account` const RIZFUL_GET_TOKEN_URL = `${RIZFUL_URL}/nostr_onboarding_auth_token/get_token` const RIZFUL_TOKEN_EXCHANGE_URL = `${RIZFUL_URL}/nostr_onboarding_auth_token/post_for_secrets` const RizfulPage = forwardRef(({ index }: { index?: number }, ref) => { const { t } = useTranslation() const { pubkey, profile, profileEvent, publish, updateProfileEvent } = useNostr() const { provider } = useZap() const [token, setToken] = useState('') const [connecting, setConnecting] = useState(false) const [connected, setConnected] = useState(false) const [copiedLightningAddress, setCopiedLightningAddress] = useState(false) const [lightningAddress, setLightningAddress] = useState('') useEffect(() => { if (provider instanceof WebLNProviders.NostrWebLNProvider) { const lud16 = provider.client.lud16 const domain = lud16?.split('@')[1] if (domain !== 'rizful.com') return if (lud16) { setConnected(true) setLightningAddress(lud16) } } }, [provider]) const updateUserProfile = async (address: string) => { try { // If the profile already has a lightning address, do nothing if (profile?.lightningAddress) { return } const profileContent = profileEvent ? JSON.parse(profileEvent.content) : {} if (isEmail(address)) { profileContent.lud16 = address } else if (address.startsWith('lnurl')) { profileContent.lud06 = address } else { throw new Error(t('Invalid Lightning Address')) } if (!profileContent.nip05) { profileContent.nip05 = address } const profileDraftEvent = createProfileDraftEvent( JSON.stringify(profileContent), profileEvent?.tags ) const newProfileEvent = await publish(profileDraftEvent) await updateProfileEvent(newProfileEvent) } catch (e: unknown) { toast.error(e instanceof Error ? e.message : String(e)) } } const connectRizful = async () => { setConnecting(true) try { const r = await fetch(RIZFUL_TOKEN_EXCHANGE_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'omit', body: JSON.stringify({ secret_code: token.trim(), nostr_public_key: pubkey }) }) if (!r.ok) { const errorText = await r.text() throw new Error(errorText || 'Exchange failed') } const j = (await r.json()) as { nwc_uri?: string lightning_address?: string } if (j.nwc_uri) { connectNWC(j.nwc_uri) } if (j.lightning_address) { updateUserProfile(j.lightning_address) } } catch (e: unknown) { toast.error(e instanceof Error ? e.message : String(e)) } finally { setTimeout(() => setConnecting(false), 5000) } } if (connected) { return (
{t('Rizful Vault connected!')}
{t('You can now use your Rizful Vault to zap your favorite notes and creators.')}
{lightningAddress && (
{t('Your Lightning Address')}:
{ navigator.clipboard.writeText(lightningAddress) setCopiedLightningAddress(true) setTimeout(() => setCopiedLightningAddress(false), 2000) }} > {lightningAddress}{' '} {copiedLightningAddress ? ( ) : ( )}
)}
) } return (
1. {t('New to Rizful?')}
{t('If you already have a Rizful account, you can skip this step.')}
2. {t('Get your one-time code')}
3. {t('Connect to your Rizful Vault')}
{ setToken(e.target.value.trim()) }} />
) }) RizfulPage.displayName = 'RizfulPage' export default RizfulPage function openPopup(url: string, name: string, width = 520, height = 700) { const left = Math.max((window.screenX || 0) + (window.innerWidth - width) / 2, 0) const top = Math.max((window.screenY || 0) + (window.innerHeight - height) / 2, 0) return window.open( url, name, `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no` ) }