mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-30 00:41:12 +00:00
Use nostr tools to encode/decode bech32
This commit is contained in:
parent
360d68856a
commit
2b5dc20def
@ -49,19 +49,18 @@ If you like Coracle and want to support its development, you can donate sats via
|
||||
## Current
|
||||
|
||||
- [x] Upgrade nostr-tools
|
||||
- [ ] Publish user relays using nip 23
|
||||
- [ ] Use user relays for feeds
|
||||
- [x] Publish user relays using nip 23
|
||||
- [x] Use user relays for feeds
|
||||
- [ ] Publish to user relays + target relays:
|
||||
- If a reply or reaction, publish to the parent event's best relay, which is:
|
||||
- e tag relay
|
||||
- p tag relay
|
||||
- or pubkey's recommended relays
|
||||
- [ ] Add recommended relay to tags
|
||||
- [ ] Add correct recommended relay to tags
|
||||
- [ ] Close connections that haven't been used in a while
|
||||
- [ ] Support some read/write config on relays page
|
||||
- [ ] Get real home relays for default pubkeys
|
||||
- [ ] Add settings storage
|
||||
- [ ] Use hexToBech32 from nostr-tools
|
||||
- [ ] Warn that everything will be cleared on logout
|
||||
- [ ] Clear dexie on page load, we don't need any persistence other than people/relays
|
||||
- [ ] Clean up login page to prefer extension, make private key entry "advanced"
|
||||
|
BIN
package-lock.json
generated
BIN
package-lock.json
generated
Binary file not shown.
@ -22,8 +22,6 @@
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.2.1",
|
||||
"@noble/secp256k1": "^1.7.0",
|
||||
"bech32": "^2.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"classnames": "^2.3.2",
|
||||
"compressorjs": "^1.1.1",
|
||||
"dexie": "^3.2.2",
|
||||
|
@ -13,6 +13,7 @@
|
||||
import {timedelta, now} from 'src/util/misc'
|
||||
import {user} from 'src/agent'
|
||||
import {modal, toast, settings, alerts, getRelays} from "src/app"
|
||||
import {routes} from "src/app/ui"
|
||||
import Anchor from 'src/partials/Anchor.svelte'
|
||||
import NoteDetail from "src/views/NoteDetail.svelte"
|
||||
import PersonSettings from "src/views/PersonSettings.svelte"
|
||||
@ -92,8 +93,8 @@
|
||||
<Route path="/search/:type" component={Search} />
|
||||
<Route path="/notes/:activeTab" component={Notes} />
|
||||
<Route path="/notes/new" component={NoteCreate} />
|
||||
<Route path="/people/:pubkey/:activeTab" let:params>
|
||||
{#key params.pubkey}
|
||||
<Route path="/people/:npub/:activeTab" let:params>
|
||||
{#key params.npub}
|
||||
<Person {...params} />
|
||||
{/key}
|
||||
</Route>
|
||||
@ -113,7 +114,7 @@
|
||||
>
|
||||
{#if $user}
|
||||
<li>
|
||||
<a href={`/people/${$user.pubkey}/notes`} class="flex gap-2 px-4 py-2 pb-6 items-center">
|
||||
<a href={routes.person($user.pubkey)} class="flex gap-2 px-4 py-2 pb-6 items-center">
|
||||
<div
|
||||
class="overflow-hidden w-6 h-6 rounded-full bg-cover bg-center shrink-0 border border-solid border-white"
|
||||
style="background-image: url({$user.picture})" />
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Dexie from 'dexie'
|
||||
import {matchFilter} from 'nostr-tools'
|
||||
import {writable, get} from 'svelte/store'
|
||||
import {get} from 'svelte/store'
|
||||
import {groupBy, prop, flatten, pick} from 'ramda'
|
||||
import {ensurePlural, switcherFn} from 'hurdak/lib/hurdak'
|
||||
import {synced, now, timedelta} from 'src/util/misc'
|
||||
@ -92,7 +92,7 @@ export const processEvents = async events => {
|
||||
2: () => putPerson({relays: ($people[pubkey]?.relays || []).concat(content)}),
|
||||
3: () => putPerson({petnames: tags}),
|
||||
12165: () => putPerson({muffle: tags}),
|
||||
10001: () => putPerson({relays: tags}),
|
||||
10001: () => putPerson({relays: tags.map(t => t[0])}),
|
||||
default: () => {
|
||||
console.log(`Received unsupported event type ${event.kind}`)
|
||||
},
|
||||
|
@ -44,7 +44,9 @@ const publish = async (urls, event) => {
|
||||
urls.map(async url => {
|
||||
const relay = await connect(url)
|
||||
|
||||
return relay.publish(event)
|
||||
if (relay) {
|
||||
return relay.publish(event)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -48,8 +48,10 @@ export const login = async ({privkey, pubkey}) => {
|
||||
export const logout = async () => {
|
||||
keys.clear()
|
||||
|
||||
await db.tags.clear()
|
||||
await db.events.clear()
|
||||
await Promise.all([
|
||||
db.tags.clear(),
|
||||
db.events.clear(),
|
||||
])
|
||||
}
|
||||
|
||||
export const addRelay = async url => {
|
||||
|
@ -4,6 +4,7 @@ import {ensurePlural, createMap, ellipsize} from 'hurdak/lib/hurdak'
|
||||
import {renderContent} from 'src/util/html'
|
||||
import {filterTags, displayPerson, getTagValues, findReply, findRoot} from 'src/util/nostr'
|
||||
import {db, people, getPerson} from 'src/agent'
|
||||
import {routes} from "src/app/ui"
|
||||
|
||||
const filterEvents = async ({limit, ...filter}) => {
|
||||
let events = db.events
|
||||
@ -152,8 +153,9 @@ const renderNote = async (note, {showEntire = false}) => {
|
||||
const pubkey = note.tags[parseInt(i)][1]
|
||||
const person = peopleByPubkey[pubkey] || {pubkey}
|
||||
const name = displayPerson(person)
|
||||
const path = routes.person(pubkey)
|
||||
|
||||
return `@<a href="/people/${pubkey}/notes" class="underline">${name}</a>`
|
||||
return `@<a href="${path}" class="underline">${name}</a>`
|
||||
})
|
||||
|
||||
return content
|
||||
|
@ -1,10 +1,17 @@
|
||||
import {prop} from "ramda"
|
||||
import {uuid} from "hurdak/lib/hurdak"
|
||||
import {navigate} from "svelte-routing"
|
||||
import {nip19} from 'nostr-tools'
|
||||
import {writable, get} from "svelte/store"
|
||||
import {globalHistory} from "svelte-routing/src/history"
|
||||
import {synced} from "src/util/misc"
|
||||
|
||||
// Routing
|
||||
|
||||
export const routes = {
|
||||
person: (pubkey, tab = 'notes') => `/people/${nip19.npubEncode(pubkey)}/${tab}`,
|
||||
}
|
||||
|
||||
// Toast
|
||||
|
||||
export const toast = writable(null)
|
||||
|
@ -2,6 +2,7 @@
|
||||
import {Link} from 'svelte-routing'
|
||||
import {killEvent} from 'src/util/html'
|
||||
import {displayPerson} from 'src/util/nostr'
|
||||
import {routes} from 'src/app/ui'
|
||||
|
||||
export let person
|
||||
export let inert = false
|
||||
@ -16,7 +17,7 @@
|
||||
</span>
|
||||
{:else}
|
||||
<Link
|
||||
to={`/people/${person.pubkey}/notes`}
|
||||
to={routes.person(person.pubkey)}
|
||||
class="flex gap-2 items-center relative z-10"
|
||||
on:click={killEvent}>
|
||||
<div
|
||||
|
@ -1,14 +1,12 @@
|
||||
<script>
|
||||
import {propEq, identity, uniq, uniqBy, prop, sortBy} from 'ramda'
|
||||
import {propEq, identity, uniq, prop, sortBy} from 'ramda'
|
||||
import {onMount} from 'svelte'
|
||||
import {fly} from 'svelte/transition'
|
||||
import {createMap} from 'hurdak/lib/hurdak'
|
||||
import {now, createScroller, timedelta} from 'src/util/misc'
|
||||
import {findReply, isLike} from 'src/util/nostr'
|
||||
import {now, createScroller} from 'src/util/misc'
|
||||
import {getPerson, user, db} from 'src/agent'
|
||||
import {alerts} from 'src/app'
|
||||
import query from 'src/app/query'
|
||||
import Spinner from "src/partials/Spinner.svelte"
|
||||
import Note from 'src/partials/Note.svelte'
|
||||
import Like from 'src/partials/Like.svelte'
|
||||
|
||||
@ -53,7 +51,7 @@
|
||||
annotatedNotes = sortBy(
|
||||
e => -e.created_at,
|
||||
notes
|
||||
.filter(e => e.pubkey !== $user.pubkey)
|
||||
.filter(e => e && e.pubkey !== $user.pubkey)
|
||||
.concat(Object.values(likesById))
|
||||
).slice(0, limit)
|
||||
})
|
||||
|
@ -2,8 +2,8 @@
|
||||
import {onMount} from "svelte"
|
||||
import {fly} from 'svelte/transition'
|
||||
import {navigate} from "svelte-routing"
|
||||
import {nip19} from 'nostr-tools'
|
||||
import {copyToClipboard} from "src/util/html"
|
||||
import {hexToBech32} from "src/util/misc"
|
||||
import Input from "src/partials/Input.svelte"
|
||||
import Anchor from "src/partials/Anchor.svelte"
|
||||
import {user} from "src/agent"
|
||||
@ -13,10 +13,11 @@
|
||||
const delegationUrl = 'https://github.com/nostr-protocol/nips/blob/b62aa418dee13aac1899ea7c6946a0f55dd7ee84/26.md'
|
||||
|
||||
const copyKey = type => {
|
||||
const prefix = type === 'private' ? 'nsec' : 'npub'
|
||||
const hex = type === 'private' ? $user.privkey : $user.pubkey
|
||||
|
||||
copyToClipboard(hexToBech32(prefix, hex))
|
||||
copyToClipboard(
|
||||
type === 'private'
|
||||
? nip19.nsecEncode($user.privkey)
|
||||
: nip19.npubEncode($user.pubkey)
|
||||
)
|
||||
|
||||
toast.show("info", `Your ${type} key has been copied to the clipboard.`)
|
||||
}
|
||||
@ -41,7 +42,7 @@
|
||||
<div class="flex flex-col gap-8 w-full">
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>Public Key</strong>
|
||||
<Input disabled value={$user ? hexToBech32('npub', $user.pubkey) : ''}>
|
||||
<Input disabled value={$user ? nip19.npubEncode($user.pubkey) : ''}>
|
||||
<i slot="after" class="fa-solid fa-copy cursor-pointer" on:click={() => copyKey('public')} />
|
||||
</Input>
|
||||
<p class="text-sm text-light">
|
||||
@ -52,7 +53,7 @@
|
||||
{#if $user?.privkey}
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>Private Key</strong>
|
||||
<Input disabled type="password" value={hexToBech32('nsec', $user.privkey)}>
|
||||
<Input disabled type="password" value={nip19.nsecEncode($user.privkey)}>
|
||||
<i slot="after" class="fa-solid fa-copy cursor-pointer" on:click={() => copyKey('private')} />
|
||||
</Input>
|
||||
<p class="text-sm text-light">
|
||||
|
@ -3,7 +3,7 @@
|
||||
import {fade, fly} from 'svelte/transition'
|
||||
import {navigate} from 'svelte-routing'
|
||||
import {generatePrivateKey, getPublicKey} from 'nostr-tools'
|
||||
import {hexToBech32, bech32ToHex} from "src/util/misc"
|
||||
import {nip19} from 'nostr-tools'
|
||||
import {copyToClipboard} from "src/util/html"
|
||||
import Anchor from "src/partials/Anchor.svelte"
|
||||
import Input from "src/partials/Input.svelte"
|
||||
@ -27,7 +27,7 @@
|
||||
}
|
||||
|
||||
const generateKey = () => {
|
||||
nsec = hexToBech32('nsec', generatePrivateKey())
|
||||
nsec = nip19.nsecEncode(generatePrivateKey())
|
||||
toast.show("info", "Your private key has been re-generated.")
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
}
|
||||
|
||||
const logInWithPrivateKey = async () => {
|
||||
const privkey = nsec.startsWith('nsec') ? bech32ToHex(nsec) : nsec
|
||||
const privkey = nsec.startsWith('nsec') ? nip19.decode(nsec).data : nsec
|
||||
|
||||
if (!privkey.match(/[a-z0-9]{64}/)) {
|
||||
toast.show("error", "Sorry, but that's an invalid private key.")
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script>
|
||||
import {find, propEq} from 'ramda'
|
||||
import {onMount, onDestroy} from 'svelte'
|
||||
import {nip19} from 'nostr-tools'
|
||||
import {fly} from 'svelte/transition'
|
||||
import {navigate} from 'svelte-routing'
|
||||
import {now, batch} from 'src/util/misc'
|
||||
@ -14,12 +15,14 @@
|
||||
import {getPerson, listen, user} from "src/agent"
|
||||
import {modal, getRelays} from "src/app"
|
||||
import loaders from "src/app/loaders"
|
||||
import {routes} from "src/app/ui"
|
||||
import cmd from "src/app/cmd"
|
||||
|
||||
export let pubkey
|
||||
export let npub
|
||||
export let activeTab
|
||||
|
||||
let subs = []
|
||||
let pubkey = nip19.decode(npub).data
|
||||
let following = find(t => t[1] === pubkey, $user?.petnames || [])
|
||||
let followers = new Set()
|
||||
let followersCount = 0
|
||||
@ -61,7 +64,7 @@
|
||||
}
|
||||
})
|
||||
|
||||
const setActiveTab = tab => navigate(`/people/${pubkey}/${tab}`)
|
||||
const setActiveTab = tab => navigate(routes.person(pubkey, tab))
|
||||
|
||||
const follow = async () => {
|
||||
following = true
|
||||
|
@ -10,6 +10,7 @@
|
||||
import Button from "src/partials/Button.svelte"
|
||||
import {user} from "src/agent"
|
||||
import {toast} from "src/app"
|
||||
import {routes} from "src/app/ui"
|
||||
import cmd from "src/app/cmd"
|
||||
|
||||
let values = {picture: null, about: null, name: null}
|
||||
@ -40,7 +41,7 @@
|
||||
|
||||
await cmd.updateUser(values)
|
||||
|
||||
navigate(`/people/${$user.pubkey}/profile`)
|
||||
navigate(routes.person($user.pubkey, 'profile'))
|
||||
|
||||
toast.show("info", "Your profile has been updated!")
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
import LZ from 'lz-string'
|
||||
import {Buffer} from 'buffer'
|
||||
import {bech32} from 'bech32'
|
||||
import {debounce} from 'throttle-debounce'
|
||||
import {pluck, sortBy} from "ramda"
|
||||
import Fuse from "fuse.js/dist/fuse.min.js"
|
||||
@ -145,14 +143,6 @@ export class Cursor {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const hexToBech32 = (prefix, hex) =>
|
||||
bech32.encode(prefix, bech32.toWords(Buffer.from(hex, 'hex')))
|
||||
|
||||
export const bech32ToHex = b32 =>
|
||||
Buffer.from(bech32.fromWords(bech32.decode(b32).words)).toString('hex')
|
||||
|
||||
|
||||
export const synced = (key, defaultValue = null) => {
|
||||
// If it's an object, merge defaults
|
||||
const store = writable(
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {last, find, intersection} from 'ramda'
|
||||
import {nip19} from 'nostr-tools'
|
||||
import {ensurePlural, first} from 'hurdak/lib/hurdak'
|
||||
import {hexToBech32} from 'src/util/misc'
|
||||
|
||||
export const epoch = 1633046400
|
||||
|
||||
@ -55,7 +55,7 @@ export const displayPerson = p => {
|
||||
return p.name
|
||||
}
|
||||
|
||||
return hexToBech32('npub', p.pubkey).slice(4, 12)
|
||||
return nip19.npubEncode(p.pubkey).slice(4, 12)
|
||||
}
|
||||
|
||||
export const isLike = content => ['', '+', '🤙', '👍', '❤️'].includes(content)
|
||||
|
@ -6,6 +6,7 @@
|
||||
import {renderContent} from "src/util/html"
|
||||
import {displayPerson} from "src/util/nostr"
|
||||
import {user, people} from 'src/agent'
|
||||
import {routes} from "src/app/ui"
|
||||
|
||||
export let q
|
||||
|
||||
@ -19,7 +20,7 @@
|
||||
{#each search(q).slice(0, 30) as p (p.pubkey)}
|
||||
{#if p.pubkey !== $user.pubkey}
|
||||
<li in:fly={{y: 20}}>
|
||||
<a href="/people/{p.pubkey}/notes" class="flex gap-4 my-4">
|
||||
<a href={routes.person(p.pubkey)} class="flex gap-4 my-4">
|
||||
<div
|
||||
class="overflow-hidden w-12 h-12 rounded-full bg-cover bg-center shrink-0 border border-solid border-white"
|
||||
style="background-image: url({p.picture})" />
|
||||
|
Loading…
Reference in New Issue
Block a user