Add docs for blossom, add nip 86 and 98 support
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import {Base64} from "js-base64"
|
||||
import {now, bytesToHex, hexToBytes} from "@welshman/lib"
|
||||
import {BLOSSOM_AUTH} from "./Kinds.js"
|
||||
import {makeEvent, SignedEvent} from "./Events.js"
|
||||
import {makeHttpAuthHeader} from "./Nip98.js"
|
||||
|
||||
export type BlossomAuthAction = "get" | "upload" | "list" | "delete"
|
||||
|
||||
@@ -48,10 +48,6 @@ export const makeBlossomAuthEvent = ({
|
||||
return makeEvent(BLOSSOM_AUTH, {content, tags})
|
||||
}
|
||||
|
||||
export const createAuthorizationHeader = (event: SignedEvent): string => {
|
||||
return `Nostr ${Base64.encode(JSON.stringify(event))}`
|
||||
}
|
||||
|
||||
export const buildBlobUrl = (server: string, sha256: string, extension?: string): string => {
|
||||
const url = new URL(server)
|
||||
const filename = extension ? `${sha256}.${extension}` : sha256
|
||||
@@ -69,7 +65,7 @@ export const checkBlobExists = async (
|
||||
const headers: Record<string, string> = {}
|
||||
|
||||
if (options.authEvent) {
|
||||
headers.Authorization = createAuthorizationHeader(options.authEvent)
|
||||
headers.Authorization = makeHttpAuthHeader(options.authEvent)
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -101,7 +97,7 @@ export const getBlob = async (
|
||||
const headers: Record<string, string> = {}
|
||||
|
||||
if (options.authEvent) {
|
||||
headers.Authorization = createAuthorizationHeader(options.authEvent)
|
||||
headers.Authorization = makeHttpAuthHeader(options.authEvent)
|
||||
}
|
||||
|
||||
if (options.range) {
|
||||
@@ -126,7 +122,7 @@ export const uploadBlob = async (
|
||||
const headers: Record<string, string> = {}
|
||||
|
||||
if (options.authEvent) {
|
||||
headers.Authorization = createAuthorizationHeader(options.authEvent)
|
||||
headers.Authorization = makeHttpAuthHeader(options.authEvent)
|
||||
}
|
||||
|
||||
return fetch(uploadUrl, {method: "PUT", headers, body})
|
||||
@@ -144,7 +140,7 @@ export const deleteBlob = async (
|
||||
const headers: Record<string, string> = {}
|
||||
|
||||
if (options.authEvent) {
|
||||
headers.Authorization = createAuthorizationHeader(options.authEvent)
|
||||
headers.Authorization = makeHttpAuthHeader(options.authEvent)
|
||||
}
|
||||
|
||||
return fetch(url, {method: "DELETE", headers})
|
||||
@@ -175,7 +171,7 @@ export const listBlobs = async (
|
||||
const headers: Record<string, string> = {}
|
||||
|
||||
if (options.authEvent) {
|
||||
headers.Authorization = createAuthorizationHeader(options.authEvent)
|
||||
headers.Authorization = makeHttpAuthHeader(options.authEvent)
|
||||
}
|
||||
|
||||
return fetch(fullUrl, {headers})
|
||||
|
||||
@@ -54,12 +54,14 @@ export type MakeEventOpts = {
|
||||
created_at?: number
|
||||
}
|
||||
|
||||
// Event template creation
|
||||
|
||||
export const makeEvent = (
|
||||
kind: number,
|
||||
{content = "", tags = [], created_at = now()}: MakeEventOpts = {},
|
||||
) => ({kind, content, tags, created_at})
|
||||
|
||||
export const createEvent = makeEvent
|
||||
// Event signature verification
|
||||
|
||||
export const verifyEvent = (() => {
|
||||
let verify = verifyEventPure
|
||||
@@ -80,6 +82,8 @@ export const verifyEvent = (() => {
|
||||
Boolean(event.sig && (event[verifiedSymbol] || verify(event as SignedEvent)))
|
||||
})()
|
||||
|
||||
// Type guards
|
||||
|
||||
export const isEventTemplate = (e: EventTemplate): e is EventTemplate =>
|
||||
Boolean(typeof e.kind === "number" && Array.isArray(e.tags) && typeof e.content === "string")
|
||||
|
||||
@@ -100,6 +104,8 @@ export const isUnwrappedEvent = (e: TrustedEvent): e is UnwrappedEvent =>
|
||||
export const isTrustedEvent = (e: TrustedEvent): e is TrustedEvent =>
|
||||
isSignedEvent(e) || isUnwrappedEvent(e)
|
||||
|
||||
// Type coercion and attribute stripping
|
||||
|
||||
export const asEventTemplate = (e: EventTemplate): EventTemplate =>
|
||||
pick(["kind", "tags", "content"], e)
|
||||
|
||||
@@ -121,6 +127,8 @@ export const asUnwrappedEvent = (e: UnwrappedEvent): UnwrappedEvent =>
|
||||
export const asTrustedEvent = (e: TrustedEvent): TrustedEvent =>
|
||||
pick(["kind", "tags", "content", "created_at", "pubkey", "id", "sig", "wrap"], e)
|
||||
|
||||
// Utilities for working with events
|
||||
|
||||
export const getIdentifier = (e: EventTemplate) => e.tags.find(t => t[0] === "d")?.[1]
|
||||
|
||||
export const getIdOrAddress = (e: HashedEvent) => (isReplaceable(e) ? getAddress(e) : e.id)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import {postJson} from "@welshman/lib"
|
||||
import {SignedEvent} from "./Events.js"
|
||||
import {makeHttpAuthHeader} from "./Nip98.js"
|
||||
|
||||
export enum ManagementMethod {
|
||||
SupportedMethods = "supportedmethods",
|
||||
BanPubkey = "banpubkey",
|
||||
AllowPubkey = "allowpubkey",
|
||||
ListBannedPubkeys = "listbannedpubkeys",
|
||||
ListAllowedPubkeys = "listallowedpubkeys",
|
||||
ListEventsNeedingModeration = "listeventsneedingmoderation",
|
||||
AllowEvent = "allowevent",
|
||||
BanEvent = "banevent",
|
||||
ListBannedEvents = "listbannedevents",
|
||||
ChangeRelayName = "changerelayname",
|
||||
ChangeRelayDescription = "changerelaydescription",
|
||||
ChangeRelayIcon = "changerelayicon",
|
||||
AllowKind = "allowkind",
|
||||
DisallowKind = "disallowkind",
|
||||
ListAllowedKinds = "listallowedkinds",
|
||||
BlockIp = "blockip",
|
||||
UnblockIp = "unblockip",
|
||||
ListBlockedIps = "listblockedips",
|
||||
}
|
||||
|
||||
export type ManagementRequest = {
|
||||
method: ManagementMethod
|
||||
params: string[]
|
||||
}
|
||||
|
||||
export const sendManagementRequest = (
|
||||
url: string,
|
||||
request: ManagementRequest,
|
||||
authEvent: SignedEvent,
|
||||
) =>
|
||||
postJson(url, request, {
|
||||
headers: {
|
||||
"Content-Type": "application/nostr+json+rpc",
|
||||
Authorization: makeHttpAuthHeader(authEvent),
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,20 @@
|
||||
import {Base64} from "js-base64"
|
||||
import {sha256, textEncoder} from "@welshman/lib"
|
||||
import {makeEvent, SignedEvent} from "./Events.js"
|
||||
import {HTTP_AUTH} from "./Kinds.js"
|
||||
|
||||
export const makeHttpAuth = async (url: string, method = "GET", body?: string) => {
|
||||
const tags = [
|
||||
["u", url],
|
||||
["method", method],
|
||||
]
|
||||
|
||||
if (body) {
|
||||
tags.push(["payload", await sha256(textEncoder.encode(body))])
|
||||
}
|
||||
|
||||
return makeEvent(HTTP_AUTH, {tags})
|
||||
}
|
||||
|
||||
export const makeHttpAuthHeader = (event: SignedEvent) =>
|
||||
`Nostr ${Base64.encode(JSON.stringify(event))}`
|
||||
@@ -7,6 +7,8 @@ export * from "./Handler.js"
|
||||
export * from "./Kinds.js"
|
||||
export * from "./Links.js"
|
||||
export * from "./List.js"
|
||||
export * from "./Nip86.js"
|
||||
export * from "./Nip98.js"
|
||||
export * from "./Profile.js"
|
||||
export * from "./Relay.js"
|
||||
export * from "./Tags.js"
|
||||
|
||||
Reference in New Issue
Block a user