nostr-tools/nip11.ts

287 lines
9.7 KiB
TypeScript

var _fetch: any
try {
_fetch = fetch
} catch {}
export function useFetchImplementation(fetchImplementation: any): void {
_fetch = fetchImplementation
}
export async function fetchRelayInformation(url: string): Promise<RelayInformation> {
return (await (
await fetch(url.replace('ws://', 'http://').replace('wss://', 'https://'), {
headers: { Accept: 'application/nostr+json' },
})
).json()) as RelayInformation
}
/**
* ## Relay Information Document
* Relays may provide server metadata to clients to inform
* them of capabilities, administrative contacts, and
* various server attributes. This is made available as a
* JSON document over HTTP, on the same URI as the relay's
* websocket.
* Any field may be omitted, and clients MUST ignore any
* additional fields they do not understand. Relays MUST
* accept CORS requests by sending
* `Access-Control-Allow-Origin`,
* `Access-Control-Allow-Headers`, and
* `Access-Control-Allow-Methods` headers.
* @param name string identifying relay
* @param description string with detailed information
* @param pubkey administrative contact pubkey
* @param contact: administrative alternate contact
* @param supported_nips a list of NIP numbers supported by
* the relay
* @param software identifying relay software URL
* @param version string version identifier
*/
export interface BasicRelayInformation {
// string identifying relay
name: string
description: string
pubkey: string
contact: string
supported_nips: number[]
software: string
version: string
// limitation?: Limitations<A, P>
}
/**
* * ## Extra Fields
* * ### Server Limitations
* These are limitations imposed by the relay on clients.
* Your client should expect that requests which exceed
* these practical_ limitations are rejected or fail immediately.
* @param max_message_length this is the maximum number of
* bytes for incoming JSON that the relay will attempt to
* decode and act upon. When you send large subscriptions,
* you will be limited by this value. It also effectively
* limits the maximum size of any event. Value is calculated
* from `[` to `]` and is after UTF-8 serialization (so some
* unicode characters will cost 2-3 bytes). It is equal to
* the maximum size of the WebSocket message frame.
* @param max_subscription total number of subscriptions
* that may be active on a single websocket connection to
* this relay. It's possible that authenticated clients with
* a (paid) relationship to the relay may have higher limits.
* @param max_filters maximum number of filter values in
* each subscription. Must be one or higher.
* @param max_limit the relay server will clamp each
* filter's `limit` value to this number.
* This means the client won't be able to get more than this
* number of events from a single subscription filter. This
* clamping is typically done silently by the relay, but
* with this number, you can know that there are additional
* results if you narrowed your filter's time range or other
* parameters.
* @param max_subid_length maximum length of subscription id as a
* string.
* @param min_prefix for `authors` and `ids` filters which
* are to match against a hex prefix, you must provide at
* least this many hex digits in the prefix.
* @param max_event_tags in any event, this is the maximum
* number of elements in the `tags` list.
* @param max_content_length maximum number of characters in
* the `content` field of any event. This is a count of
* unicode characters. After serializing into JSON it may be
* larger (in bytes), and is still subject to the
* max_message_length`, if defined.
* @param min_pow_difficulty new events will require at
* least this difficulty of PoW, based on [NIP-13](13.md),
* or they will be rejected by this server.
* @param auth_required this relay requires [NIP-42](42.md)
* authentication to happen before a new connection may
* perform any other action. Even if set to False,
* authentication may be required for specific actions.
* @param payment_required this relay requires payment
* before a new connection may perform any action.
*/
export interface Limitations {
max_message_length: number
max_subscription: number
max_filters: number
max_limit: number
max_subid_length: number
min_prefix: number
max_event_tags: number
max_content_length: number
min_pow_difficulty: number
auth_required: boolean
payment_required: boolean
}
interface RetentionDetails {
kinds: (number | number[])[]
time?: number | null
count?: number | null
}
type AnyRetentionDetails = RetentionDetails
/**
* ### Event Retention
* There may be a cost associated with storing data forever,
* so relays may wish to state retention times. The values
* stated here are defaults for unauthenticated users and
* visitors. Paid users would likely have other policies.
* Retention times are given in seconds, with `null`
* indicating infinity. If zero is provided, this means the
* event will not be stored at all, and preferably an error
* will be provided when those are received.
* ```json
{
...
"retention": [
{ "kinds": [0, 1, [5, 7], [40, 49]], "time": 3600 },
{ "kinds": [[40000, 49999]], "time": 100 },
{ "kinds": [[30000, 39999]], "count": 1000 },
{ "time": 3600, "count": 10000 }
]
...
}
```
* @param retention is a list of specifications: each will
* apply to either all kinds, or a subset of kinds. Ranges
* may be specified for the kind field as a tuple of
* inclusive start and end values. Events of indicated kind
* (or all) are then limited to a `count` and/or time
* period.
* It is possible to effectively blacklist Nostr-based
* protocols that rely on a specific `kind` number, by
* giving a retention time of zero for those `kind` values.
* While that is unfortunate, it does allow clients to
* discover servers that will support their protocol quickly
* via a single HTTP fetch.
* There is no need to specify retention times for
* _ephemeral events_ as defined in [NIP-16](16.md) since
* they are not retained.
*/
export interface Retention {
retention: AnyRetentionDetails[]
}
/**
* Some relays may be governed by the arbitrary laws of a
* nation state. This may limit what content can be stored
* in cleartext on those relays. All clients are encouraged
* to use encryption to work around this limitation.
* It is not possible to describe the limitations of each
* country's laws and policies which themselves are
* typically vague and constantly shifting.
* Therefore, this field allows the relay operator to
* indicate which countries' laws might end up being
* enforced on them, and then indirectly on their users'
* content.
* Users should be able to avoid relays in countries they
* don't like, and/or select relays in more favourable
* zones. Exposing this flexibility is up to the client
* software.
* @param relay_countries a list of two-level ISO country
* codes (ISO 3166-1 alpha-2) whose laws and policies may
* affect this relay. `EU` may be used for European Union
* countries.
* Remember that a relay may be hosted in a country which is
* not the country of the legal entities who own the relay,
* so it's very likely a number of countries are involved.
*/
export interface ContentLimitations {
relay_countries: string[]
}
/**
* ### Community Preferences
* For public text notes at least, a relay may try to foster
* a local community. This would encourage users to follow
* the global feed on that relay, in addition to their usual
* individual follows. To support this goal, relays MAY
* specify some of the following values.
* @param language_tags is an ordered list of [IETF
* language
* tags](https://en.wikipedia.org/wiki/IETF_language_tag
* indicating the major languages spoken on the relay.
* @param tags is a list of limitations on the topics to be
* discussed. For example `sfw-only` indicates that only
* "Safe For Work" content is encouraged on this relay. This
* relies on assumptions of what the "work" "community"
* feels "safe" talking about. In time, a common set of tags
* may emerge that allow users to find relays that suit
* their needs, and client software will be able to parse
* these tags easily. The `bitcoin-only` tag indicates that
* any _altcoin_, _"crypto"_ or _blockchain_ comments will
* be ridiculed without mercy.
* @param posting_policy is a link to a human-readable page
* which specifies the community policies for the relay. In
* cases where `sfw-only` is True, it's important to link to
* a page which gets into the specifics of your posting
* policy.
* The `description` field should be used to describe your
* community goals and values, in brief. The
* `posting_policy` is for additional detail and legal
* terms. Use the `tags` field to signify limitations on
* content, or topics to be discussed, which could be
* machine processed by appropriate client software.
*/
export interface CommunityPreferences {
language_tags: string[]
tags: string[]
posting_policy: string
}
export interface Amount {
amount: number
unit: 'msat'
}
export interface PublicationAmount extends Amount {
kinds: number[]
}
export interface Subscription extends Amount {
period: number
}
export interface Fees {
admission: Amount[]
subscription: Subscription[]
publication: PublicationAmount[]
}
/**
* Relays that require payments may want to expose their fee
* schedules.
*/
export interface PayToRelay {
payments_url: string
fees: Fees
}
/**
* A URL pointing to an image to be used as an icon for the
* relay. Recommended to be squared in shape.
*/
export interface Icon {
icon: string
}
export type RelayInformation = BasicRelayInformation &
Partial<Retention> & {
limitation?: Partial<Limitations>
} & Partial<ContentLimitations> &
Partial<CommunityPreferences> &
Partial<PayToRelay> &
Partial<Icon>