implicit val byteSeqEncoder: Encoder[IndexedSeq[Byte]] = { in =>
Algos.encode(in.toArray).asJson
}
implicit val modifierIdEncoder: Encoder[ModifierId] = Algos.encode(_).asJson
implicit val modifierIdDecoder: Decoder[ModifierId] = _.as[String].map(ModifierId @@ _)
implicit val digest32Encoder: Encoder[Digest32] = _.array.asJson
implicit val digest32Decoder: Decoder[Digest32] = bytesDecoder(Digest32 @@ _)
implicit val adKeyEncoder: Encoder[ADKey] = _.array.asJson
implicit val adKeyDecoder: Decoder[ADKey] = bytesDecoder(ADKey @@ _)
implicit val adDigestDecoder: Decoder[ADDigest] = bytesDecoder(ADDigest @@ _)
def bytesDecoder[T](transform: Array[Byte] => T): Decoder[T] = { implicit cursor =>
for {
str <- cursor.as[String]
bytes <- fromTry(Algos.decode(str))
} yield transform(bytes)
}
implicit val ergoTreeEncoder: Encoder[ErgoTree] = { value =>
ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(value).asJson
}
implicit val ergoTreeDecoder: Decoder[ErgoTree] = {
decodeErgoTree(_.asInstanceOf[ErgoTree])
}
implicit val evaluatedValueEncoder: Encoder[EvaluatedValue[SType]] = { value =>
ValueSerializer.serialize(value).asJson
}
implicit val evaluatedValueDecoder: Decoder[EvaluatedValue[SType]] = {
decodeEvaluatedValue(_.asInstanceOf[EvaluatedValue[SType]])
}
def decodeEvaluatedValue[T](transform: EvaluatedValue[SType] => T): Decoder[T] = { implicit cursor: ACursor =>
cursor.as[Array[Byte]] flatMap { bytes =>
fromThrows(transform(ValueSerializer.deserialize(bytes).asInstanceOf[EvaluatedValue[SType]]))
}
}
def decodeErgoTree[T](transform: ErgoTree => T): Decoder[T] = { implicit cursor: ACursor =>
cursor.as[Array[Byte]] flatMap { bytes =>
fromThrows(transform(ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bytes)))
}
}
implicit val registerIdEncoder: Encoder[RegisterId] = { regId =>
s"R${regId.number}".asJson
}
implicit val registerIdDecoder: Decoder[RegisterId] = { implicit cursor =>
for {
regId <- cursor.as[String]
reg <- fromOption(ErgoBox.registerByName.get(regId))
} yield reg
}
implicit val nonMandatoryRegisterIdEncoder: KeyEncoder[NonMandatoryRegisterId] = { regId =>
s"R${regId.number}"
}
implicit val nonMandatoryRegisterIdDecoder: KeyDecoder[NonMandatoryRegisterId] = { key =>
ErgoBox.registerByName.get(key).collect {
case nonMandatoryId: NonMandatoryRegisterId => nonMandatoryId
}
}
implicit val proveDlogEncoder: Encoder[ProveDlog] = _.pkBytes.asJson
def decodeNonMandatoryRegisterId(key: String)(implicit cursor: ACursor): Decoder.Result[NonMandatoryRegisterId] = {
nonMandatoryRegisterIdDecoder
.apply(key.toUpperCase)
.toRight(DecodingFailure(s"Unknown register identifier: $key", cursor.history))
}
implicit val nonMandatoryRegistersEncoder: Encoder[Map[NonMandatoryRegisterId, EvaluatedValue[_ <: SType]]] = {
_.map { case (key, value) =>
nonMandatoryRegisterIdEncoder(key) -> evaluatedValueEncoder(value)
}.asJson
}
implicit def assetEncoder[Id: Encoder]: Encoder[(Id, Long)] = { asset =>
Json.obj(
"tokenId" -> asset._1.asJson,
"amount" -> asset._2.asJson
)
}
implicit val boxEncoder: Encoder[ErgoBox] = { box =>
Json.obj(
"boxId" -> box.id.asJson,
"value" -> box.value.asJson,
"ergoTree" -> ergoTreeEncoder(box.ergoTree),
"assets" -> box.additionalTokens.toArray.toSeq.asJson,
"creationHeight" -> box.creationHeight.asJson,
"additionalRegisters" -> nonMandatoryRegistersEncoder(box.additionalRegisters)
)
}
def fromTry[T](tryResult: Try[T])(implicit cursor: ACursor): Either[DecodingFailure, T] = {
tryResult.fold(e => Left(DecodingFailure(e.toString, cursor.history)), Right.apply)
}