Improves package layout for nip64 chess

This commit is contained in:
Vitor Pamplona
2026-03-04 09:25:38 -05:00
parent 46dcd105c8
commit 9abd61e2de
21 changed files with 45 additions and 51 deletions
@@ -18,7 +18,7 @@
* 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 com.vitorpamplona.quartz.nip64Chess.accept
package com.vitorpamplona.quartz.nip64Chess.challenge.accept
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.core.HexKey
@@ -28,7 +28,7 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag
import com.vitorpamplona.quartz.nip31Alts.alt
import com.vitorpamplona.quartz.nip64Chess.baseEvent.BaseChessEvent
import com.vitorpamplona.quartz.nip64Chess.challenge.LiveChessGameChallengeEvent
import com.vitorpamplona.quartz.nip64Chess.challenge.offer.LiveChessGameChallengeEvent
import com.vitorpamplona.quartz.utils.TimeUtils
/**
@@ -18,13 +18,13 @@
* 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 com.vitorpamplona.quartz.nip64Chess.accept
package com.vitorpamplona.quartz.nip64Chess.challenge.accept
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
import com.vitorpamplona.quartz.nip64Chess.accept.tags.ChallengeEventTag
import com.vitorpamplona.quartz.nip64Chess.accept.tags.toOpponentTag
import com.vitorpamplona.quartz.nip64Chess.challenge.LiveChessGameChallengeEvent
import com.vitorpamplona.quartz.nip64Chess.challenge.accept.tags.ChallengeEventTag
import com.vitorpamplona.quartz.nip64Chess.challenge.accept.tags.toOpponentTag
import com.vitorpamplona.quartz.nip64Chess.challenge.offer.LiveChessGameChallengeEvent
fun TagArrayBuilder<LiveChessGameAcceptEvent>.challenge(challengeHint: EventHintBundle<LiveChessGameChallengeEvent>) = addUnique(ChallengeEventTag.assemble(challengeHint))
@@ -18,9 +18,9 @@
* 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 com.vitorpamplona.quartz.nip64Chess.accept
package com.vitorpamplona.quartz.nip64Chess.challenge.accept
import com.vitorpamplona.quartz.nip01Core.core.TagArray
import com.vitorpamplona.quartz.nip64Chess.accept.tags.ChallengeEventTag
import com.vitorpamplona.quartz.nip64Chess.challenge.accept.tags.ChallengeEventTag
fun TagArray.challengeEventId() = firstNotNullOfOrNull(ChallengeEventTag::parse)
@@ -18,7 +18,7 @@
* 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 com.vitorpamplona.quartz.nip64Chess.accept.tags
package com.vitorpamplona.quartz.nip64Chess.challenge.accept.tags
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.has
@@ -29,7 +29,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
import com.vitorpamplona.quartz.nip01Core.tags.events.GenericETag
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
import com.vitorpamplona.quartz.nip64Chess.baseEvent.tags.OpponentTag
import com.vitorpamplona.quartz.nip64Chess.challenge.LiveChessGameChallengeEvent
import com.vitorpamplona.quartz.nip64Chess.challenge.offer.LiveChessGameChallengeEvent
import com.vitorpamplona.quartz.utils.arrayOfNotNull
import com.vitorpamplona.quartz.utils.ensure
@@ -18,7 +18,7 @@
* 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 com.vitorpamplona.quartz.nip64Chess.challenge
package com.vitorpamplona.quartz.nip64Chess.challenge.offer
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.core.HexKey
@@ -18,13 +18,13 @@
* 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 com.vitorpamplona.quartz.nip64Chess.challenge
package com.vitorpamplona.quartz.nip64Chess.challenge.offer
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
import com.vitorpamplona.quartz.nip64Chess.Color
import com.vitorpamplona.quartz.nip64Chess.challenge.tags.PlayerColorTag
import com.vitorpamplona.quartz.nip64Chess.challenge.tags.TimeControlTag
import com.vitorpamplona.quartz.nip64Chess.challenge.offer.tags.PlayerColorTag
import com.vitorpamplona.quartz.nip64Chess.challenge.offer.tags.TimeControlTag
fun TagArrayBuilder<LiveChessGameChallengeEvent>.playerColor(color: Color) = addUnique(PlayerColorTag.assemble(color))
fun TagArrayBuilder<LiveChessGameChallengeEvent>.timeControl(timeControl: String) = addUnique(TimeControlTag.assemble(timeControl))
fun TagArrayBuilder<LiveChessGameChallengeEvent>.timeControl(timeControl: String) = addUnique(TimeControlTag.Companion.assemble(timeControl))
@@ -18,12 +18,12 @@
* 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 com.vitorpamplona.quartz.nip64Chess.challenge
package com.vitorpamplona.quartz.nip64Chess.challenge.offer
import com.vitorpamplona.quartz.nip01Core.core.TagArray
import com.vitorpamplona.quartz.nip64Chess.challenge.tags.PlayerColorTag
import com.vitorpamplona.quartz.nip64Chess.challenge.tags.TimeControlTag
import com.vitorpamplona.quartz.nip64Chess.challenge.offer.tags.PlayerColorTag
import com.vitorpamplona.quartz.nip64Chess.challenge.offer.tags.TimeControlTag
fun TagArray.playerColor() = firstNotNullOfOrNull(PlayerColorTag::parse)
fun TagArray.timeControl() = firstNotNullOfOrNull(TimeControlTag::parse)
fun TagArray.timeControl() = firstNotNullOfOrNull(TimeControlTag.Companion::parse)
@@ -18,7 +18,7 @@
* 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 com.vitorpamplona.quartz.nip64Chess.challenge.tags
package com.vitorpamplona.quartz.nip64Chess.challenge.offer.tags
import com.vitorpamplona.quartz.nip01Core.core.has
import com.vitorpamplona.quartz.nip64Chess.Color
@@ -18,7 +18,7 @@
* 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 com.vitorpamplona.quartz.nip64Chess.challenge.tags
package com.vitorpamplona.quartz.nip64Chess.challenge.offer.tags
import com.vitorpamplona.quartz.nip01Core.core.has
import com.vitorpamplona.quartz.utils.ensure
@@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.nip64Chess.jester
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.JsonMapper
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
@@ -30,13 +31,6 @@ import com.vitorpamplona.quartz.nip64Chess.Color
import com.vitorpamplona.quartz.nip64Chess.GameResult
import com.vitorpamplona.quartz.nip64Chess.GameTermination
import com.vitorpamplona.quartz.utils.TimeUtils
import kotlinx.serialization.json.Json
private val json =
Json {
ignoreUnknownKeys = true
encodeDefaults = false
}
/**
* Jester Chess Event (Kind 30)
@@ -58,7 +52,7 @@ class JesterEvent(
) : Event(id, pubKey, createdAt, JesterProtocol.KIND, tags, content, sig) {
private val parsedContent: JesterContent? by lazy {
try {
json.decodeFromString<JesterContent>(content)
JsonMapper.fromJson<JesterContent>(content)
} catch (e: Exception) {
null
}
@@ -133,7 +127,7 @@ class JesterEvent(
nonce = nonce,
playerColor = if (playerColor == Color.WHITE) "white" else "black",
)
return eventTemplate(KIND, json.encodeToString(content), createdAt) {
return eventTemplate(KIND, JsonMapper.toJson(content), createdAt) {
// Reference the standard start position for game discovery
add(arrayOf("e", JesterProtocol.START_POSITION_HASH))
initializer()
@@ -163,7 +157,7 @@ class JesterEvent(
nonce = nonce,
playerColor = if (playerColor == Color.WHITE) "white" else "black",
)
return eventTemplate(KIND, json.encodeToString(content), createdAt) {
return eventTemplate(KIND, JsonMapper.toJson(content), createdAt) {
// Reference the standard start position
add(arrayOf("e", JesterProtocol.START_POSITION_HASH))
// Tag the opponent for notifications (only if valid pubkey)
@@ -202,7 +196,7 @@ class JesterEvent(
move = move,
history = history,
)
return eventTemplate(KIND, json.encodeToString(content), createdAt) {
return eventTemplate(KIND, JsonMapper.toJson(content), createdAt) {
// e-tags: [startId, headId]
add(arrayOf("e", startEventId))
add(arrayOf("e", headEventId))
@@ -241,7 +235,7 @@ class JesterEvent(
result = result.notation,
termination = termination.name.lowercase(),
)
return eventTemplate(KIND, json.encodeToString(content), createdAt) {
return eventTemplate(KIND, JsonMapper.toJson(content), createdAt) {
add(arrayOf("e", startEventId))
add(arrayOf("e", headEventId))
// Tag opponent for notifications (only if valid pubkey)
@@ -270,7 +264,7 @@ fun Event.isJesterEvent(): Boolean = kind == JesterProtocol.KIND
fun Event.isJesterStartEvent(): Boolean {
if (kind != JesterProtocol.KIND) return false
return try {
val content = json.decodeFromString<JesterContent>(this.content)
val content = JsonMapper.fromJson<JesterContent>(this.content)
content.kind == JesterProtocol.CONTENT_KIND_START && content.history.isEmpty()
} catch (e: Exception) {
false
@@ -283,7 +277,7 @@ fun Event.isJesterStartEvent(): Boolean {
fun Event.isJesterMoveEvent(): Boolean {
if (kind != JesterProtocol.KIND) return false
return try {
val content = json.decodeFromString<JesterContent>(this.content)
val content = JsonMapper.fromJson<JesterContent>(this.content)
content.kind == JesterProtocol.CONTENT_KIND_MOVE &&
content.history.isNotEmpty() &&
tags.count { it.size >= 2 && it[0] == "e" } == 2
@@ -114,8 +114,8 @@ import com.vitorpamplona.quartz.nip58Badges.BadgeProfilesEvent
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
import com.vitorpamplona.quartz.nip62RequestToVanish.RequestToVanishEvent
import com.vitorpamplona.quartz.nip64Chess.accept.LiveChessGameAcceptEvent
import com.vitorpamplona.quartz.nip64Chess.challenge.LiveChessGameChallengeEvent
import com.vitorpamplona.quartz.nip64Chess.challenge.accept.LiveChessGameAcceptEvent
import com.vitorpamplona.quartz.nip64Chess.challenge.offer.LiveChessGameChallengeEvent
import com.vitorpamplona.quartz.nip64Chess.draw.LiveChessDrawOfferEvent
import com.vitorpamplona.quartz.nip64Chess.end.LiveChessGameEndEvent
import com.vitorpamplona.quartz.nip64Chess.game.ChessGameEvent