This commit is contained in:
Vitor Pamplona
2026-03-15 16:15:44 -04:00
parent 04d04ebe69
commit 30b76347c5
11 changed files with 206 additions and 80 deletions
@@ -59,15 +59,19 @@ object CommandKSerializer : KSerializer<Command> {
add(FilterKSerializer.serializeToElement(filter)) add(FilterKSerializer.serializeToElement(filter))
} }
} }
is EventCmd -> { is EventCmd -> {
add(EventKSerializer.serializeToElement(value.event)) add(EventKSerializer.serializeToElement(value.event))
} }
is CloseCmd -> { is CloseCmd -> {
add(JsonPrimitive(value.subId)) add(JsonPrimitive(value.subId))
} }
is AuthCmd -> { is AuthCmd -> {
add(EventKSerializer.serializeToElement(value.event)) add(EventKSerializer.serializeToElement(value.event))
} }
is CountCmd -> { is CountCmd -> {
add(JsonPrimitive(value.queryId)) add(JsonPrimitive(value.queryId))
for (filter in value.filters) { for (filter in value.filters) {
@@ -93,6 +97,7 @@ object CommandKSerializer : KSerializer<Command> {
} }
ReqCmd(subId, filters) ReqCmd(subId, filters)
} }
CountCmd.LABEL -> { CountCmd.LABEL -> {
val queryId = array[1].jsonPrimitive.content val queryId = array[1].jsonPrimitive.content
val filters = val filters =
@@ -101,16 +106,22 @@ object CommandKSerializer : KSerializer<Command> {
} }
CountCmd(queryId, filters) CountCmd(queryId, filters)
} }
EventCmd.LABEL -> { EventCmd.LABEL -> {
EventCmd(EventKSerializer.deserializeFromElement(array[1].jsonObject)) EventCmd(EventKSerializer.deserializeFromElement(array[1].jsonObject))
} }
CloseCmd.LABEL -> { CloseCmd.LABEL -> {
CloseCmd(array[1].jsonPrimitive.content) CloseCmd(array[1].jsonPrimitive.content)
} }
AuthCmd.LABEL -> { AuthCmd.LABEL -> {
AuthCmd(EventKSerializer.deserializeFromElement(array[1].jsonObject) as RelayAuthEvent) AuthCmd(EventKSerializer.deserializeFromElement(array[1].jsonObject) as RelayAuthEvent)
} }
else -> throw IllegalArgumentException("Message $type is not supported")
else -> {
throw IllegalArgumentException("Message $type is not supported")
}
} }
} }
} }
@@ -34,8 +34,6 @@ import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonEncoder import kotlinx.serialization.json.JsonEncoder
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.int import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
@@ -27,18 +27,15 @@ import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonEncoder import kotlinx.serialization.json.JsonEncoder
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.buildJsonArray import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.int
import kotlinx.serialization.json.intOrNull import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.long
import kotlinx.serialization.json.longOrNull import kotlinx.serialization.json.longOrNull
import kotlinx.serialization.json.put import kotlinx.serialization.json.put
@@ -120,6 +117,7 @@ object FilterKSerializer : KSerializer<Filter> {
key.startsWith("#") -> { key.startsWith("#") -> {
tags[key.substring(1)] = value.jsonArray.mapNotNull { it.jsonPrimitive.content } tags[key.substring(1)] = value.jsonArray.mapNotNull { it.jsonPrimitive.content }
} }
key.startsWith("&") -> { key.startsWith("&") -> {
tagsAll[key.substring(1)] = value.jsonArray.mapNotNull { it.jsonPrimitive.content } tagsAll[key.substring(1)] = value.jsonArray.mapNotNull { it.jsonPrimitive.content }
} }
@@ -70,19 +70,46 @@ class KotlinSerializationMapper {
fun toJson(value: OptimizedSerializable): String = fun toJson(value: OptimizedSerializable): String =
when (value) { when (value) {
is Event -> json.encodeToString(EventKSerializer, value) is Event -> {
is Filter -> json.encodeToString(FilterKSerializer, value) json.encodeToString(EventKSerializer, value)
is Rumor -> json.encodeToString(RumorKSerializer, value) }
is Filter -> {
json.encodeToString(FilterKSerializer, value)
}
is Rumor -> {
json.encodeToString(RumorKSerializer, value)
}
is EventTemplate<*> -> { is EventTemplate<*> -> {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
json.encodeToString(EventTemplateKSerializer, value as EventTemplate<Event>) json.encodeToString(EventTemplateKSerializer, value as EventTemplate<Event>)
} }
is Message -> json.encodeToString(MessageKSerializer, value)
is Command -> json.encodeToString(CommandKSerializer, value) is Message -> {
is BunkerRequest -> json.encodeToString(BunkerRequestKSerializer, value) json.encodeToString(MessageKSerializer, value)
is BunkerResponse -> json.encodeToString(BunkerResponseKSerializer, value) }
is BunkerMessage -> json.encodeToString(BunkerMessageKSerializer, value)
else -> throw IllegalArgumentException("Unsupported type: ${value::class}") is Command -> {
json.encodeToString(CommandKSerializer, value)
}
is BunkerRequest -> {
json.encodeToString(BunkerRequestKSerializer, value)
}
is BunkerResponse -> {
json.encodeToString(BunkerResponseKSerializer, value)
}
is BunkerMessage -> {
json.encodeToString(BunkerMessageKSerializer, value)
}
else -> {
throw IllegalArgumentException("Unsupported type: ${value::class}")
}
} }
inline fun <reified T : OptimizedSerializable> fromJsonTo(jsonStr: String): T { inline fun <reified T : OptimizedSerializable> fromJsonTo(jsonStr: String): T {
@@ -60,9 +60,11 @@ object MessageKSerializer : KSerializer<Message> {
add(JsonPrimitive(value.subId)) add(JsonPrimitive(value.subId))
add(EventKSerializer.serializeToElement(value.event)) add(EventKSerializer.serializeToElement(value.event))
} }
is NoticeMessage -> { is NoticeMessage -> {
add(JsonPrimitive(value.message)) add(JsonPrimitive(value.message))
} }
is OkMessage -> { is OkMessage -> {
add(JsonPrimitive(value.eventId)) add(JsonPrimitive(value.eventId))
// Jackson writes success as a string, not boolean // Jackson writes success as a string, not boolean
@@ -71,16 +73,20 @@ object MessageKSerializer : KSerializer<Message> {
add(JsonPrimitive(value.message)) add(JsonPrimitive(value.message))
} }
} }
is AuthMessage -> { is AuthMessage -> {
add(JsonPrimitive(value.challenge)) add(JsonPrimitive(value.challenge))
} }
is NotifyMessage -> { is NotifyMessage -> {
add(JsonPrimitive(value.message)) add(JsonPrimitive(value.message))
} }
is ClosedMessage -> { is ClosedMessage -> {
add(JsonPrimitive(value.subId)) add(JsonPrimitive(value.subId))
add(JsonPrimitive(value.message)) add(JsonPrimitive(value.message))
} }
is CountMessage -> { is CountMessage -> {
add(CountResultKSerializer.serializeToElement(value.result)) add(CountResultKSerializer.serializeToElement(value.result))
} }
@@ -100,12 +106,15 @@ object MessageKSerializer : KSerializer<Message> {
val event = EventKSerializer.deserializeFromElement(array[2].jsonObject) val event = EventKSerializer.deserializeFromElement(array[2].jsonObject)
EventMessage(subId, event) EventMessage(subId, event)
} }
EoseMessage.LABEL -> { EoseMessage.LABEL -> {
EoseMessage(array[1].jsonPrimitive.content) EoseMessage(array[1].jsonPrimitive.content)
} }
NoticeMessage.LABEL -> { NoticeMessage.LABEL -> {
NoticeMessage(array[1].jsonPrimitive.content) NoticeMessage(array[1].jsonPrimitive.content)
} }
OkMessage.LABEL -> { OkMessage.LABEL -> {
OkMessage( OkMessage(
eventId = array[1].jsonPrimitive.content, eventId = array[1].jsonPrimitive.content,
@@ -113,24 +122,31 @@ object MessageKSerializer : KSerializer<Message> {
message = if (array.size > 3) array[3].jsonPrimitive.content else "", message = if (array.size > 3) array[3].jsonPrimitive.content else "",
) )
} }
AuthMessage.LABEL -> { AuthMessage.LABEL -> {
AuthMessage(array[1].jsonPrimitive.content) AuthMessage(array[1].jsonPrimitive.content)
} }
NotifyMessage.LABEL -> { NotifyMessage.LABEL -> {
NotifyMessage(array[1].jsonPrimitive.content) NotifyMessage(array[1].jsonPrimitive.content)
} }
ClosedMessage.LABEL -> { ClosedMessage.LABEL -> {
ClosedMessage( ClosedMessage(
subId = array[1].jsonPrimitive.content, subId = array[1].jsonPrimitive.content,
message = if (array.size > 2) array[2].jsonPrimitive.content else "", message = if (array.size > 2) array[2].jsonPrimitive.content else "",
) )
} }
CountMessage.LABEL -> { CountMessage.LABEL -> {
val queryId = array[1].jsonPrimitive.content val queryId = array[1].jsonPrimitive.content
val result = CountResultKSerializer.deserializeFromElement(array[2].jsonObject) val result = CountResultKSerializer.deserializeFromElement(array[2].jsonObject)
CountMessage(queryId, result) CountMessage(queryId, result)
} }
else -> throw IllegalArgumentException("Message $type is not supported")
else -> {
throw IllegalArgumentException("Message $type is not supported")
}
} }
} }
} }
@@ -71,27 +71,55 @@ object BunkerMessageKSerializer : KSerializer<BunkerMessage> {
id: String, id: String,
method: String, method: String,
params: Array<String>, params: Array<String>,
): BunkerRequest { ): BunkerRequest =
return when (method) { when (method) {
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestConnect.METHOD_NAME -> com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestConnect.METHOD_NAME -> {
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestConnect.parse(id, params) com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestConnect
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetPublicKey.METHOD_NAME -> .parse(id, params)
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetPublicKey.parse(id, params) }
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetRelays.METHOD_NAME ->
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetRelays.parse(id, params) com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetPublicKey.METHOD_NAME -> {
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Decrypt.METHOD_NAME -> com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetPublicKey
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Decrypt.parse(id, params) .parse(id, params)
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Encrypt.METHOD_NAME -> }
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Encrypt.parse(id, params)
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Decrypt.METHOD_NAME -> com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetRelays.METHOD_NAME -> {
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Decrypt.parse(id, params) com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetRelays
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Encrypt.METHOD_NAME -> .parse(id, params)
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Encrypt.parse(id, params) }
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestPing.METHOD_NAME ->
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestPing.parse(id, params) com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Decrypt.METHOD_NAME -> {
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign.METHOD_NAME -> com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Decrypt
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign.parse(id, params) .parse(id, params)
else -> BunkerRequest(id, method, params) }
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Encrypt.METHOD_NAME -> {
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Encrypt
.parse(id, params)
}
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Decrypt.METHOD_NAME -> {
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Decrypt
.parse(id, params)
}
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Encrypt.METHOD_NAME -> {
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Encrypt
.parse(id, params)
}
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestPing.METHOD_NAME -> {
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestPing
.parse(id, params)
}
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign.METHOD_NAME -> {
com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign
.parse(id, params)
}
else -> {
BunkerRequest(id, method, params)
}
} }
}
} }
@@ -81,8 +81,14 @@ object BunkerResponseKSerializer : KSerializer<BunkerResponse> {
if (result != null) { if (result != null) {
when (result) { when (result) {
BunkerResponseAck.RESULT -> return BunkerResponseAck.parse(id, result, error) BunkerResponseAck.RESULT -> {
BunkerResponsePong.RESULT -> return BunkerResponsePong.parse(id, result, error) return BunkerResponseAck.parse(id, result, error)
}
BunkerResponsePong.RESULT -> {
return BunkerResponsePong.parse(id, result, error)
}
else -> { else -> {
if (result.length == 64 && Hex.isHex(result)) { if (result.length == 64 && Hex.isHex(result)) {
return BunkerResponsePublicKey.parse(id, result) return BunkerResponsePublicKey.parse(id, result)
@@ -44,9 +44,7 @@ object Nip47NotificationKSerializer : KSerializer<Notification> {
override fun serialize( override fun serialize(
encoder: Encoder, encoder: Encoder,
value: Notification, value: Notification,
) { ): Unit = throw UnsupportedOperationException("NIP-47 Notification serialization not supported")
throw UnsupportedOperationException("NIP-47 Notification serialization not supported")
}
override fun deserialize(decoder: Decoder): Notification { override fun deserialize(decoder: Decoder): Notification {
val jsonDecoder = decoder as JsonDecoder val jsonDecoder = decoder as JsonDecoder
@@ -63,6 +61,7 @@ object Nip47NotificationKSerializer : KSerializer<Notification> {
), ),
) )
} }
NwcNotificationType.PAYMENT_SENT -> { NwcNotificationType.PAYMENT_SENT -> {
PaymentSentNotification( PaymentSentNotification(
notification = notification =
@@ -71,6 +70,7 @@ object Nip47NotificationKSerializer : KSerializer<Notification> {
), ),
) )
} }
NwcNotificationType.HOLD_INVOICE_ACCEPTED -> { NwcNotificationType.HOLD_INVOICE_ACCEPTED -> {
val notifObj = jsonObject["notification"]?.jsonObject val notifObj = jsonObject["notification"]?.jsonObject
HoldInvoiceAcceptedNotification( HoldInvoiceAcceptedNotification(
@@ -88,7 +88,10 @@ object Nip47NotificationKSerializer : KSerializer<Notification> {
}, },
) )
} }
else -> throw IllegalArgumentException("Unknown notification type: $notificationType")
else -> {
throw IllegalArgumentException("Unknown notification type: $notificationType")
}
} }
} }
} }
@@ -68,9 +68,7 @@ object Nip47RequestKSerializer : KSerializer<Request> {
override fun serialize( override fun serialize(
encoder: Encoder, encoder: Encoder,
value: Request, value: Request,
) { ): Unit = throw UnsupportedOperationException("NIP-47 Request serialization not supported")
throw UnsupportedOperationException("NIP-47 Request serialization not supported")
}
override fun deserialize(decoder: Decoder): Request { override fun deserialize(decoder: Decoder): Request {
val jsonDecoder = decoder as JsonDecoder val jsonDecoder = decoder as JsonDecoder
@@ -60,9 +60,7 @@ object Nip47ResponseKSerializer : KSerializer<Response> {
override fun serialize( override fun serialize(
encoder: Encoder, encoder: Encoder,
value: Response, value: Response,
) { ): Unit = throw UnsupportedOperationException("NIP-47 Response serialization not supported")
throw UnsupportedOperationException("NIP-47 Response serialization not supported")
}
override fun deserialize(decoder: Decoder): Response { override fun deserialize(decoder: Decoder): Response {
val jsonDecoder = decoder as JsonDecoder val jsonDecoder = decoder as JsonDecoder
@@ -73,7 +71,10 @@ object Nip47ResponseKSerializer : KSerializer<Response> {
if (hasError) { if (hasError) {
return when (resultType) { return when (resultType) {
NwcMethod.PAY_INVOICE -> parsePayInvoiceError(jsonObject) NwcMethod.PAY_INVOICE -> {
parsePayInvoiceError(jsonObject)
}
else -> { else -> {
val error = jsonObject["error"]?.jsonObject?.let { parseNwcError(it) } val error = jsonObject["error"]?.jsonObject?.let { parseNwcError(it) }
NwcErrorResponse(resultType ?: "", error) NwcErrorResponse(resultType ?: "", error)
@@ -83,19 +84,58 @@ object Nip47ResponseKSerializer : KSerializer<Response> {
if (hasResult || resultType != null) { if (hasResult || resultType != null) {
return when (resultType) { return when (resultType) {
NwcMethod.PAY_INVOICE -> parsePayInvoiceSuccess(jsonObject) NwcMethod.PAY_INVOICE -> {
NwcMethod.PAY_KEYSEND -> parsePayKeysendSuccess(jsonObject) parsePayInvoiceSuccess(jsonObject)
NwcMethod.MAKE_INVOICE -> MakeInvoiceSuccessResponse(parseTransaction(jsonObject["result"]?.jsonObject)) }
NwcMethod.LOOKUP_INVOICE -> LookupInvoiceSuccessResponse(parseTransaction(jsonObject["result"]?.jsonObject))
NwcMethod.LIST_TRANSACTIONS -> parseListTransactionsSuccess(jsonObject) NwcMethod.PAY_KEYSEND -> {
NwcMethod.GET_BALANCE -> parseGetBalanceSuccess(jsonObject) parsePayKeysendSuccess(jsonObject)
NwcMethod.GET_INFO -> parseGetInfoSuccess(jsonObject) }
NwcMethod.GET_BUDGET -> parseGetBudgetSuccess(jsonObject)
NwcMethod.SIGN_MESSAGE -> parseSignMessageSuccess(jsonObject) NwcMethod.MAKE_INVOICE -> {
NwcMethod.CREATE_CONNECTION -> parseCreateConnectionSuccess(jsonObject) MakeInvoiceSuccessResponse(parseTransaction(jsonObject["result"]?.jsonObject))
NwcMethod.MAKE_HOLD_INVOICE -> MakeHoldInvoiceSuccessResponse(parseTransaction(jsonObject["result"]?.jsonObject)) }
NwcMethod.CANCEL_HOLD_INVOICE -> CancelHoldInvoiceSuccessResponse()
NwcMethod.SETTLE_HOLD_INVOICE -> SettleHoldInvoiceSuccessResponse() NwcMethod.LOOKUP_INVOICE -> {
LookupInvoiceSuccessResponse(parseTransaction(jsonObject["result"]?.jsonObject))
}
NwcMethod.LIST_TRANSACTIONS -> {
parseListTransactionsSuccess(jsonObject)
}
NwcMethod.GET_BALANCE -> {
parseGetBalanceSuccess(jsonObject)
}
NwcMethod.GET_INFO -> {
parseGetInfoSuccess(jsonObject)
}
NwcMethod.GET_BUDGET -> {
parseGetBudgetSuccess(jsonObject)
}
NwcMethod.SIGN_MESSAGE -> {
parseSignMessageSuccess(jsonObject)
}
NwcMethod.CREATE_CONNECTION -> {
parseCreateConnectionSuccess(jsonObject)
}
NwcMethod.MAKE_HOLD_INVOICE -> {
MakeHoldInvoiceSuccessResponse(parseTransaction(jsonObject["result"]?.jsonObject))
}
NwcMethod.CANCEL_HOLD_INVOICE -> {
CancelHoldInvoiceSuccessResponse()
}
NwcMethod.SETTLE_HOLD_INVOICE -> {
SettleHoldInvoiceSuccessResponse()
}
else -> { else -> {
// backward compatibility: guess by result content // backward compatibility: guess by result content
val resultObj = jsonObject["result"]?.jsonObject val resultObj = jsonObject["result"]?.jsonObject
@@ -111,13 +151,14 @@ object Nip47ResponseKSerializer : KSerializer<Response> {
} }
private fun parseNwcError(obj: JsonObject): NwcError { private fun parseNwcError(obj: JsonObject): NwcError {
val code = obj["code"]?.jsonPrimitive?.content?.let { codeName -> val code =
try { obj["code"]?.jsonPrimitive?.content?.let { codeName ->
NwcErrorCode.valueOf(codeName) try {
} catch (_: Exception) { NwcErrorCode.valueOf(codeName)
null } catch (_: Exception) {
null
}
} }
}
return NwcError(code, obj["message"]?.jsonPrimitive?.content) return NwcError(code, obj["message"]?.jsonPrimitive?.content)
} }
@@ -157,13 +198,14 @@ object Nip47ResponseKSerializer : KSerializer<Response> {
return PayInvoiceErrorResponse( return PayInvoiceErrorResponse(
error?.let { error?.let {
PayInvoiceErrorResponse.PayInvoiceErrorParams( PayInvoiceErrorResponse.PayInvoiceErrorParams(
code = it["code"]?.jsonPrimitive?.content?.let { codeName -> code =
try { it["code"]?.jsonPrimitive?.content?.let { codeName ->
NwcErrorCode.valueOf(codeName) try {
} catch (_: Exception) { NwcErrorCode.valueOf(codeName)
null } catch (_: Exception) {
} null
}, }
},
message = it["message"]?.jsonPrimitive?.content, message = it["message"]?.jsonPrimitive?.content,
) )
}, },
@@ -187,7 +229,7 @@ object Nip47ResponseKSerializer : KSerializer<Response> {
return ListTransactionsSuccessResponse( return ListTransactionsSuccessResponse(
result?.let { result?.let {
ListTransactionsSuccessResponse.ListTransactionsResult( ListTransactionsSuccessResponse.ListTransactionsResult(
transactions = it["transactions"]?.jsonArray?.map { t -> parseTransaction(t.jsonObject) }, transactions = it["transactions"]?.jsonArray?.mapNotNull { t -> parseTransaction(t.jsonObject) },
total_count = it["total_count"]?.jsonPrimitive?.longOrNull, total_count = it["total_count"]?.jsonPrimitive?.longOrNull,
) )
}, },
@@ -20,10 +20,9 @@
*/ */
package com.vitorpamplona.quartz.nip59Giftwrap.rumors.kotlinSerialization package com.vitorpamplona.quartz.nip59Giftwrap.rumors.kotlinSerialization
import com.vitorpamplona.quartz.nip01Core.kotlinSerialization.TagArrayKSerializer
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArray
import com.vitorpamplona.quartz.nip01Core.kotlinSerialization.TagArrayKSerializer
import com.vitorpamplona.quartz.nip59Giftwrap.rumors.Rumor import com.vitorpamplona.quartz.nip59Giftwrap.rumors.Rumor
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor