import browser from 'webextension-polyfill' import React, {useState, useCallback, useEffect} from 'react' import {render} from 'react-dom' import {generatePrivateKey, nip19} from 'nostr-tools' import {getPermissionsString, readPermissions} from './common' function Options() { let [key, setKey] = useState('') let [relays, setRelays] = useState([]) let [newRelayURL, setNewRelayURL] = useState('') let [permissions, setPermissions] = useState() let [message, setMessage] = useState('') const showMessage = useCallback(msg => { setMessage(msg) setTimeout(setMessage, 3000) }) useEffect(() => { browser.storage.local.get(['private_key', 'relays']).then(results => { if (results.private_key) setKey(nip19.nsecEncode(results.private_key)) if (results.relays) { let relaysList = [] for (let url in results.relays) { relaysList.push({ url, policy: results.relays[url] }) } setRelays(relaysList) } }) }, []) useEffect(() => { readPermissions().then(permissions => { setPermissions( Object.entries(permissions).map( ([host, {level, condition, created_at}]) => ({ host, level, condition, created_at }) ) ) }) }, []) return ( <>

nos2x

nostr signer extension

options

preferred relays:
{relays.map(({url, policy}, i) => (
))}
setNewRelayURL(e.target.value)} onBlur={addNewRelay} />
{permissions?.length > 0 && ( <>

permissions

{permissions.map(({host, level, condition, created_at}) => ( ))}
domain permissions condition since
{host} {getPermissionsString(level)} {condition} {new Date(created_at * 1000) .toISOString() .split('.')[0] .split('T') .join(' ')}
)}
{message}
) async function handleKeyChange(e) { let key = e.target.value.toLowerCase().trim() setKey(key) } async function generate(e) { setKey(nip19.nsecEncode(generatePrivateKey())) } async function saveKey() { if (!isKeyValid()) return let hexOrEmptyKey = key try { let {type, data} = nip19.decode(key) if (type === 'nsec') hexOrEmptyKey = data } catch (_) {} await browser.storage.local.set({ private_key: hexOrEmptyKey }) if (hexOrEmptyKey !== '') { setKey(nip19.nsecEncode(hexOrEmptyKey)) } showMessage('saved private key!') } function isKeyValid() { if (key === '') return true if (key.match(/^[a-f0-9]{64}$/)) return true try { if (nip19.decode(key).type === 'nsec') return true } catch (_) {} return false } function changeRelayURL(i, ev) { setRelays([ ...relays.slice(0, i), {url: ev.target.value, policy: relays[i].policy}, ...relays.slice(i + 1) ]) } function toggleRelayPolicy(i, cat) { setRelays([ ...relays.slice(0, i), { url: relays[i].url, policy: {...relays[i].policy, [cat]: !relays[i].policy[cat]} }, ...relays.slice(i + 1) ]) } function addNewRelay() { relays.push({ url: newRelayURL, policy: {read: true, write: true} }) setRelays(relays) setNewRelayURL('') } async function saveRelays() { await browser.storage.local.set({ relays: Object.fromEntries( relays .filter(({url}) => url.trim() !== '') .map(({url, policy}) => [url.trim(), policy]) ) }) showMessage('saved relays!') } } render(, document.getElementById('main'))