0

I am trying to parse this json object and I ran a unit test and I got this error Error: Error when parsing result of 'listdescriptors': {"obj":[{"msg":["error.expected.jsarray"],"args":[]}]}! [info] at org.bitcoins.rpc.client.common.Client.parseResult(Client.scala:455). I think the problem may be that I'm parsing the json file into a case class incorectly.

Result:
{                                 (json object)
  "wallet_name" : "str",          (string) Name of wallet this operation was performed on
  "descriptors" : [               (json array) Array of descriptor objects
    {                             (json object)
      "desc" : "str",             (string) Descriptor string representation
      "timestamp" : n,            (numeric) The creation time of the descriptor
      "active" : true|false,      (boolean) Activeness flag
      "internal" : true|false,    (boolean, optional) Whether this is an internal or external descriptor; defined only for active descriptors
      "range" : [                 (json array, optional) Defined only for ranged descriptors
        n,                        (numeric) Range start inclusive
        n                         (numeric) Range end inclusive
      ],
      "next" : n                  (numeric, optional) The next index to generate addresses from; defined only for ranged descriptors
    },
    ...
  ]
}

object JsonSerializers {

implicit val descriptorsClassReads: Reads[descriptorsClass] =
    Json.reads[descriptorsClass]

  implicit val listDescriptorsReads: Reads[listDescriptorsResult] =
    Json.reads[listDescriptorsResult]
sealed abstract class WalletResult

case class listDescriptorsResult(
    wallet_name: String,
    descriptors: Vector[descriptorsClass]
) extends WalletResult

case class descriptorsClass(
    desc: String,
    timestamp: ZonedDateTime,
    active: Boolean,
    internal: Boolean,
    range: Array[(Int, Int)],
    next: Int
) extends WalletResult
1

1 Answer 1

1

Here is a working example without the ZonedDateTime. It is probably better to have it represented as a Long in case class and convert it to ZonedDateTime later only when you need to represent it as ZonedDateTime

import play.api.libs.json.{Json, Reads, Writes}

sealed abstract class WalletResult

case class ListDescriptorsResult(
                                  wallet_name: String,
                                  descriptors: Seq[DescriptorsClass]
                                ) extends WalletResult

case class DescriptorsClass(
                             desc: String,
                             timestamp: Long,
                             active: Boolean,
                             internal: Boolean,
                             range: (Int, Int),
                             next: Int
                           ) extends WalletResult


implicit val descriptorsClassReads: Reads[DescriptorsClass] = 
  Json.reads[DescriptorsClass]
implicit val listDescriptorsResultReads: Reads[ListDescriptorsResult] = 
  Json.reads[ListDescriptorsResult]

val jsonString =
  """
    |{
    |  "wallet_name" : "str",
    |  "descriptors" : [
    |    {
    |      "desc" : "desc1",
    |      "timestamp" : 1657920976,
    |      "active" : true,
    |      "internal" : true,
    |      "range" : [
    |        10,
    |        20
    |      ],
    |      "next" : 10
    |    },
    |    {
    |      "desc" : "desc2",
    |      "timestamp" : 1657920976,
    |      "active" : true,
    |      "internal" : false,
    |      "range" : [
    |        30,
    |        40
    |      ],
    |      "next" : 20
    |    }
    |  ]
    |}
    |
""".stripMargin.replaceAll("\n","")

val jsValue = Json.parse(jsonString)

println(Json.fromJson[ListDescriptorsResult] (jsValue).get)

Here is the code in a scastie editor

Sign up to request clarification or add additional context in comments.

1 Comment

Think it will be better to paste full answer to SO. Other resources can be unavailable via few months/years. Also it is common practice on SO.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.