feat: support login with hex privkey

This commit is contained in:
codytseng
2025-03-25 18:19:50 +08:00
parent e4b7722c50
commit fe0190a674
2 changed files with 21 additions and 12 deletions

View File

@@ -31,19 +31,19 @@ export default function PrivateKeyLogin({
function NsecLogin({ back, onLoginSuccess }: { back: () => void; onLoginSuccess: () => void }) { function NsecLogin({ back, onLoginSuccess }: { back: () => void; onLoginSuccess: () => void }) {
const { t } = useTranslation() const { t } = useTranslation()
const { nsecLogin } = useNostr() const { nsecLogin } = useNostr()
const [nsec, setNsec] = useState('') const [nsecOrHex, setNsecOrHex] = useState('')
const [errMsg, setErrMsg] = useState<string | null>(null) const [errMsg, setErrMsg] = useState<string | null>(null)
const [password, setPassword] = useState('') const [password, setPassword] = useState('')
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setNsec(e.target.value) setNsecOrHex(e.target.value)
setErrMsg(null) setErrMsg(null)
} }
const handleLogin = () => { const handleLogin = () => {
if (nsec === '') return if (nsecOrHex === '') return
nsecLogin(nsec, password) nsecLogin(nsecOrHex, password)
.then(() => onLoginSuccess()) .then(() => onLoginSuccess())
.catch((err) => { .catch((err) => {
setErrMsg(err.message) setErrMsg(err.message)
@@ -58,11 +58,11 @@ function NsecLogin({ back, onLoginSuccess }: { back: () => void; onLoginSuccess:
)} )}
</div> </div>
<div className="space-y-1"> <div className="space-y-1">
<div className="text-muted-foreground text-sm font-semibold">nsec</div> <div className="text-muted-foreground text-sm font-semibold">nsec or hex</div>
<Input <Input
type="password" type="password"
placeholder="nsec1.." placeholder="nsec1.. or hex"
value={nsec} value={nsecOrHex}
onChange={handleInputChange} onChange={handleInputChange}
className={errMsg ? 'border-destructive' : ''} className={errMsg ? 'border-destructive' : ''}
/> />

View File

@@ -11,6 +11,7 @@ import client from '@/services/client.service'
import indexedDb from '@/services/indexed-db.service' import indexedDb from '@/services/indexed-db.service'
import storage from '@/services/local-storage.service' import storage from '@/services/local-storage.service'
import { ISigner, TAccount, TAccountPointer, TDraftEvent, TProfile, TRelayList } from '@/types' import { ISigner, TAccount, TAccountPointer, TDraftEvent, TProfile, TRelayList } from '@/types'
import { bytesToHex, hexToBytes } from '@noble/hashes/utils'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { Event, kinds, VerifiedEvent } from 'nostr-tools' import { Event, kinds, VerifiedEvent } from 'nostr-tools'
import * as nip19 from 'nostr-tools/nip19' import * as nip19 from 'nostr-tools/nip19'
@@ -248,18 +249,26 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
await loginWithAccountPointer(act) await loginWithAccountPointer(act)
} }
const nsecLogin = async (nsec: string, password?: string) => { const nsecLogin = async (nsecOrHex: string, password?: string) => {
const browserNsecSigner = new NsecSigner() const browserNsecSigner = new NsecSigner()
const { type, data: privkey } = nip19.decode(nsec) let privkey: Uint8Array
if (nsecOrHex.startsWith('nsec')) {
const { type, data } = nip19.decode(nsecOrHex)
if (type !== 'nsec') { if (type !== 'nsec') {
throw new Error('invalid nsec') throw new Error('invalid nsec or hex')
}
privkey = data
} else if (/^[0-9a-fA-F]{64}$/.test(nsecOrHex)) {
privkey = hexToBytes(nsecOrHex)
} else {
throw new Error('invalid nsec or hex')
} }
const pubkey = browserNsecSigner.login(privkey) const pubkey = browserNsecSigner.login(privkey)
if (password) { if (password) {
const ncryptsec = nip49.encrypt(privkey, password) const ncryptsec = nip49.encrypt(privkey, password)
return login(browserNsecSigner, { pubkey, signerType: 'ncryptsec', ncryptsec }) return login(browserNsecSigner, { pubkey, signerType: 'ncryptsec', ncryptsec })
} }
return login(browserNsecSigner, { pubkey, signerType: 'nsec', nsec }) return login(browserNsecSigner, { pubkey, signerType: 'nsec', nsec: nip19.nsecEncode(privkey) })
} }
const ncryptsecLogin = async (ncryptsec: string) => { const ncryptsecLogin = async (ncryptsec: string) => {