From f30be7e8451f8dac8ac1fcd5e40dff01aba37668 Mon Sep 17 00:00:00 2001 From: KotlinGeekDev Date: Tue, 5 Aug 2025 15:44:12 +0100 Subject: [PATCH] Add documentation(KDocs) for relay-related code. --- .../kotlin/rhodium/nostr/relay/Relay.kt | 91 ++++++++++++++++++- .../kotlin/rhodium/nostr/relay/RelayPool.kt | 33 +++++++ .../rhodium/nostr/relay/info/Payments.kt | 23 +++++ .../rhodium/nostr/relay/info/Preferences.kt | 31 +++++++ .../rhodium/nostr/relay/info/RelayLimits.kt | 21 +++++ .../nostr/relay/info/RetentionPolicy.kt | 13 +++ 6 files changed, 209 insertions(+), 3 deletions(-) create mode 100644 rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/Preferences.kt diff --git a/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/Relay.kt b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/Relay.kt index bc953b7..43de70d 100644 --- a/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/Relay.kt +++ b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/Relay.kt @@ -38,6 +38,19 @@ import rhodium.nostr.relay.info.Payments import rhodium.nostr.relay.info.RelayLimits import rhodium.nostr.relay.info.RetentionPolicy +/** + * Represents a Nostr relay, including it's read/write policies. + * When creating you can use the `Relay(...)` constructor, or use + * [fromUrl], and just pass in the relay address. + * + * The read/write policies are set to true by default. + * + * @constructor Relay(String, Boolean, Boolean) + * + * @property relayURI - The relay's address, as a String + * @property readPolicy - The relay's read status(whether a relay accepts reads from it), as a Boolean. + * @property writePolicy - The relay's write status(whether a relay accepts writes to it), as a Boolean. + */ class Relay( val relayURI: String, val readPolicy: Boolean = true, @@ -48,7 +61,21 @@ class Relay( return Relay(address) } - suspend fun fetchInfoFor(relayUrl: String, httpClient: HttpClient = httpClient()): Info { + /** + * Fetches information about a relay, per [NIP-11](https://github.com/nostr-protocol/nips/blob/master/11.md), + * and returns the information as an [Info] object. + * + * @param relayUrl - The relay URL/URI, as a String + * @param httpClient - (Optional) A custom HTTP client that can be used for fetching the info, + * particularly for a project using a particular client. + * By default, the library's own [client][rhodium.net.httpClient] is used. + * + * @return Relay information, as an [Info] object. + */ + suspend fun fetchInfoFor( + relayUrl: String, + httpClient: HttpClient = httpClient() + ): Info { val raw = relayUrl.removePrefix("wss://").removePrefix("ws://") val actualUrl = "https://$raw" val relayInfoResponse = httpClient.get(actualUrl) { @@ -61,17 +88,75 @@ class Relay( else throw RelayInfoFetchError("Could not fetch relay info with reason: ${relayInfoResponse.bodyAsText()}") } - fun infoFromJson(relayInfoJson: String): Info { + /** + * Transforms already obtained relay info in JSON form, + * and returns it as an `Info` object. + * + * @param relayInfoJson - The relay info, in JSON format. + * + * @return Relay information, stored as an [Info] object. + */ + fun infoFromJson( + relayInfoJson: String + ): Info { val relayInfo = eventMapper.decodeFromString(relayInfoJson) return relayInfo } + + /** + * Does the exact opposite of [infoFromJson], + * taking relay information stored in an `Info` object, and returns it in JSON format. + * + * @param relayInfo - The relay's information, as an `Info` object + * + * @return A JSON formatted `String` representation of the relay info. + */ + fun infoToJson( + relayInfo: Info + ): String { + val relayInfoJson = eventMapper.encodeToString(relayInfo) + return relayInfoJson + } } override fun toString(): String { return "Relay(url=$relayURI, read=$readPolicy, write=$writePolicy)" } - //Docs: Write something useful about Relay Info + /** + * Represents a relay's information, + * provided as per [NIP-11](https://github.com/nostr-protocol/nips/blob/master/11.md). + * The elements required for a relay's details are its name, description, banner, icon, + * pubkey, and contact. The other properties are optional. + * + * By default, an `Info` object is "empty". + * + * @property name - The relay's name + * @property description - A description of the relay + * @property banner - A banner for the relay, similar to a user profile's banner. + * @property icon - An icon for the relay, similar to a user's profile picture. + * @property pubkey - The Nostr pubkey of the relay's administrator. + * @property contact - An alternative contact for the relay administrator. + * @property supportedNips - (Optional) A list of Nostr specs(NIPs) supported by the relay. + * @property relaySoftware - (Optional) The name of the underlying relay implementation used by this relay. + * @property softwareVersion - (Optional) The version of the relay implementation currently in use by the relay. + * @property privacyPolicy - (Optional) The privacy policy for this relay. + * @property termsOfService - (Optional) The relay's terms of service. + * @property limits - (Optional) A set of limits imposed by the relay, as a [RelayLimits] object. + * @property retentionPolicies - (Optional) A set of data retention policies provided by the relay. + * A retention policy is stored as a [RetentionPolicy] object. + * @see RetentionPolicy + * + * @property relayRegionHosts - (Optional) Countries, regions, whose policies might affect the relay's hosted content. + * @property allowedLanguages - (Optional) A relay's preference concerning the language of content to be published to it. + * @property allowedTopics - (Optional) A set of allowed topics for discussion on this relay. + * @property postingPolicy - (Optional) The relay's posting policy; a set of guidelines on content + * to be published to the relay. + * @property paymentUrl - (Optional) Indicates where you should pay the relay operator. + * Usually for paid relays, or paid tiers on mixed relays. + * @property paymentInfo - (Optional) Contains info on payments to make: what to pay for, how to pay, how much to pay, etc. + * The information is stored as a [Payments] object. + */ @Serializable data class Info( val name: String = "", diff --git a/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/RelayPool.kt b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/RelayPool.kt index 95232b4..5f2e1d1 100644 --- a/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/RelayPool.kt +++ b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/RelayPool.kt @@ -1,8 +1,41 @@ +/* + * MIT License + * + * Copyright (c) 2025 KotlinGeekDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + package rhodium.nostr.relay import rhodium.nostr.RelayError import kotlin.jvm.JvmStatic +/** + * Handles the relays used by the `NostrService`. + * For now, it is very simple. It just handles addition, + * removal, and resetting of the relay pool. + * + * You can specify a custom list of relays by using the `Relay(...)` primary constructor, + * or using [RelayPool.fromUrls]. + */ class RelayPool { private val relayList: MutableList = mutableListOf() diff --git a/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/Payments.kt b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/Payments.kt index 8bfe506..88d1ade 100644 --- a/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/Payments.kt +++ b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/Payments.kt @@ -28,6 +28,18 @@ package rhodium.nostr.relay.info import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +/** + * Represents the different payment options given by the relay, provided the relay has paid features. + * For more, see [Pay-to-Relay](https://github.com/nostr-protocol/nips/blob/master/11.md#pay-to-relay). + * The payment options are divided into 3 nominal categories: admission, subscription, and publication. + * Each category has a set of payment choices, each choice represented by a [PaymentInfo] object. + * + *@see PaymentInfo + * + * @property admissionFees The payment choices for *admission*(admission tiers), as an array. + * @property subscriptionFees The payment choices for *subscription*(subscription tiers), as an array. + * @property publicationFees The payment choices for *event publication*(publishing tiers), as an array. + */ @Serializable data class Payments( @SerialName("admission") val admissionFees: Array? = null, @@ -55,6 +67,17 @@ data class Payments( } } +/** + * Represents a payment choice, or tier, provided by the relay. + * + * @see Payments + * + * @property amount The amount to be paid for this tier. + * @property unit The currency(or units of currency) for the amount. + * @property durationInSeconds Specifies how long the usage of this tier will last. + * @property eventKinds - The event kinds that will be retained, + * or allowed for publication if paying for this tier. + */ @Serializable data class PaymentInfo( val amount: Long, diff --git a/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/Preferences.kt b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/Preferences.kt new file mode 100644 index 0000000..cf3601a --- /dev/null +++ b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/Preferences.kt @@ -0,0 +1,31 @@ +/* + * MIT License + * + * Copyright (c) 2025 KotlinGeekDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package rhodium.nostr.relay.info + +import kotlinx.serialization.Serializable + +@Serializable() +class Preferences \ No newline at end of file diff --git a/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/RelayLimits.kt b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/RelayLimits.kt index ba68010..bb555c2 100644 --- a/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/RelayLimits.kt +++ b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/RelayLimits.kt @@ -28,6 +28,27 @@ package rhodium.nostr.relay.info import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +/** + * Represents a relay's advertised limits. + * For more, see [NIP-11](https://github.com/nostr-protocol/nips/blob/master/11.md). + * All properties here are *optional*. + * + * @property maxMessageLength - The maximum length of the event to be published, in bytes. + * @property maxSubscriptions - The maximum number of active subscriptions on a single connection to the relay. + * @property maxLimit - The maximum limit for subscription filters sent to this relay. + * @property maxSubscriptionIdLength - The maximum length of the subscription id string. + * @property maxEventTagNumber - The maximum number of tags allowed in an event published to this relay. + * @property maxContentLength - The maximum number of characters in the content field of an event to be published + * to this relay. + * @property minPowDifficulty - The minimum amount of PoW difficulty needed for an event to be published to this + * relay. + * @property isAuthRequired - Determines if the relay has placed limits on publishing events/sending requests. + * @property creationDateLowerLimit - Determines the 'lowest date', or date furthest back in time, + * that an event being published(or request being made) can reach. + * @property creationDateUpperLimit - Determines the 'highest date', or date furthest into the future, that + * an event being published(or request limit being made) to the relay can reach. + * @property defaultLimit - The limit being applied by default, when a request is sent without any limits. + */ @Serializable data class RelayLimits( @SerialName("max_message_length") val maxMessageLength: Int? = null, diff --git a/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/RetentionPolicy.kt b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/RetentionPolicy.kt index e2f89c6..d6f31e1 100644 --- a/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/RetentionPolicy.kt +++ b/rhodium-core/src/commonMain/kotlin/rhodium/nostr/relay/info/RetentionPolicy.kt @@ -28,6 +28,19 @@ package rhodium.nostr.relay.info import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +/** + * Represents a relay's data retention policies, per NIP-11, + * on [event retention](https://github.com/nostr-protocol/nips/blob/master/11.md#event-retention). + * + * @property retainedKinds - A set of event kinds specified by the relay. + * Events of these kinds are the ones kept by the relay. + * @property retentionTime - The amount of time for which a set of events(specified by `retainedKinds` above) + * will be kept by the relay, measured in seconds. + * A value of zero(`0`) indicates that the relay won't store that event kind, and a `null` value indicates that + * the event set will be stored forever. + * @property retainedEventCount - The number of events for a particular + * kind(or all kinds mentioned in `retainedKinds` above) that will be stored by the relay. + */ @Serializable data class RetentionPolicy( @SerialName("kinds") val retainedKinds: IntArray = emptyArray().toIntArray(),