diff options
| author | Adam Soltys <[email protected]> | 2025-01-09 23:44:40 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2025-01-09 23:44:40 -0800 |
| commit | 8588de25f16486b56ef0ad533013bd8cb48ff120 (patch) | |
| tree | 4c1e39704e2edb332c5fe8c58fb0d81c8154af2b /src/lib/nostr.ts | |
| parent | 2358d1bf39c34a508db6c50f0f6312ee411a8a17 (diff) | |
| download | coinos-ui-8588de25f16486b56ef0ad533013bd8cb48ff120.tar.gz coinos-ui-8588de25f16486b56ef0ad533013bd8cb48ff120.zip | |
nostr signing
Diffstat (limited to 'src/lib/nostr.ts')
| -rw-r--r-- | src/lib/nostr.ts | 95 |
1 files changed, 79 insertions, 16 deletions
diff --git a/src/lib/nostr.ts b/src/lib/nostr.ts index 77c1d60a..85f1bdaa 100644 --- a/src/lib/nostr.ts +++ b/src/lib/nostr.ts @@ -2,18 +2,21 @@ import { Buffer } from "buffer"; import { browser } from "$app/environment"; import { decrypted, + eventToSign, password as pw, passwordPrompt, - signaturePrompt, + signer as $signer, } from "$lib/store"; import { post, wait } from "$lib/utils"; import { type EventTemplate, finalizeEvent, + getEventHash, getPublicKey, nip04, nip19, } from "nostr-tools"; +import { Relay } from "nostr-tools/relay"; import { get } from "svelte/store"; import { @@ -21,8 +24,6 @@ import { encrypt as nip49encrypt, } from "nostr-tools/nip49"; -import { bech32m } from "@scure/base"; - type User = { [key: string]: any; }; @@ -101,19 +102,17 @@ export const encryptNsec = async (nsec: string) => { return nip49encrypt(d, await getPassword()); }; -type SignParams = { - event: EventTemplate; - user: User; -}; - -export const sign = async ({ event, user }: SignParams) => { - let sk; - if (user.nsec) { - sk = await getPrivateKey(user); - event = finalizeEvent(event, sk); - } else { - signaturePrompt.set(event); - } +export const sign = async (event) => { + eventToSign.set(event); + let unsubscribe; + const { method, params } = await new Promise((r) => { + unsubscribe = $signer.subscribe((v) => v?.ready && r(v)); + }); + await unsubscribe(); + const signedEvent = await signingMethods[method](event, params); + eventToSign.set(signedEvent); + setTimeout(() => eventToSign.set(null), 1000); + return signedEvent; }; export const send = (event: EventTemplate) => { @@ -125,3 +124,67 @@ const getPassword = async (): Promise<string> => { await wait(() => !!get(pw)); return get(pw) || ""; }; + +export const nostrConnectRelay = "wss://relay.nsec.app"; + +const signingMethods = { + async connect(event, { sk, pk, pubkey }) { + const id = crypto.randomUUID(); + const signEvent = { + id, + method: "sign_event", + params: [JSON.stringify(event)], + }; + + const content = await nip04.encrypt(sk, pk, JSON.stringify(signEvent)); + + const signedSignEvent = finalizeEvent( + { + created_at: Math.round(Date.now() / 1000), + kind: 24133, + pubkey, + content, + tags: [["p", pk]], + }, + sk, + ); + + const relay = await Relay.connect(nostrConnectRelay); + relay.publish(signedSignEvent); + + return new Promise((resolve) => { + relay.subscribe([{ kinds: [24133], "#p": [pubkey] }], { + async onevent(event) { + pk = event.pubkey; + try { + const response = JSON.parse( + await nip04.decrypt(sk, pk, event.content), + ); + + if (response.id === id) resolve(JSON.parse(response.result)); + } catch (e) { + console.log("failed to parse nostr connect event", e); + } + }, + }); + }); + }, + + async nsec(event, { sk }) { + return finalizeEvent(event, sk); + }, + + async extension(event) { + return window.nostr.signEvent(event); + }, + + async signer(event, { pubkey, sig }) { + event.pubkey = pubkey; + const signedEvent = { + ...event, + id: getEventHash(event), + sig, + }; + return signedEvent; + }, +}; |
