36 lines
1.8 KiB
TypeScript
36 lines
1.8 KiB
TypeScript
import { Nip59, Nip01Signer } from "@welshman/signer"
|
|
import { signer, repository, publishThunk, getMessagingRelayList } from "@welshman/app"
|
|
import { getRelaysFromList } from "@welshman/util"
|
|
import type { HashedEvent } from "@welshman/util"
|
|
import { Router } from "@welshman/router"
|
|
|
|
const TOPIC = "b7ed"
|
|
|
|
// TODO: PROTOCOL.md §Event Kinds requires at least 16 bits of proof-of-work (NIP-13)
|
|
// on each kind 1059 gift wrap. PoW is out of scope for this pass; the ["t","b7ed"]
|
|
// topic tag below IS required and is always present.
|
|
|
|
function inboxRelays(pubkey: string): string[] {
|
|
const relays = getRelaysFromList(getMessagingRelayList(pubkey))
|
|
return relays.length ? relays : Router.get().ForPubkey(pubkey).getUrls()
|
|
}
|
|
|
|
/** Gift-wrap a rumor to one recipient (with the b7ed topic tag) and publish to their inbox relays. */
|
|
export async function deliverTo(recipient: string, rumor: HashedEvent): Promise<void> {
|
|
const $signer = signer.get()
|
|
if (!$signer) { throw new Error("Cannot send without a signer") }
|
|
const nip59 = new Nip59($signer, Nip01Signer.ephemeral())
|
|
const wrap = await nip59.wrap(recipient, rumor, [["t", TOPIC]])
|
|
publishThunk({ event: wrap, relays: inboxRelays(recipient) })
|
|
}
|
|
|
|
/**
|
|
* Broadcast one rumor to many recipients. Stores a local copy in the repository (so our own derived
|
|
* state reflects what we sent) unless storeLocal is false. Per-recipient payloads (round-2 shares) call
|
|
* deliverTo directly with storeLocal handled by the caller. Recipients should EXCLUDE self.
|
|
*/
|
|
export async function sendProtocolEvent(rumor: HashedEvent, recipients: string[], opts: { storeLocal?: boolean } = {}): Promise<void> {
|
|
if (opts.storeLocal !== false) { repository.publish(rumor) }
|
|
await Promise.all(recipients.map(r => deliverTo(r, rumor).catch(e => console.error("deliver failed", r, e))))
|
|
}
|